diff options
493 files changed, 29404 insertions, 23475 deletions
diff --git a/.gitignore b/.gitignore index 7ccedd3ff3..9cd91245f5 100644 --- a/.gitignore +++ b/.gitignore @@ -150,6 +150,7 @@ JAVADOC-GENERATED /erts/epmd/test/Emakefile /lib/*/SKIP +/lib/SKIP-APPLICATIONS /lib/*/doc/html/*.html /lib/*/doc/html/*.css diff --git a/HOWTO/INSTALL-CROSS.md b/HOWTO/INSTALL-CROSS.md index fbcb5f83c6..a5cf775583 100644 --- a/HOWTO/INSTALL-CROSS.md +++ b/HOWTO/INSTALL-CROSS.md @@ -4,14 +4,7 @@ Cross Compiling Erlang/OTP Introduction ------------ -This document describes how to cross compile Erlang/OTP-%OTP-REL%. Note that -the support for cross compiling Erlang/OTP should be considered as -experimental. As far as we know, the %OTP-REL% release should cross compile -fine, but since we currently have a very limited set of cross compilation -environments to test with we cannot be sure. The cross compilation support -will remain in an experimental state until we get a lot more cross compilation -environments to test with. - +This document describes how to cross compile Erlang/OTP-%OTP-REL%. You are advised to read the whole document before attempting to cross compile Erlang/OTP. However, before reading this document, you should read the [$ERL_TOP/HOWTO/INSTALL.md][] document which describes building and installing diff --git a/HOWTO/INSTALL.md b/HOWTO/INSTALL.md index 9ea50ce86c..2eb12f3b2d 100644 --- a/HOWTO/INSTALL.md +++ b/HOWTO/INSTALL.md @@ -308,6 +308,12 @@ Some of the available `configure` options are: If your nif/driver depends on some other dynamic library, you now have to link that to the Erlang VM binary. This is easily achived by passing `LIBS=-llibname` to configure. +* `--without-$app` - By default all applications in Erlang/OTP will be included + in a release. If this is not wanted it is possible to specify that Erlang/OTP + should be compiled without that applications, i.e. `--without-wx`. There is + no automatic dependency handling inbetween applications. So if you disable + an application that another depends on, you also have to disable the + dependant application. If you or your system has special requirements please read the `Makefile` for additional configuration information. diff --git a/bootstrap/lib/compiler/ebin/v3_core.beam b/bootstrap/lib/compiler/ebin/v3_core.beam Binary files differindex 1cfb8b1aaa..3da6d334b4 100644 --- a/bootstrap/lib/compiler/ebin/v3_core.beam +++ b/bootstrap/lib/compiler/ebin/v3_core.beam diff --git a/bootstrap/lib/kernel/ebin/hipe_unified_loader.beam b/bootstrap/lib/kernel/ebin/hipe_unified_loader.beam Binary files differindex cfe44f72ef..23a20576fe 100644 --- a/bootstrap/lib/kernel/ebin/hipe_unified_loader.beam +++ b/bootstrap/lib/kernel/ebin/hipe_unified_loader.beam diff --git a/bootstrap/lib/stdlib/ebin/erl_compile.beam b/bootstrap/lib/stdlib/ebin/erl_compile.beam Binary files differindex 1311018a7f..244bb5e290 100644 --- a/bootstrap/lib/stdlib/ebin/erl_compile.beam +++ b/bootstrap/lib/stdlib/ebin/erl_compile.beam diff --git a/bootstrap/lib/stdlib/ebin/erl_lint.beam b/bootstrap/lib/stdlib/ebin/erl_lint.beam Binary files differindex c4469bd74c..c087684fa1 100644 --- a/bootstrap/lib/stdlib/ebin/erl_lint.beam +++ b/bootstrap/lib/stdlib/ebin/erl_lint.beam diff --git a/configure.in b/configure.in index 4b3884864c..f25a068be9 100644 --- a/configure.in +++ b/configure.in @@ -390,6 +390,15 @@ if test X${enable_native_libs} = Xyes -a X${enable_hipe} != Xno; then fi AC_SUBST(NATIVE_LIBS_ENABLED) + +rm -f $ERL_TOP/lib/SKIP-APPLICATIONS +for app in `cd lib && ls -d *`; do + var=`eval echo \\$with_$app` + if test X${var} == Xno; then + echo "$app" >> $ERL_TOP/lib/SKIP-APPLICATIONS + fi +done + export ERL_TOP AC_CONFIG_SUBDIRS(lib erts) @@ -400,15 +409,22 @@ AC_OUTPUT pattern="lib/*/SKIP" files=`echo $pattern` -if test "$files" != "$pattern"; then +if test "$files" != "$pattern" || test -f $ERL_TOP/lib/SKIP-APPLICATIONS; then echo '*********************************************************************' echo '********************** APPLICATIONS DISABLED **********************' echo '*********************************************************************' echo - for skipfile in $files; do - app=`dirname $skipfile`; app=`basename $app` - printf "%-15s: " $app; cat $skipfile - done + if test "$files" != "$pattern"; then + for skipfile in $files; do + app=`dirname $skipfile`; app=`basename $app` + printf "%-15s: " $app; cat $skipfile + done + fi + if test -f $ERL_TOP/lib/SKIP-APPLICATIONS; then + for skipapp in `cat $ERL_TOP/lib/SKIP-APPLICATIONS`; do + printf "%-15s: User gave --without-%s option\n" $skipapp $skipapp + done + fi echo echo '*********************************************************************' fi diff --git a/erts/configure.in b/erts/configure.in index 4e60b27ee9..886d82b109 100644 --- a/erts/configure.in +++ b/erts/configure.in @@ -1690,6 +1690,10 @@ if test x"$ac_cv_header_netinet_sctp_h" = x"yes"; then ]) fi +dnl Check for setns +AC_CHECK_HEADERS(sched.h setns.h) +AC_CHECK_FUNCS([setns]) + HAVE_VALGRIND=no AC_CHECK_HEADER(valgrind/valgrind.h, HAVE_VALGRIND=yes) AC_SUBST(HAVE_VALGRIND) @@ -1981,8 +1985,8 @@ AC_CHECK_FUNCS([getipnodebyname getipnodebyaddr gethostbyname2]) AC_CHECK_FUNCS([ieee_handler fpsetmask finite isnan isinf res_gethostbyname dlopen \ pread pwrite memmove strerror strerror_r strncasecmp \ - gethrtime localtime_r gmtime_r inet_pton mmap mremap memcpy mallopt \ - sbrk _sbrk __sbrk brk _brk __brk \ + gethrtime localtime_r gmtime_r inet_pton posix_memalign \ + mmap mremap memcpy mallopt sbrk _sbrk __sbrk brk _brk __brk \ flockfile fstat strlcpy strlcat setsid posix2time time2posix \ setlocale nl_langinfo poll]) diff --git a/erts/doc/src/Makefile b/erts/doc/src/Makefile index 89d7c85a86..d4c6fe67d2 100644 --- a/erts/doc/src/Makefile +++ b/erts/doc/src/Makefile @@ -78,6 +78,7 @@ XML_CHAPTER_FILES = \ erl_ext_dist.xml \ erl_dist_protocol.xml \ communication.xml \ + time_correction.xml \ notes.xml \ notes_history.xml diff --git a/erts/doc/src/erl.xml b/erts/doc/src/erl.xml index c151b35d77..bf0d132955 100644 --- a/erts/doc/src/erl.xml +++ b/erts/doc/src/erl.xml @@ -524,7 +524,7 @@ <p>Calling <c>erlang:halt/1</c> with a string argument will still produce a crash dump.</p> </item> - <tag><c><![CDATA[+e Number]]></c></tag> + <tag><marker id="+e"><c><![CDATA[+e Number]]></c></marker></tag> <item> <p>Set max number of ETS tables.</p> </item> @@ -748,19 +748,47 @@ </item> <tag><marker id="+S"><c><![CDATA[+S Schedulers:SchedulerOnline]]></c></marker></tag> <item> - <p>Sets the amount of scheduler threads to create and scheduler - threads to set online when SMP support has been enabled. - Valid range for both values are 1-1024. If the - Erlang runtime system is able to determine the amount - of logical processors configured and logical processors available, - <c>Schedulers</c> will default to logical processors configured, - and <c>SchedulersOnline</c> will default to logical processors - available; otherwise, the default values will be 1. <c>Schedulers</c> - may be omitted if <c>:SchedulerOnline</c> is not and vice versa. The - amount of schedulers online can be changed at run time via + <p>Sets the number of scheduler threads to create and scheduler + threads to set online when SMP support has been enabled. The maximum for + both values is 1024. If the Erlang runtime system is able to determine the + amount of logical processors configured and logical processors available, + <c>Schedulers</c> will default to logical processors configured, and + <c>SchedulersOnline</c> will default to logical processors available; + otherwise, the default values will be 1. <c>Schedulers</c> may be omitted + if <c>:SchedulerOnline</c> is not and vice versa. The number of schedulers + online can be changed at run time via <seealso marker="erlang#system_flag_schedulers_online">erlang:system_flag(schedulers_online, SchedulersOnline)</seealso>. </p> - <p>This flag will be ignored if the emulator doesn't have + <p>If <c>Schedulers</c> or <c>SchedulersOnline</c> is specified as a + negative number, the value is subtracted from the default number of + logical processors configured or logical processors available, respectively. + </p> + <p>Specifying the value 0 for <c>Schedulers</c> or <c>SchedulersOnline</c> + resets the number of scheduler threads or scheduler threads online respectively + to its default value. + </p> + <p>This option is ignored if the emulator doesn't have + SMP support enabled (see the <seealso marker="#smp">-smp</seealso> + flag).</p> + </item> + <tag><marker id="+SP"><c><![CDATA[+SP SchedulersPercentage:SchedulersOnlinePercentage]]></c></marker></tag> + <item> + <p>Similar to <seealso marker="#+S">+S</seealso> but uses percentages to set the + number of scheduler threads to create, based on logical processors configured, + and scheduler threads to set online, based on logical processors available, when + SMP support has been enabled. Specified values must be greater than 0. For example, + <c>+SP 50:25</c> sets the number of scheduler threads to 50% of the logical processors + configured and the number of scheduler threads online to 25% of the logical processors available. + <c>SchedulersPercentage</c> may be omitted if <c>:SchedulersOnlinePercentage</c> is + not and vice versa. The number of schedulers online can be changed at run time via + <seealso marker="erlang#system_flag_schedulers_online">erlang:system_flag(schedulers_online, SchedulersOnline)</seealso>. + </p> + <p>This option interacts with <seealso marker="#+S">+S</seealso> settings. + For example, on a system with 8 logical cores configured and 8 logical cores + available, the combination of the options <c>+S 4:4 +SP 50:25</c> (in either order) + results in 2 scheduler threads (50% of 4) and 1 scheduler thread online (25% of 4). + </p> + <p>This option is ignored if the emulator doesn't have SMP support enabled (see the <seealso marker="#smp">-smp</seealso> flag).</p> </item> diff --git a/erts/doc/src/erl_driver.xml b/erts/doc/src/erl_driver.xml index 64b0c3cac8..b453a4861e 100644 --- a/erts/doc/src/erl_driver.xml +++ b/erts/doc/src/erl_driver.xml @@ -2907,8 +2907,84 @@ ERL_DRV_EXT2TERM char *buf, ErlDrvUInt len beginning of this document.</p> </desc> </func> - </funcs> + <func> + <name><ret>char *</ret><nametext>erl_drv_cond_name(ErlDrvCond *cnd)</nametext></name> + <fsummary>Get name of driver mutex.</fsummary> + <desc> + <marker id="erl_drv_cnd_name"></marker> + <p>Arguments:</p> + <taglist> + <tag><c>cnd</c></tag> + <item>A pointer to an initialized condition.</item> + </taglist> + <p> + Returns a pointer to the name of the condition. + </p> + <note> + <p>This function is intended for debugging purposes only.</p> + </note> + </desc> + </func> + + <func> + <name><ret>char *</ret><nametext>erl_drv_mutex_name(ErlDrvMutex *mtx)</nametext></name> + <fsummary>Get name of driver mutex.</fsummary> + <desc> + <marker id="erl_drv_mutex_name"></marker> + <p>Arguments:</p> + <taglist> + <tag><c>mtx</c></tag> + <item>A pointer to an initialized mutex.</item> + </taglist> + <p> + Returns a pointer to the name of the mutex. + </p> + <note> + <p>This function is intended for debugging purposes only.</p> + </note> + </desc> + </func> + + <func> + <name><ret>char *</ret><nametext>erl_drv_rwlock_name(ErlDrvRWLock *rwlck)</nametext></name> + <fsummary>Get name of driver mutex.</fsummary> + <desc> + <marker id="erl_drv_rwlock_name"></marker> + <p>Arguments:</p> + <taglist> + <tag><c>rwlck</c></tag> + <item>A pointer to an initialized r/w-lock.</item> + </taglist> + <p> + Returns a pointer to the name of the r/w-lock. + </p> + <note> + <p>This function is intended for debugging purposes only.</p> + </note> + </desc> + </func> + + <func> + <name><ret>char *</ret><nametext>erl_drv_thread_name(ErlDrvTid tid)</nametext></name> + <fsummary>Get name of driver mutex.</fsummary> + <desc> + <marker id="erl_drv_rwlock_name"></marker> + <p>Arguments:</p> + <taglist> + <tag><c>tid</c></tag> + <item>A thread identifier.</item> + </taglist> + <p> + Returns a pointer to the name of the thread. + </p> + <note> + <p>This function is intended for debugging purposes only.</p> + </note> + </desc> + </func> + + </funcs> <section> <title>SEE ALSO</title> <p><seealso marker="driver_entry">driver_entry(3)</seealso>, diff --git a/erts/doc/src/erlang.xml b/erts/doc/src/erlang.xml index beb8b9c9eb..94adc0c160 100644 --- a/erts/doc/src/erlang.xml +++ b/erts/doc/src/erlang.xml @@ -5480,6 +5480,9 @@ ok <name name="system_info" arity="1" clause_i="49"/> <name name="system_info" arity="1" clause_i="50"/> <name name="system_info" arity="1" clause_i="51"/> + <name name="system_info" arity="1" clause_i="52"/> + <name name="system_info" arity="1" clause_i="53"/> + <name name="system_info" arity="1" clause_i="54"/> <fsummary>Information about the system</fsummary> <desc> <p>Returns various information about the current system @@ -5556,6 +5559,13 @@ ok information see the <seealso marker="erts:crash_dump">"How to interpret the Erlang crash dumps"</seealso> chapter in the ERTS User's Guide.</p> </item> + <tag><marker id="system_info_dist_buf_busy_limit"><c>dist_buf_busy_limit</c></marker></tag> + <item> + <p>Returns the value of the distribution buffer busy limit + in bytes. This limit can be set on startup by passing the + <seealso marker="erts:erl#+zdbbl">+zdbbl</seealso> command line + flag to <c>erl</c>.</p> + </item> <tag><c>dist_ctrl</c></tag> <item> <p>Returns a list of tuples @@ -5602,12 +5612,14 @@ ok The return value will always be <c>false</c> since the elib_malloc allocator has been removed.</p> </item> - <tag><marker id="system_info_dist_buf_busy_limit"><c>dist_buf_busy_limit</c></marker></tag> + <tag><c>ets_limit</c></tag> <item> - <p>Returns the value of the distribution buffer busy limit - in bytes. This limit can be set on startup by passing the - <seealso marker="erts:erl#+zdbbl">+zdbbl</seealso> command line - flag to <c>erl</c>.</p> + <p>Returns the maximum number of ETS tables allowed. This limit + can be increased on startup by passing the <seealso + marker="erts:erl#+e">+e</seealso> command line flag to + <c>erl</c> or by setting the environment variable + <c>ERL_MAX_ETS_TABLES</c> before starting the Erlang runtime + system.</p> </item> <tag><c>fullsweep_after</c></tag> <item> diff --git a/erts/doc/src/erts_alloc.xml b/erts/doc/src/erts_alloc.xml index e8682db5d5..8dd9ed1398 100644 --- a/erts/doc/src/erts_alloc.xml +++ b/erts/doc/src/erts_alloc.xml @@ -271,6 +271,65 @@ memory segment cache is not reused if its size exceeds the requested size with more than relative max cache bad fit percent of the requested size. Default value is 20.</item> + <tag><marker id="MMscmgc"><c><![CDATA[+MMscmgc <amount>]]></c></marker></tag> + <item> + Set <seealso marker="#MMscs">super carrier</seealso> max guaranteed + no of carriers. This parameter defaults to <c>65536</c>. This + parameter determines an amount of pre-allocated structures that is + needed in order to keep track of different areas in the super carrier. + When the system runs out of such structures it may crash due to an + out of memory condition. + </item> + <tag><marker id="MMsco"><c><![CDATA[+MMsco true|false]]></c></marker></tag> + <item> + Set <seealso marker="#MMscs">super carrier</seealso> only flag. This + flag defaults to <c>true</c>. When a super carrier is used and this + flag is <c>true</c>, the system will crash when a carrier request + cannot be satisfied by the super carrier. When the flag is <c>false</c> + the system will try to create requested carrier by other means. + <br/><br/> + <em>NOTE</em>: Setting this flag to <c>false</c> may not be supported + on all systems. This flag will in that case be ignored. + <br/><br/> + <em>NOTE</em>: The super carrier cannot be enabled nor + disabled on halfword heap systems. This flag will be + ignored on halfword heap systems. + </item> + <tag><marker id="MMscrpm"><c><![CDATA[+MMscrpm true|false]]></c></marker></tag> + <item> + Set <seealso marker="#MMscs">super carrier</seealso> reserve physical + memory flag. This flag defaults to <c>true</c>. When this flag is + <c>true</c>, physical memory will be reserved for the whole super + carrier at once when it is created. The reservation will after that + be left unchanged. When this flag is set to <c>false</c> only virtual + address space will be reserved for the super carrier upon creation. + The system will attempt to reserve physical memory upon carrier + creations in the super carrier, and attempt to unreserve physical + memory upon carrier destructions in the super carrier. + <br/><br/> + <em>NOTE</em>: What reservation of physical memory actually means + highly depends on the operating system, and how it is configured. For + example, different memory overcommit settings on Linux drastically + change the behaviour. Also note, setting this flag to <c>false</c> + may not be supported on all systems. This flag will in that case + be ignored. + <br/><br/> + <em>NOTE</em>: The super carrier cannot be enabled nor + disabled on halfword heap systems. This flag will be + ignored on halfword heap systems. + </item> + <tag><marker id="MMscs"><c><![CDATA[+MMscs <size in MB>]]></c></marker></tag> + <item> + Set super carrier size (in MB). The super carrier size defaults to + zero; i.e, the super carrier is by default disabled. The super + carrier is a large continuous area in the virtual address space. + The system will always try to create new carriers in the super + carrier. + <br/><br/> + <em>NOTE</em>: The super carrier cannot be enabled nor + disabled on halfword heap systems. This flag will be + ignored on halfword heap systems. + </item> <tag><marker id="MMmcs"><c><![CDATA[+MMmcs <amount>]]></c></marker></tag> <item> Max cached segments. The maximum number of memory segments diff --git a/erts/doc/src/notes.xml b/erts/doc/src/notes.xml index 9920dc3c45..b25e4ccbec 100644 --- a/erts/doc/src/notes.xml +++ b/erts/doc/src/notes.xml @@ -30,6 +30,256 @@ </header> <p>This document describes the changes made to the ERTS application.</p> +<section><title>Erts 5.10.3.1</title> + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Memory allocators will be able to create <c>sys_alloc</c> + carriers as fallback, if <c>mseg_alloc</c> cannot create + more carriers, on systems with <c>posix_memalign()</c> + support. This is similar to how it worked in pre-R16 + releases.</p> + <p> + Windows systems will create carriers using + <c>_aligned_malloc()</c> and can by this use the new + optimized allocator header scheme introduced in R16 on + other platforms.</p> + <p> + Own Id: OTP-11318</p> + </item> + </list> + </section> + +</section> + +<section><title>Erts 5.10.3</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> The documentation of predefined types and built-in + types has been corrected. </p> + <p> + Own Id: OTP-11090</p> + </item> + <item> + <p> + Fix changing terminal parameters in to_erl</p> + <p> + Change the behaviour of to_erl to use TCSADRAIN instead + of TCSANOW when changing terminal parameters. This makes + the serial driver wait for the output queues to be empty + before applying the terminal parameter change. Thanks to + Stefan Zegenhagen.</p> + <p> + Own Id: OTP-11206</p> + </item> + <item> + <p> + The default value of {flush, boolean()} in erlang:halt/2 + is documented to be 'true' if the status is an integer. + The implementation behaviour was reversed. The + Implementation is now corrected to adhere to the + documentation. Thanks to Jose Valim for reporting the + error.</p> + <p> + *** POTENTIAL INCOMPATIBILITY ***</p> + <p> + Own Id: OTP-11218</p> + </item> + <item> + <p> + Fix serious race bug in R16B01 that could cause PID + mix-ups when a lot of processes were spawned and + terminated in a very rapid pace on an SMP emulator with + at least two scheduler threads.</p> + <p> + Own Id: OTP-11225</p> + </item> + <item> + <p> + Validating a trace pattern with the option silent no + longer incorrectly enables/disables the silent option of + the calling process.</p> + <p> + Own Id: OTP-11232</p> + </item> + <item> + <p> + Fixed a bug where GCC 4.8 and later use a more aggressive + loop optimization algorithm that broke some previously + working code in the efile driver. Thanks to Tomas + Abrahamsson for reporting this issue.</p> + <p> + Own Id: OTP-11246</p> + </item> + <item> + <p> + Fixed bug when printing memory allocator acul option in + crash dump.</p> + <p> + Own Id: OTP-11264</p> + </item> + <item> + <p> + Opening a new compressed file on Windows could in rare + (random) cases result in {error,eisdir} or other error + codes although it should have succeeded. This is now + corrected.</p> + <p> + Own Id: OTP-11265</p> + </item> + <item> + <p> + Fixed a race condition when closing a trace port that + would cause the emulator to crash.</p> + <p> + Own Id: OTP-11290</p> + </item> + </list> + </section> + + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + There is a new somewhat experimental socket option + 'netns' that can set the network namespace for a socket + on Linux:es where it is supported. See the documentation.</p> + <p> + Own Id: OTP-11157</p> + </item> + <item> + <p> + New allocator strategy <c>aoffcbf</c> (address order + first fit carrier best fit). Supports carrier migration + but with better CPU performance than <c>aoffcaobf</c>.</p> + <p> + Own Id: OTP-11174</p> + </item> + <item> + <p> + Introduced functionality for inspection of system and + build configuration.</p> + <p> + Own Id: OTP-11196</p> + </item> + <item> + <p> + Fix matching of floating point middle-endian machines. + Thanks to Johannes Weissl.</p> + <p> + Own Id: OTP-11201</p> + </item> + <item> + <p> + Fix compile error on ARM and GCC versions greater than + 4.1.0. Thanks to Johannes Weissl.</p> + <p> + Own Id: OTP-11214</p> + </item> + <item> + <p> + run_erl: Redirect standard streams to /dev/null. Thanks + to Johannes Weissl.</p> + <p> + Own Id: OTP-11215</p> + </item> + <item> + <p> + Misc. corrections in documentation for erl_driver. Thanks + to Giacomo Olgeni.</p> + <p> + Own Id: OTP-11227</p> + </item> + <item> + <p> + Fix documentation regarding binary_part.</p> + <p> + Own Id: OTP-11239</p> + </item> + <item> + <p> + Make edlin understand a few important control keys. + Thanks to Stefan Zegenhagen.</p> + <p> + Own Id: OTP-11251</p> + </item> + <item> + <p> + Export type zlib:zstream/0. Thanks to Loic Hoguin.</p> + <p> + Own Id: OTP-11278</p> + </item> + <item> + <p> + Add erl option to set schedulers by percentages. </p> + <p> + For applications where measurements show enhanced + performance from the use of a non-default number of + emulator scheduler threads, having to accurately set the + right number of scheduler threads across multiple hosts + each with different numbers of logical processors is + difficult because the erl +S option requires absolute + numbers of scheduler threads and scheduler threads online + to be specified.</p> + <p> + To address this issue, add a +SP option to erl, similar + to the existing +S option but allowing the number of + scheduler threads and scheduler threads online to be set + as percentages of logical processors configured and + logical processors available, respectively. For example, + "+SP 50:25" sets the number of scheduler threads to 50% + of the logical processors configured, and the number of + scheduler threads online to 25% of the logical processors + available. The +SP option also interacts with any + settings specified with the +S option, such that the + combination of options "+S 4:4 +SP 50:50" (in either + order) results in 2 scheduler threads and 2 scheduler + threads online.</p> + <p> + Thanks to Steve Vinoski</p> + <p> + Own Id: OTP-11282</p> + </item> + <item> + <p> + Extend erl_driver interface with lock names</p> + <p> + Lock and thread names are already a feature in the driver + interface. This extension will let developers read these + names which eases debugging.</p> + <p> + Own Id: OTP-11303</p> + </item> + <item> + <p> + Fix incorrect values returned by integer_to_binary/2. + Thanks to Juan Jose Comellas.</p> + <p> + Own Id: OTP-11311</p> + </item> + <item> + <p> + Fix system_flag scheduling_statistics - disable . Thanks + to Steve Vinoski.</p> + <p> + Own Id: OTP-11317</p> + </item> + <item> + <p> The documentation of predefined types has been + corrected Thanks to Kostis Sagonas. </p> + <p> + Own Id: OTP-11321</p> + </item> + </list> + </section> + +</section> + <section><title>Erts 5.10.2</title> <section><title>Fixed Bugs and Malfunctions</title> @@ -321,7 +571,7 @@ <item> <p> Support wide characters in the shell through wcwidth(). - Thanks to Anthony Ramine. Reported by Lo�c Hoguin.</p> + Thanks to Anthony Ramine. Reported by Loïc Hoguin.</p> <p> Own Id: OTP-11088</p> </item> @@ -342,7 +592,7 @@ <item> <p> Remove 'query' from the list of reserved words in docs. - Thanks to Matthias Endler and Lo�c Hoguin.</p> + Thanks to Matthias Endler and Loïc Hoguin.</p> <p> Own Id: OTP-11158</p> </item> diff --git a/erts/doc/src/part.xml b/erts/doc/src/part.xml index fb720e05f3..7b17b5b551 100644 --- a/erts/doc/src/part.xml +++ b/erts/doc/src/part.xml @@ -32,6 +32,7 @@ <p>The Erlang Runtime System Application <em>ERTS</em>.</p> </description> <xi:include href="communication.xml"/> + <xi:include href="time_correction.xml"/> <xi:include href="match_spec.xml"/> <xi:include href="crash_dump.xml"/> <xi:include href="alt_dist.xml"/> diff --git a/erts/doc/src/time_correction.xml b/erts/doc/src/time_correction.xml new file mode 100644 index 0000000000..d52cc7f3e2 --- /dev/null +++ b/erts/doc/src/time_correction.xml @@ -0,0 +1,274 @@ +<?xml version="1.0" encoding="utf8" ?> +<!DOCTYPE chapter SYSTEM "chapter.dtd"> + +<chapter> + <header> + <copyright> + <year>1999</year><year>2013</year> + <holder>Ericsson AB. All Rights Reserved.</holder> + </copyright> + <legalnotice> + The contents of this file are subject to the Erlang Public License, + Version 1.1, (the "License"); you may not use this file except in + compliance with the License. You should have received a copy of the + Erlang Public License along with this software. If not, it can be + retrieved online at http://www.erlang.org/. + + Software distributed under the License is distributed on an "AS IS" + basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + the License for the specific language governing rights and limitations + under the License. + + </legalnotice> + + <title>Time and time correction in Erlang</title> + <prepared>Patrik Nyblom</prepared> + <responsible></responsible> + <docno></docno> + <approved></approved> + <checked></checked> + <date>2013-08-28</date> + <rev>PA1</rev> + <file>time_correction.xml</file> + </header> + <p>Time is vital to an Erlang program and, more importantly, <em>correct</em> + time is vital to an Erlang program. As Erlang is a language with + soft real time properties and we have the possibility to express + time in our programs, the Virtual Machine and the language has to be + very careful about what is considered a correct point in time and in + how time functions behave.</p> + + <p>In the beginning, Erlang was constructed assuming that the wall + clock time in the system showed a monotonic time moving forward at + exactly the same pace as the definition of time. That more or less + meant that an atomic clock (or better) was expected to be attached + to your hardware and that the hardware was then expected to be + locked away from any human (or unearthly) tinkering for all + eternity. While this might be a compelling thought, it's simply + never the case.</p> + + <p>A "normal" modern computer can not keep time. Not on itself and + not unless you actually have a chip level atomic clock wired to + it. Time, as perceived by your computer, will normally need to be + corrected. Hence the NTP protocol that together with the ntpd + process will do it's best to keep your computers time in sync with + the "real" time in the universe. Between NTP corrections, usually a + less potent time-keeper than an atomic clock is used.</p> + + <p>But NTP is not fail safe. The NTP server can be unavailable, the + ntp.conf can be wrongly configured or your computer may from time to + time be disconnected from the internet. Furthermore you can have a + user (or even system administrator) on your system that thinks the + right way to handle daylight saving time is to adjust the clock one + hour two times a year (a tip, that is not the right way to do + it...). To further complicate things, this user fetched your + software from the internet and has never ever thought about what's + the correct time as perceived by a computer. The user simply does + not care about keeping the wall clock in sync with the rest of the + universe. The user expects your program to have omnipotent knowledge + about the time.</p> + + <p>Most programmers also expect time to be reliable, at least until + they realize that the wall clock time on their workstation is of by + a minute. Then they simply set it to the correct time, maybe or + maybe not in a smooth way. Most probably not in a smooth way.</p> + + <p>The amount of problems that arise when you expect the wall clock + time on the system to always be correct may be immense. Therefore Erlang + introduced the "corrected estimate of time", or the "time + correction" many years ago. The time correction relies on the fact + that most operating systems have some kind of monotonic clock, + either a real time extension or some built in "tick counter" that is + independent of the wall clock settings. This counter may have + microsecond resolution or much less, but generally it has a drift + that is not to be ignored.</p> + + <p>So we have this monotonic ticking and we have the wall clock + time. Two unreliable times that together can give us an estimate of + an actual wall clock time that does not jump around and that + monotonically moves forward. If the tick counter has a high + resolution, this is fairly easy to do, if the counter has a low + resolution, it's more expensive, but still doable down to + frequencies of 50-60 Hz (of the tick counter).</p> + + <p>So the corrected time is the nearest approximation of an atomic + clock that is available on the computer. We want it to have the + following properties:</p> + <taglist> + <tag>Monotonic</tag> + <item>The clock should not move backwards</item> + <tag>Intervals should be near the truth</tag> + <item>We want the actual time (as measured by an atomic clock or + an astronomer) that passes between two time stamps, T1 and T2, to be as + near to T2 - T1 as possible.</item> + <tag>Tight coupling to the wall clock</tag> + <item>We want a timer that is to be fired when the wall clock + reaches a time in the future, to fire as near to that point in + time as possible</item> + </taglist> + <p>To meet all the criteria, we have to utilize both times in such a + way that Erlangs "corrected time" moves slightly slower or slightly + faster than the wall clock to get in sync with it. The word + "slightly" means a maximum of 1% difference to the wall clock time, + meaning that a sudden change in the wall clock of one minute, takes + 100 minutes to fix, by letting all "corrected time" move 1% slower + or faster.</p> + + <p>Needless to say, correcting for a faulty handling of daylight + saving time may be disturbing to a user comparing wall clock + time to for example calendar:now_to_local_time(erlang:now()). But + calendar:now_to_local_time/1 is not supposed to be used for presenting wall + clock time to the user.</p> + + <p>Time correction is not perfect, but it saves you from the havoc + of clocks jumping around, which would make timers in your program + fire far to late or far to early and could bring your whole system + to it's knees (or worse) just because someone detected a small error + in the wall clock time of the server where your program runs. So + while it might be confusing, it is still a really good feature of + Erlang and you should not throw it away using time functions which + may give you higher benchmark results, not unless you really know + what you're doing.</p> + + <section> + <title>What does time correction mean in my system?</title> + <p>Time correction means that Erlang estimates a time from current + and previous settings of the wall clock, and it uses a fairly + exact tick counter to detect when the wall clock time has jumped + for some reason, slowly adjusting to the new value.</p> + + <p>In practice, this means that the difference between two calls + to time corrected functions, like erlang:now(), might differ up to + one percent from the corresponding calls to non time corrected + functions (like os:timestamp()). Furthermore, if comparing + calendar:local_time/0 to calendar:now_to_local_time(erlang:now()), + you might temporarily see a difference, depending on how well kept your + system is.</p> + + <p>It is important to understand that it is (to the program) + always unknown if it is the wall clock time that moves in the + wrong pace or the Erlang corrected time. The only way to determine + that, is to have an external source of universally correct time. If + some such source is available, the wall clock time can be kept + nearly perfect at all times, and no significant difference will be + detected between erlang:now/0's pace and the wall clock's.</p> + + <p>Still, the time correction will mean that your system keeps + it's real time characteristics very well, even when the wall clock + is unreliable.</p> + </section> + <section> + <title>Where does Erlang use corrected time?</title> + <p>For all functionality where real time characteristics are + desirable, time correction is used. This basically means:</p> + <taglist> + <tag>erlang:now/0</tag> + <item>The infamous erlang:now/0 function uses time correction so + that differences between two "now-timestamps" will correspond to + other timeouts in the system. erlang:now/0 also holds other + properties, discussed later.</item> + <tag>receive ... after</tag> + <item>Timeouts on receive uses time correction to determine a + stable timeout interval.</item> + <tag>The timer module</tag> + <item>As the timer module uses other built in functions which + deliver corrected time, the timer module itself works with + corrected time.</item> + <tag>erlang:start_timer/3 and erlang:send_after/3</tag> + <item>The timer BIF's work with corrected time, so that they + will not fire prematurely or too late due to changes in the wall + clock time.</item> + </taglist> + + <p>All other functionality in the system where erlang:now/0 or any + other time corrected functionality is used, will of course + automatically benefit from it, as long as it's not "optimized" to + use some other time stamp function (like os:timestamp/0).</p> + + <p>Modules like calendar and functions like erlang:localtime/0 use + the wall clock time as it is currently set on the system. They + will not use corrected time. However, if you use a now-value and + convert it to local time, you will get a corrected local time + value, which may or may not be what you want. Typically older code + tend to use erlang:now/0 as a wall clock time, which is usually + correct (at least when testing), but might surprise you when + compared to other times in the system.</p> + </section> + <section> + <title>What is erlang:now/0 really?</title> + <p>erlang:now/0 is a function designed to serve multiple purposes + (or a multi-headed beast if you're a VM designer). It is expected + to hold the following properties:</p> + <taglist> + <tag>Monotonic</tag> + <item>erlang:now() never jumps backwards - it always moves + forward</item> + <tag>Interval correct</tag> + <item>The interval between two erlang:now() calls is expected to + correspond to the correct time in real life (as defined by an + atomic clock, or better)</item> + <tag>Absolute correctness</tag> + <item>The erlang:now/0 value should be possible to convert to an + absolute and correct date-time, corresponding to the real world + date and time (the wall clock)</item> + <tag>System correspondence</tag> + <item>The erlang:now/0 value converted to a date-time is + expected to correspond to times given by other programs on the + system (or by functions like os:timestamp/0)</item> + <tag>Unique</tag> + <item>No two calls to erlang:now on one Erlang node should + return the same value</item> + </taglist> + <p>All these requirements are possible to uphold at the same + time if (and only if):</p> + <taglist> + <tag>The wall clock time of the system is perfect</tag> + <item>The system (Operating System) time needs to be perfectly + in sync with the actual time as defined by an atomic clock or + a better time source. A good installation using NTP, and that is + up to date before Erlang starts, will have properties that for + most users and programs will be near indistinguishable from the + perfect time. Note that any larger corrections to the time done + by hand, or after Erlang has started, will partly (or + temporarily) invalidate some of the properties, as the time is + no longer perfect.</item> + <tag>Less than one call per microsecond to erlang:now/0 is + done</tag> + <item>This means that at <em>any</em> microsecond interval in + time, there can be no more than one call to erlang:now/0 in the + system. However, for the system not to loose it's properties + completely, it's enough that it on average is no more than one + call per microsecond (in one Erlang node).</item> + </taglist> + <p>The uniqueness property of erlang:now/0 is the most limiting + property. It means that erlang:now() maintains a global state and + that there is a hard-to-check property of the system that needs to + be maintained. For most applications this is still not a problem, + but a future system might very well manage to violate the + frequency limit on the calls globally. The uniqueness property is + also quite useless, as there are globally unique references that + provide a much better unique value to programs. However the + property will need to be maintained unless a really subtle + backward compatibility issue is to be introduced.</p> + </section> + <section> + <title>Should I use erlang:now/0 or os:timestamp/0</title> + <p>The simple answer is to use erlang:now/0 for everything where + you want to keep real time characteristics, but use os:timestamp + for things like logs, user communication and debugging (typically + timer:ts uses os:timestamp, as it is a test tool, not a real world + application API). The benefit of using os:timestamp/0 is that it's + faster and does not involve any global state (unless the operating + system has one). The downside is that it will be vulnerable to wall + clock time changes.</p> + </section> + <section> + <title>Turning off time correction</title> + <p>If, for some reason, time correction causes trouble and you are + absolutely confident that the wall clock on the system is nearly + perfect, you can turn off time correction completely by giving the + <c>+c</c> option to <c>erl</c>. The probability for this being a + good idea, is very low.</p> + </section> +</chapter> + diff --git a/erts/emulator/Makefile.in b/erts/emulator/Makefile.in index 048e92baad..5638683f88 100644 --- a/erts/emulator/Makefile.in +++ b/erts/emulator/Makefile.in @@ -852,6 +852,7 @@ OS_OBJS += $(OBJDIR)/erl_poll.o \ endif OS_OBJS += $(OBJDIR)/erl_mseg.o \ + $(OBJDIR)/erl_mmap.o \ $(OBJDIR)/erl_$(ERLANG_OSTYPE)_sys_ddll.o \ $(OBJDIR)/erl_mtrace_sys_wrap.o \ $(OBJDIR)/erl_sys_common_misc.o diff --git a/erts/emulator/beam/beam_emu.c b/erts/emulator/beam/beam_emu.c index da36c4437e..78ab6fa30f 100644 --- a/erts/emulator/beam/beam_emu.c +++ b/erts/emulator/beam/beam_emu.c @@ -5654,7 +5654,6 @@ build_stacktrace(Process* c_p, Eterm exc) { return res; } - static BeamInstr* call_error_handler(Process* p, BeamInstr* fi, Eterm* reg, Eterm func) { @@ -5702,7 +5701,6 @@ call_error_handler(Process* p, BeamInstr* fi, Eterm* reg, Eterm func) return ep->addressv[erts_active_code_ix()]; } - static Export* apply_setup_error_handler(Process* p, Eterm module, Eterm function, Uint arity, Eterm* reg) { @@ -6208,7 +6206,6 @@ new_fun(Process* p, Eterm* reg, ErlFunEntry* fe, int num_free) return make_fun(funp); } - int catchlevel(Process *p) { diff --git a/erts/emulator/beam/beam_load.c b/erts/emulator/beam/beam_load.c index 4193eb4f3f..938fd8f2c9 100644 --- a/erts/emulator/beam/beam_load.c +++ b/erts/emulator/beam/beam_load.c @@ -535,7 +535,6 @@ static int must_swap_floats; Uint erts_total_code_size; /**********************************************************************/ - void init_load(void) { FloatDef f; @@ -1209,7 +1208,6 @@ verify_chunks(LoaderState* stp) return 0; } - static int load_atom_table(LoaderState* stp) { @@ -1255,7 +1253,6 @@ load_atom_table(LoaderState* stp) return 0; } - static int load_import_table(LoaderState* stp) { @@ -1308,7 +1305,6 @@ load_import_table(LoaderState* stp) return 0; } - static int read_export_table(LoaderState* stp) { @@ -1641,7 +1637,6 @@ read_line_table(LoaderState* stp) return 0; } - static int read_code_header(LoaderState* stp) { @@ -1711,7 +1706,6 @@ read_code_header(LoaderState* stp) return 0; } - #define VerifyTag(Stp, Actual, Expected) \ if (Actual != Expected) { \ LoadError2(Stp, "bad tag %d; expected %d", Actual, Expected); \ @@ -1730,7 +1724,6 @@ read_code_header(LoaderState* stp) #define TermWords(t) (((t) / (sizeof(BeamInstr)/sizeof(Eterm))) + !!((t) % (sizeof(BeamInstr)/sizeof(Eterm)))) - static int load_code(LoaderState* stp) { @@ -2512,7 +2505,6 @@ load_code(LoaderState* stp) return retval; } - #define succ(St, X, Y) ((X).type == (Y).type && (X).val + 1 == (Y).val) #define succ2(St, X, Y) ((X).type == (Y).type && (X).val + 2 == (Y).val) #define succ3(St, X, Y) ((X).type == (Y).type && (X).val + 3 == (Y).val) @@ -3958,7 +3950,6 @@ tuple_append_put(LoaderState* stp, GenOpArg Arity, GenOpArg Dst, } - /* * Freeze the code in memory, move the string table into place, * resolve all labels. @@ -4276,7 +4267,6 @@ freeze_code(LoaderState* stp) return 0; } - static void final_touch(LoaderState* stp) { @@ -4378,7 +4368,6 @@ final_touch(LoaderState* stp) } } - static int transform_engine(LoaderState* st) { @@ -4716,7 +4705,6 @@ transform_engine(LoaderState* st) return rval; } - static void short_file(int line, LoaderState* stp, unsigned needed) { @@ -4724,7 +4712,6 @@ short_file(int line, LoaderState* stp, unsigned needed) stp->file_name, needed); } - static void load_printf(int line, LoaderState* context, char *fmt,...) { @@ -5190,7 +5177,6 @@ native_addresses(Process* p, Eterm mod) return result; } - /* * Builds a list of all exported functions in the given module: * [{Name, Arity},...] @@ -5240,7 +5226,6 @@ exported_from_module(Process* p, /* Process whose heap to use. */ return result; } - /* * Returns a list of all attributes for the module. * @@ -5281,7 +5266,6 @@ attributes_for_module(Process* p, /* Process whose heap to use. */ return result; } - /* * Returns a list containing compilation information. * diff --git a/erts/emulator/beam/big.c b/erts/emulator/beam/big.c index 6b43c53985..2b27b111d8 100644 --- a/erts/emulator/beam/big.c +++ b/erts/emulator/beam/big.c @@ -1325,9 +1325,9 @@ static dsize_t I_lshift(ErtsDigit* x, dsize_t xl, Sint y, return 1; } else { - SWord ay = (y < 0) ? -y : y; - int bw = ay / D_EXP; - int sw = ay % D_EXP; + Uint ay = (y < 0) ? -y : y; + Uint bw = ay / D_EXP; + Uint sw = ay % D_EXP; dsize_t rl; ErtsDigit a1=0; ErtsDigit a0=0; @@ -1368,7 +1368,7 @@ static dsize_t I_lshift(ErtsDigit* x, dsize_t xl, Sint y, } if (sign) { - int zl = bw; + Uint zl = bw; ErtsDigit* z = x; while(zl--) { diff --git a/erts/emulator/beam/dist.c b/erts/emulator/beam/dist.c index 44f4eb9d43..aabccac822 100644 --- a/erts/emulator/beam/dist.c +++ b/erts/emulator/beam/dist.c @@ -353,7 +353,7 @@ static void doit_link_net_exits_sub(ErtsLink *sublnk, void *vlnecp) static void doit_link_net_exits(ErtsLink *lnk, void *vnecp) { LinkNetExitsContext lnec = {(NetExitsContext *) vnecp, lnk}; - ASSERT(lnk->type == LINK_PID) + ASSERT(lnk->type == LINK_PID); erts_sweep_links(ERTS_LINK_ROOT(lnk), &doit_link_net_exits_sub, (void *) &lnec); #ifdef DEBUG ERTS_LINK_ROOT(lnk) = NULL; @@ -369,7 +369,7 @@ static void doit_node_link_net_exits(ErtsLink *lnk, void *vnecp) Process *rp; ErtsLink *rlnk; Uint i,n; - ASSERT(lnk->type == LINK_NODE) + ASSERT(lnk->type == LINK_NODE); if (is_internal_pid(lnk->pid)) { ErtsProcLocks rp_locks = ERTS_PROC_LOCK_LINK; rp = erts_pid2proc(NULL, 0, lnk->pid, rp_locks); diff --git a/erts/emulator/beam/erl_alloc.c b/erts/emulator/beam/erl_alloc.c index 5eacff8829..d8da616d05 100644 --- a/erts/emulator/beam/erl_alloc.c +++ b/erts/emulator/beam/erl_alloc.c @@ -267,7 +267,6 @@ set_default_sl_alloc_opts(struct au_init *ip) ip->atype = GOODFIT; #endif ip->init.util.name_prefix = "sl_"; - ip->init.util.mmmbc = 5; ip->init.util.alloc_no = ERTS_ALC_A_SHORT_LIVED; #ifndef SMALL_MEMORY ip->init.util.mmbcs = 128*1024; /* Main carrier size */ @@ -295,7 +294,6 @@ set_default_std_alloc_opts(struct au_init *ip) ip->atype = BESTFIT; #endif ip->init.util.name_prefix = "std_"; - ip->init.util.mmmbc = 5; ip->init.util.alloc_no = ERTS_ALC_A_STANDARD; #ifndef SMALL_MEMORY ip->init.util.mmbcs = 128*1024; /* Main carrier size */ @@ -319,7 +317,6 @@ set_default_ll_alloc_opts(struct au_init *ip) #endif ip->init.util.ramv = 0; ip->init.util.mmsbc = 0; - ip->init.util.mmmbc = 0; ip->init.util.sbct = ~((UWord) 0); ip->init.util.name_prefix = "ll_"; ip->init.util.alloc_no = ERTS_ALC_A_LONG_LIVED; @@ -370,7 +367,6 @@ set_default_eheap_alloc_opts(struct au_init *ip) ip->thr_spec = 1; ip->atype = GOODFIT; #endif - ip->init.util.mmmbc = 100; ip->init.util.name_prefix = "eheap_"; ip->init.util.alloc_no = ERTS_ALC_A_EHEAP; #ifndef SMALL_MEMORY @@ -397,7 +393,6 @@ set_default_binary_alloc_opts(struct au_init *ip) ip->thr_spec = 1; ip->atype = BESTFIT; #endif - ip->init.util.mmmbc = 50; ip->init.util.name_prefix = "binary_"; ip->init.util.alloc_no = ERTS_ALC_A_BINARY; #ifndef SMALL_MEMORY @@ -419,7 +414,6 @@ set_default_ets_alloc_opts(struct au_init *ip) ip->thr_spec = 1; ip->atype = BESTFIT; #endif - ip->init.util.mmmbc = 100; ip->init.util.name_prefix = "ets_"; ip->init.util.alloc_no = ERTS_ALC_A_ETS; #ifndef SMALL_MEMORY @@ -495,13 +489,6 @@ adjust_tpref(struct au_init *ip, int no_sched) /* ... shrink smallest multi-block carrier size */ if (ip->default_.smbcs) ip->init.util.smbcs /= ERTS_MIN(4, no_sched); - /* ... and more than three allocators shrink - max mseg multi-block carriers */ - if (ip->default_.mmmbc && no_sched > 2) { - ip->init.util.mmmbc /= ERTS_MIN(4, no_sched - 1); - if (ip->init.util.mmmbc < 3) - ip->init.util.mmmbc = 3; - } } } @@ -731,6 +718,7 @@ erts_alloc_init(int *argc, char **argv, ErtsAllocInitOpts *eaiop) init.mseg.nos = erts_no_schedulers; erts_mseg_init(&init.mseg); #endif + erts_alcu_init(&init.alloc_util); erts_afalc_init(); erts_bfalc_init(); @@ -1187,6 +1175,25 @@ get_kb_value(char *param_end, char** argv, int* ip) return ((Uint) tmp)*1024; } +static UWord +get_mb_value(char *param_end, char** argv, int* ip) +{ + SWord tmp; + UWord max = ((~((UWord) 0))/(1024*1024)) + 1; + char *rest; + char *param = argv[*ip]+1; + char *value = get_value(param_end, argv, ip); + errno = 0; + tmp = (SWord) ErtsStrToSint(value, &rest, 10); + if (errno != 0 || rest == value || tmp < 0 || max < ((UWord) tmp)) + bad_value(param, param_end, value); + if (max == (UWord) tmp) + return ~((UWord) 0); + else + return ((UWord) tmp)*1024*1024; +} + + #if 0 static Uint get_byte_value(char *param_end, char** argv, int* ip) @@ -1461,6 +1468,30 @@ handle_args(int *argc, char **argv, erts_alc_hndl_args_init_t *init) #endif get_amount_value(argv[i]+6, argv, &i); } + else if (has_prefix("scs", argv[i]+3)) { +#if HAVE_ERTS_MSEG + init->mseg.mmap.scs = +#endif + get_mb_value(argv[i]+6, argv, &i); + } + else if (has_prefix("sco", argv[i]+3)) { +#if HAVE_ERTS_MSEG + init->mseg.mmap.sco = +#endif + get_bool_value(argv[i]+6, argv, &i); + } + else if (has_prefix("scrpm", argv[i]+3)) { +#if HAVE_ERTS_MSEG + init->mseg.mmap.scrpm = +#endif + get_bool_value(argv[i]+8, argv, &i); + } + else if (has_prefix("scmgc", argv[i]+3)) { +#if HAVE_ERTS_MSEG + init->mseg.mmap.scmgc = +#endif + get_amount_value(argv[i]+8, argv, &i); + } else { bad_param(param, param+2); } @@ -1560,7 +1591,6 @@ handle_args(int *argc, char **argv, erts_alc_hndl_args_init_t *init) aui[a]->thr_spec = 0; check_disable_carrier_migration(aui[a]); aui[a]->init.util.ramv = 0; - aui[a]->init.util.mmmbc = 10; aui[a]->init.util.lmbcs = 5*1024*1024; } } @@ -2682,6 +2712,7 @@ erts_allocator_info(int to, void *arg) #if HAVE_ERTS_MSEG { + struct erts_mmap_info_struct emis; #ifdef ERTS_SMP int max = (int) erts_no_schedulers; #else @@ -2692,6 +2723,8 @@ erts_allocator_info(int to, void *arg) erts_print(to, arg, "=allocator:mseg_alloc[%d]\n", i); erts_mseg_info(i, &to, arg, 0, NULL, NULL); } + erts_print(to, arg, "=allocator:mseg_alloc.erts_mmap\n"); + erts_mmap_info(&to, arg, NULL, NULL, &emis); } #endif @@ -2716,8 +2749,8 @@ erts_allocator_options(void *proc) #endif Uint sz, *szp, *hp, **hpp; Eterm res, features, settings; - Eterm atoms[ERTS_ALC_A_MAX-ERTS_ALC_A_MIN+5]; - Uint terms[ERTS_ALC_A_MAX-ERTS_ALC_A_MIN+5]; + Eterm atoms[ERTS_ALC_A_MAX-ERTS_ALC_A_MIN+6]; + Uint terms[ERTS_ALC_A_MAX-ERTS_ALC_A_MIN+6]; int a, length; SysAllocStat sas; Uint *endp = NULL; @@ -2830,6 +2863,9 @@ erts_allocator_options(void *proc) if (use_mseg) terms[length++] = am_atom_put("mseg_alloc", 10); #endif +#if ERTS_HAVE_ERTS_SYS_ALIGNED_ALLOC + terms[length++] = am_atom_put("sys_aligned_alloc", 17); +#endif features = length ? erts_bld_list(hpp, szp, length, terms) : NIL; @@ -2915,6 +2951,7 @@ reply_alloc_info(void *vair) Uint sz, *szp; ErlOffHeap *ohp = NULL; ErlHeapFragment *bp = NULL; + struct erts_mmap_info_struct emis; int i; Eterm (*info_func)(Allctr_t *, int, @@ -3027,15 +3064,23 @@ reply_alloc_info(void *vair) ? NIL : erts_mseg_info(0, NULL, NULL, hpp != NULL, hpp, szp)); - ainfo = erts_bld_tuple(hpp, szp, 3, - alloc_atom, - make_small(0), - ainfo); + ainfo = erts_bld_tuple3(hpp, szp, + alloc_atom, + make_small(0), + ainfo); + + ai_list = erts_bld_cons(hpp, szp, + ainfo, ai_list); + ainfo = (air->only_sz ? NIL : erts_mmap_info(NULL, NULL, hpp, szp, &emis)); + ainfo = erts_bld_tuple3(hpp, szp, + alloc_atom, + erts_bld_atom(hpp,szp,"erts_mmap"), + ainfo); #else - ainfo = erts_bld_tuple(hpp, szp, 2, alloc_atom, - am_false); + ainfo = erts_bld_tuple2(hpp, szp, alloc_atom, + am_false); #endif - break; + break; default: alloc_atom = erts_bld_atom(hpp, szp, (char *) ERTS_ALC_A2AD(ai)); diff --git a/erts/emulator/beam/erl_alloc.h b/erts/emulator/beam/erl_alloc.h index b5975c6c32..f83f6b39cf 100644 --- a/erts/emulator/beam/erl_alloc.h +++ b/erts/emulator/beam/erl_alloc.h @@ -54,6 +54,16 @@ void erts_sys_alloc_init(void); void *erts_sys_alloc(ErtsAlcType_t, void *, Uint); void *erts_sys_realloc(ErtsAlcType_t, void *, void *, Uint); void erts_sys_free(ErtsAlcType_t, void *, void *); +#if ERTS_HAVE_ERTS_SYS_ALIGNED_ALLOC +/* + * Note 'alignment' must remain the same in calls to + * 'erts_sys_aligned_realloc()' and 'erts_sys_aligned_free()' + * as in the initial call to 'erts_sys_aligned_alloc()'. + */ +void *erts_sys_aligned_alloc(UWord alignment, UWord size); +void *erts_sys_aligned_realloc(UWord alignment, void *ptr, UWord size, UWord old_size); +void erts_sys_aligned_free(UWord alignment, void *ptr); +#endif Eterm erts_memory(int *, void *, void *, Eterm); Eterm erts_allocated_areas(int *, void *, void *); diff --git a/erts/emulator/beam/erl_alloc_util.c b/erts/emulator/beam/erl_alloc_util.c index e6d9f83aed..1fdee4db2c 100644 --- a/erts/emulator/beam/erl_alloc_util.c +++ b/erts/emulator/beam/erl_alloc_util.c @@ -81,16 +81,12 @@ static int atoms_initialized = 0; static int initialized = 0; - #define INV_SYS_ALLOC_CARRIER_MASK ((UWord) (sys_alloc_carrier_size - 1)) #define SYS_ALLOC_CARRIER_MASK (~INV_SYS_ALLOC_CARRIER_MASK) #define SYS_ALLOC_CARRIER_FLOOR(X) ((X) & SYS_ALLOC_CARRIER_MASK) #define SYS_ALLOC_CARRIER_CEILING(X) \ SYS_ALLOC_CARRIER_FLOOR((X) + INV_SYS_ALLOC_CARRIER_MASK) -#undef ASSERT -#define ASSERT ASSERT_EXPR - #if 0 /* Can be useful for debugging */ #define MBC_REALLOC_ALWAYS_MOVES @@ -194,9 +190,9 @@ MBC after deallocating first block: #if MBC_ABLK_OFFSET_BITS -# define MBC_SZ_MAX_LIMIT ((((UWord)1 << MBC_ABLK_OFFSET_BITS) - 1) << MSEG_ALIGN_BITS) +# define MBC_SZ_MAX_LIMIT ((((UWord)1 << MBC_ABLK_OFFSET_BITS) - 1) << ERTS_SUPER_ALIGN_BITS) -# define BLK_CARRIER_OFFSET(B, C) (((char*)(B) - (char*)(C)) >> MSEG_UNIT_SHIFT) +# define BLK_CARRIER_OFFSET(B, C) (((char*)(B) - (char*)(C)) >> ERTS_SACRR_UNIT_SHIFT) # define SET_MBC_ABLK_HDR(B, Sz, F, C) \ (ASSERT(((Sz) & ~MBC_ABLK_SZ_MASK) == 0), \ @@ -210,7 +206,7 @@ MBC after deallocating first block: (B)->u.carrier = (C)) # define IS_MBC_FIRST_ABLK(AP,B) \ - ((((UWord)(B) & ~MSEG_UNIT_MASK) == MBC_HEADER_SIZE(AP)) \ + ((((UWord)(B) & ~ERTS_SACRR_UNIT_MASK) == MBC_HEADER_SIZE(AP)) \ && ((B)->bhdr & MBC_ABLK_OFFSET_MASK) == 0) # define IS_MBC_FIRST_FBLK(AP,B) \ @@ -760,8 +756,9 @@ static ERTS_INLINE void * alcu_mseg_alloc(Allctr_t *allctr, Uint *size_p, Uint flags) { void *res; - - res = erts_mseg_alloc_opt(allctr->alloc_no, size_p, flags, &allctr->mseg_opt); + UWord size = (UWord) *size_p; + res = erts_mseg_alloc_opt(allctr->alloc_no, &size, flags, &allctr->mseg_opt); + *size_p = (Uint) size; INC_CC(allctr->calls.mseg_alloc); return res; } @@ -770,9 +767,10 @@ static ERTS_INLINE void * alcu_mseg_realloc(Allctr_t *allctr, void *seg, Uint old_size, Uint *new_size_p) { void *res; - - res = erts_mseg_realloc_opt(allctr->alloc_no, seg, old_size, new_size_p, + UWord new_size = (UWord) *new_size_p; + res = erts_mseg_realloc_opt(allctr->alloc_no, seg, (UWord) old_size, &new_size, ERTS_MSEG_FLG_NONE, &allctr->mseg_opt); + *new_size_p = (Uint) new_size; INC_CC(allctr->calls.mseg_realloc); return res; } @@ -780,18 +778,22 @@ alcu_mseg_realloc(Allctr_t *allctr, void *seg, Uint old_size, Uint *new_size_p) static ERTS_INLINE void alcu_mseg_dealloc(Allctr_t *allctr, void *seg, Uint size, Uint flags) { - erts_mseg_dealloc_opt(allctr->alloc_no, seg, size, flags, &allctr->mseg_opt); + erts_mseg_dealloc_opt(allctr->alloc_no, seg, (UWord) size, flags, &allctr->mseg_opt); INC_CC(allctr->calls.mseg_dealloc); } #endif static ERTS_INLINE void * -alcu_sys_alloc(Allctr_t *allctr, Uint size) +alcu_sys_alloc(Allctr_t *allctr, Uint size, int superalign) { void *res; - - res = erts_sys_alloc(0, NULL, size); +#if ERTS_SA_MB_CARRIERS && ERTS_HAVE_ERTS_SYS_ALIGNED_ALLOC + if (superalign) + res = erts_sys_aligned_alloc(ERTS_SACRR_UNIT_SZ, size); + else +#endif + res = erts_sys_alloc(0, NULL, size); INC_CC(allctr->calls.sys_alloc); if (erts_mtrace_enabled) erts_mtrace_crr_alloc(res, allctr->alloc_no, ERTS_ALC_A_SYSTEM, size); @@ -799,11 +801,16 @@ alcu_sys_alloc(Allctr_t *allctr, Uint size) } static ERTS_INLINE void * -alcu_sys_realloc(Allctr_t *allctr, void *ptr, Uint size) +alcu_sys_realloc(Allctr_t *allctr, void *ptr, Uint size, Uint old_size, int superalign) { void *res; - res = erts_sys_realloc(0, NULL, ptr, size); +#if ERTS_SA_MB_CARRIERS && ERTS_HAVE_ERTS_SYS_ALIGNED_ALLOC + if (superalign) + res = erts_sys_aligned_realloc(ERTS_SACRR_UNIT_SZ, ptr, size, old_size); + else +#endif + res = erts_sys_realloc(0, NULL, ptr, size); INC_CC(allctr->calls.sys_realloc); if (erts_mtrace_enabled) erts_mtrace_crr_realloc(res, @@ -815,9 +822,14 @@ alcu_sys_realloc(Allctr_t *allctr, void *ptr, Uint size) } static ERTS_INLINE void -alcu_sys_free(Allctr_t *allctr, void *ptr) +alcu_sys_free(Allctr_t *allctr, void *ptr, int superalign) { - erts_sys_free(0, NULL, ptr); +#if ERTS_SA_MB_CARRIERS && ERTS_HAVE_ERTS_SYS_ALIGNED_ALLOC + if (superalign) + erts_sys_aligned_free(ERTS_SACRR_UNIT_SZ, ptr); + else +#endif + erts_sys_free(0, NULL, ptr); INC_CC(allctr->calls.sys_free); if (erts_mtrace_enabled) erts_mtrace_crr_free(allctr->alloc_no, ERTS_ALC_A_SYSTEM, ptr); @@ -1334,7 +1346,7 @@ erts_alcu_fix_alloc_shrink(Allctr_t *allctr, erts_aint32_t flgs) return fix_nocpool_alloc_shrink(allctr, flgs); } -static void dealloc_carrier(Allctr_t *allctr, Carrier_t *crr, Uint mseg_flags); +static void dealloc_carrier(Allctr_t *allctr, Carrier_t *crr, int superaligned); #ifdef ERTS_SMP @@ -1942,7 +1954,7 @@ mbc_alloc_block(Allctr_t *allctr, Uint size, Uint *blk_szp) if (!blk) { blk = create_carrier(allctr, get_blk_sz, CFLG_MBC); -#if !HALFWORD_HEAP && !HAVE_SUPER_ALIGNED_MB_CARRIERS +#if !HALFWORD_HEAP && !ERTS_SUPER_ALIGNED_MSEG_ONLY if (!blk) { /* Emergency! We couldn't create the carrier as we wanted. Try to place it in a sys_alloced sbc. */ @@ -2978,7 +2990,7 @@ check_pending_dealloc_carrier(Allctr_t *allctr, dcrr = crr; crr = crr->next; - dealloc_carrier(allctr, dcrr, ERTS_MSEG_FLG_2POW); + dealloc_carrier(allctr, dcrr, 1); i++; } while (crr && i < ERTS_ALC_MAX_DEALLOC_CARRIER); @@ -3013,7 +3025,7 @@ schedule_dealloc_carrier(Allctr_t *allctr, Carrier_t *crr) erts_aint_t max_size; if (!ERTS_ALC_IS_CPOOL_ENABLED(allctr)) { - dealloc_carrier(allctr, crr, ERTS_MSEG_FLG_2POW); + dealloc_carrier(allctr, crr, 1); return; } @@ -3053,7 +3065,7 @@ schedule_dealloc_carrier(Allctr_t *allctr, Carrier_t *crr) if (crr->cpool.thr_prgr == ERTS_THR_PRGR_INVALID || erts_thr_progress_has_reached(crr->cpool.thr_prgr)) { - dealloc_carrier(allctr, crr, ERTS_MSEG_FLG_2POW); + dealloc_carrier(allctr, crr, 1); return; } @@ -3188,10 +3200,10 @@ cpool_read_stat(Allctr_t *allctr, UWord *nocp, UWord *cszp, UWord *nobp, UWord * #ifdef DEBUG -#if HAVE_ERTS_MSEG -#define ASSERT_MSEG_UNIT_SIZE_MULTIPLE(CSZ) ASSERT((CSZ) % MSEG_UNIT_SZ == 0) +#if ERTS_SA_MB_CARRIERS +#define ASSERT_ERTS_SACRR_UNIT_SIZE_MULTIPLE(CSZ) ASSERT((CSZ) % ERTS_SACRR_UNIT_SZ == 0) #else -#define ASSERT_MSEG_UNIT_SIZE_MULTIPLE(CSZ) +#define ASSERT_ERTS_SACRR_UNIT_SIZE_MULTIPLE(CSZ) #endif static void CHECK_1BLK_CARRIER(Allctr_t* A, int SBC, int MSEGED, Carrier_t* C, @@ -3213,10 +3225,12 @@ static void CHECK_1BLK_CARRIER(Allctr_t* A, int SBC, int MSEGED, Carrier_t* C, ASSERT(IS_MBC_BLK((B))); ASSERT(IS_MB_CARRIER((C))); ASSERT(FBLK_TO_MBC(B) == (C)); + if ((MSEGED)) { + ASSERT_ERTS_SACRR_UNIT_SIZE_MULTIPLE((CSZ)); + } } if ((MSEGED)) { ASSERT(IS_MSEG_CARRIER((C))); - ASSERT_MSEG_UNIT_SIZE_MULTIPLE((CSZ)); } else { ASSERT(IS_SYS_ALLOC_CARRIER((C))); @@ -3244,7 +3258,7 @@ create_carrier(Allctr_t *allctr, Uint umem_sz, UWord flags) #if HALFWORD_HEAP flags |= CFLG_FORCE_MSEG; -#elif HAVE_SUPER_ALIGNED_MB_CARRIERS +#elif ERTS_SUPER_ALIGNED_MSEG_ONLY if (flags & CFLG_MBC) { flags |= CFLG_FORCE_MSEG; } @@ -3287,7 +3301,7 @@ create_carrier(Allctr_t *allctr, Uint umem_sz, UWord flags) if (allctr->sbcs.curr.norm.mseg.no >= allctr->max_mseg_sbcs) goto try_sys_alloc; } -#if !HAVE_SUPER_ALIGNED_MB_CARRIERS +#if !ERTS_SUPER_ALIGNED_MSEG_ONLY else { if (allctr->mbcs.curr.norm.mseg.no >= allctr->max_mseg_mbcs) goto try_sys_alloc; @@ -3350,12 +3364,12 @@ create_carrier(Allctr_t *allctr, Uint umem_sz, UWord flags) ? UNIT_CEILING(bcrr_sz) : SYS_ALLOC_CARRIER_CEILING(bcrr_sz)); - crr = (Carrier_t *) alcu_sys_alloc(allctr, crr_sz); + crr = (Carrier_t *) alcu_sys_alloc(allctr, crr_sz, flags & CFLG_MBC); if (!crr) { if (crr_sz > UNIT_CEILING(bcrr_sz)) { crr_sz = UNIT_CEILING(bcrr_sz); - crr = (Carrier_t *) alcu_sys_alloc(allctr, crr_sz); + crr = (Carrier_t *) alcu_sys_alloc(allctr, crr_sz, flags & CFLG_MBC); } if (!crr) { #if HAVE_ERTS_MSEG @@ -3453,7 +3467,7 @@ resize_carrier(Allctr_t *allctr, Block_t *old_blk, Uint umem_sz, UWord flags) if (!(flags & CFLG_FORCE_SYS_ALLOC)) { new_crr_sz = new_blk_sz + SBC_HEADER_SIZE; - new_crr_sz = MSEG_UNIT_CEILING(new_crr_sz); + new_crr_sz = ERTS_SACRR_UNIT_CEILING(new_crr_sz); new_crr = (Carrier_t *) alcu_mseg_realloc(allctr, old_crr, old_crr_sz, @@ -3503,7 +3517,9 @@ resize_carrier(Allctr_t *allctr, Block_t *old_blk, Uint umem_sz, UWord flags) new_crr = (Carrier_t *) alcu_sys_realloc(allctr, (void *) old_crr, - new_crr_sz); + new_crr_sz, + old_crr_sz, + 0); if (new_crr) { sys_realloc_success: SET_CARRIER_SZ(new_crr, new_crr_sz); @@ -3522,7 +3538,9 @@ resize_carrier(Allctr_t *allctr, Block_t *old_blk, Uint umem_sz, UWord flags) new_crr_sz = UNIT_CEILING(new_crr_sz); new_crr = (Carrier_t *) alcu_sys_realloc(allctr, (void *) old_crr, - new_crr_sz); + new_crr_sz, + old_crr_sz, + 0); if (new_crr) goto sys_realloc_success; } @@ -3541,7 +3559,7 @@ resize_carrier(Allctr_t *allctr, Block_t *old_blk, Uint umem_sz, UWord flags) (void *) BLK2UMEM(old_blk), MIN(new_blk_sz, old_blk_sz) - ABLK_HDR_SZ); unlink_carrier(&allctr->sbc_list, old_crr); - alcu_sys_free(allctr, old_crr); + alcu_sys_free(allctr, old_crr, 0); } else { /* Old carrier unchanged; restore... */ @@ -3554,14 +3572,17 @@ resize_carrier(Allctr_t *allctr, Block_t *old_blk, Uint umem_sz, UWord flags) } static void -dealloc_carrier(Allctr_t *allctr, Carrier_t *crr, Uint mseg_flags) +dealloc_carrier(Allctr_t *allctr, Carrier_t *crr, int superaligned) { #if HAVE_ERTS_MSEG if (IS_MSEG_CARRIER(crr)) - alcu_mseg_dealloc(allctr, crr, CARRIER_SZ(crr), mseg_flags); + alcu_mseg_dealloc(allctr, crr, CARRIER_SZ(crr), + (superaligned + ? ERTS_MSEG_FLG_2POW + : ERTS_MSEG_FLG_NONE)); else #endif - alcu_sys_free(allctr, crr); + alcu_sys_free(allctr, crr, superaligned); } static void @@ -3581,7 +3602,6 @@ destroy_carrier(Allctr_t *allctr, Block_t *blk, Carrier_t **busy_pcrr_pp) #if HAVE_ERTS_MSEG if (IS_MSEG_CARRIER(crr)) { - ASSERT(crr_sz % MSEG_UNIT_SZ == 0); STAT_MSEG_SBC_FREE(allctr, crr_sz, blk_sz); } else @@ -3590,7 +3610,7 @@ destroy_carrier(Allctr_t *allctr, Block_t *blk, Carrier_t **busy_pcrr_pp) unlink_carrier(&allctr->sbc_list, crr); - dealloc_carrier(allctr, crr, ERTS_MSEG_FLG_NONE); + dealloc_carrier(allctr, crr, 0); } else { ASSERT(IS_MBC_FIRST_FBLK(allctr, blk)); @@ -3624,7 +3644,7 @@ destroy_carrier(Allctr_t *allctr, Block_t *blk, Carrier_t **busy_pcrr_pp) unlink_carrier(&allctr->mbc_list, crr); #if HAVE_ERTS_MSEG if (IS_MSEG_CARRIER(crr)) { - ASSERT(crr_sz % MSEG_UNIT_SZ == 0); + ASSERT(crr_sz % ERTS_SACRR_UNIT_SZ == 0); STAT_MSEG_MBC_FREE(allctr, crr_sz); } else @@ -3635,10 +3655,9 @@ destroy_carrier(Allctr_t *allctr, Block_t *blk, Carrier_t **busy_pcrr_pp) #ifdef ERTS_SMP schedule_dealloc_carrier(allctr, crr); #else - dealloc_carrier(allctr, crr, ERTS_MSEG_FLG_2POW); + dealloc_carrier(allctr, crr, 1); #endif } - } @@ -5086,7 +5105,7 @@ do_erts_alcu_realloc(ErtsAlcType_t type, crr_sz = SYS_ALLOC_CARRIER_CEILING(used_sz); #if HAVE_ERTS_MSEG else - crr_sz = MSEG_UNIT_CEILING(used_sz); + crr_sz = ERTS_SACRR_UNIT_CEILING(used_sz); #endif diff_sz_val = crr_sz - used_sz; if (diff_sz_val < (~((Uint) 0) / 100)) @@ -5454,7 +5473,7 @@ erts_alcu_start(Allctr_t *allctr, AllctrInit_t *init) allctr->mbc_move_threshold = init->rmbcmt; #if HAVE_ERTS_MSEG allctr->max_mseg_sbcs = init->mmsbc; -# if HAVE_SUPER_ALIGNED_MB_CARRIERS +# if ERTS_SUPER_ALIGNED_MSEG_ONLY allctr->max_mseg_mbcs = ~(Uint)0; # else allctr->max_mseg_mbcs = init->mmmbc; @@ -5570,7 +5589,7 @@ erts_alcu_start(Allctr_t *allctr, AllctrInit_t *init) CFLG_MBC | CFLG_FORCE_SIZE | CFLG_NO_CPOOL -#if !HALFWORD_HEAP && !HAVE_SUPER_ALIGNED_MB_CARRIERS +#if !HALFWORD_HEAP && !ERTS_SUPER_ALIGNED_MSEG_ONLY | CFLG_FORCE_SYS_ALLOC #endif | CFLG_MAIN_CARRIER); @@ -5656,9 +5675,9 @@ erts_alcu_init(AlcUInit_t *init) #endif ASSERT(SBC_BLK_SZ_MASK == MBC_FBLK_SZ_MASK); /* see BLK_SZ */ #if HAVE_ERTS_MSEG - ASSERT(erts_mseg_unit_size() == MSEG_UNIT_SZ); + ASSERT(erts_mseg_unit_size() == ERTS_SACRR_UNIT_SZ); max_mseg_carriers = init->mmc; - sys_alloc_carrier_size = MSEG_UNIT_CEILING(init->ycs); + sys_alloc_carrier_size = ERTS_SACRR_UNIT_CEILING(init->ycs); #else /* #if HAVE_ERTS_MSEG */ sys_alloc_carrier_size = ((init->ycs + 4095) / 4096) * 4096; #endif @@ -5819,7 +5838,7 @@ check_blk_carrier(Allctr_t *allctr, Block_t *iblk) ASSERT(CARRIER_SZ(sbc) - SBC_HEADER_SIZE >= SBC_BLK_SZ(iblk)); #if HAVE_ERTS_MSEG if (IS_MSEG_CARRIER(sbc)) { - ASSERT(CARRIER_SZ(sbc) % MSEG_UNIT_SZ == 0); + ASSERT(CARRIER_SZ(sbc) % ERTS_SACRR_UNIT_SZ == 0); } #endif crr = sbc; @@ -5904,7 +5923,7 @@ check_blk_carrier(Allctr_t *allctr, Block_t *iblk) #if HAVE_ERTS_MSEG if (IS_MSEG_CARRIER(crr)) { - ASSERT(CARRIER_SZ(crr) % MSEG_UNIT_SZ == 0); + ASSERT(CARRIER_SZ(crr) % ERTS_SACRR_UNIT_SZ == 0); } #endif cl = &allctr->mbc_list; diff --git a/erts/emulator/beam/erl_alloc_util.h b/erts/emulator/beam/erl_alloc_util.h index 02cbe5c5d0..222f137024 100644 --- a/erts/emulator/beam/erl_alloc_util.h +++ b/erts/emulator/beam/erl_alloc_util.h @@ -75,7 +75,7 @@ typedef struct { #define ERTS_DEFAULT_ALCU_INIT { \ 1024*1024, /* (bytes) ycs: sys_alloc carrier size */\ - 1024 /* (amount) mmc: max mseg carriers */\ + ~((UWord) 0) /* (amount) mmc: max mseg carriers */ \ } #define ERTS_DEFAULT_ALLCTR_INIT { \ @@ -95,7 +95,7 @@ typedef struct { 50, /* (%) rmbcmt: rel mbc move threshold */\ 1024*1024, /* (bytes) mmbcs: main multiblock carrier size */\ 256, /* (amount) mmsbc: max mseg sbcs */\ - 10, /* (amount) mmmbc: max mseg mbcs */\ + ~((UWord) 0), /* (amount) mmmbc: max mseg mbcs */ \ 10*1024*1024, /* (bytes) lmbcs: largest mbc size */\ 1024*1024, /* (bytes) smbcs: smallest mbc size */\ 10, /* (amount) mbcgs: mbc growth stages */\ @@ -128,7 +128,7 @@ typedef struct { 80, /* (%) rsbcmt: rel sbc move threshold */\ 128*1024, /* (bytes) mmbcs: main multiblock carrier size */\ 256, /* (amount) mmsbc: max mseg sbcs */\ - 10, /* (amount) mmmbc: max mseg mbcs */\ + ~((UWord) 0), /* (amount) mmmbc: max mseg mbcs */ \ 1024*1024, /* (bytes) lmbcs: largest mbc size */\ 128*1024, /* (bytes) smbcs: smallest mbc size */\ 10, /* (amount) mbcgs: mbc growth stages */\ @@ -217,25 +217,34 @@ erts_aint32_t erts_alcu_fix_alloc_shrink(Allctr_t *, erts_aint32_t); #define MBC_FBLK_SZ_MASK UNIT_MASK #define CARRIER_SZ_MASK UNIT_MASK -#if HAVE_ERTS_MSEG - -# define MSEG_UNIT_SHIFT MSEG_ALIGN_BITS -# define MSEG_UNIT_SZ (1 << MSEG_UNIT_SHIFT) -# define MSEG_UNIT_MASK ((~(UWord)0) << MSEG_UNIT_SHIFT) - -# define MSEG_UNIT_FLOOR(X) ((X) & MSEG_UNIT_MASK) -# define MSEG_UNIT_CEILING(X) MSEG_UNIT_FLOOR((X) + ~MSEG_UNIT_MASK) - +#if ERTS_HAVE_MSEG_SUPER_ALIGNED \ + || (!HAVE_ERTS_MSEG && ERTS_HAVE_ERTS_SYS_ALIGNED_ALLOC) +# ifndef MSEG_ALIGN_BITS +# define ERTS_SUPER_ALIGN_BITS MSEG_ALIGN_BITS +# else +# define ERTS_SUPER_ALIGN_BITS 18 +# endif # ifdef ARCH_64 # define MBC_ABLK_OFFSET_BITS 24 -# elif HAVE_SUPER_ALIGNED_MB_CARRIERS +# else # define MBC_ABLK_OFFSET_BITS 9 /* Affects hard limits for sbct and lmbcs documented in erts_alloc.xml */ # endif -#endif -#ifndef MBC_ABLK_OFFSET_BITS +# define ERTS_SACRR_UNIT_SHIFT ERTS_SUPER_ALIGN_BITS +# define ERTS_SACRR_UNIT_SZ (1 << ERTS_SACRR_UNIT_SHIFT) +# define ERTS_SACRR_UNIT_MASK ((~(UWord)0) << ERTS_SACRR_UNIT_SHIFT) +# define ERTS_SACRR_UNIT_FLOOR(X) ((X) & ERTS_SACRR_UNIT_MASK) +# define ERTS_SACRR_UNIT_CEILING(X) ERTS_SACRR_UNIT_FLOOR((X) + ~ERTS_SACRR_UNIT_MASK) +# define ERTS_SA_MB_CARRIERS 1 +#else +# define ERTS_SA_MB_CARRIERS 0 # define MBC_ABLK_OFFSET_BITS 0 /* no carrier offset in block header */ #endif +#if ERTS_HAVE_MSEG_SUPER_ALIGNED && !ERTS_HAVE_ERTS_SYS_ALIGNED_ALLOC +# define ERTS_SUPER_ALIGNED_MSEG_ONLY 1 +#else +# define ERTS_SUPER_ALIGNED_MSEG_ONLY 0 +#endif #if MBC_ABLK_OFFSET_BITS # define MBC_ABLK_OFFSET_SHIFT (sizeof(UWord)*8 - MBC_ABLK_OFFSET_BITS) @@ -245,9 +254,9 @@ erts_aint32_t erts_alcu_fix_alloc_shrink(Allctr_t *, erts_aint32_t); # define MBC_ABLK_SZ_MASK (~FLG_MASK) #endif -#define MBC_ABLK_SZ(B) (ASSERT_EXPR(!is_sbc_blk(B)), (B)->bhdr & MBC_ABLK_SZ_MASK) -#define MBC_FBLK_SZ(B) (ASSERT_EXPR(!is_sbc_blk(B)), (B)->bhdr & MBC_FBLK_SZ_MASK) -#define SBC_BLK_SZ(B) (ASSERT_EXPR(is_sbc_blk(B)), (B)->bhdr & SBC_BLK_SZ_MASK) +#define MBC_ABLK_SZ(B) (ASSERT(!is_sbc_blk(B)), (B)->bhdr & MBC_ABLK_SZ_MASK) +#define MBC_FBLK_SZ(B) (ASSERT(!is_sbc_blk(B)), (B)->bhdr & MBC_FBLK_SZ_MASK) +#define SBC_BLK_SZ(B) (ASSERT(is_sbc_blk(B)), (B)->bhdr & SBC_BLK_SZ_MASK) #define CARRIER_SZ(C) \ ((C)->chdr & CARRIER_SZ_MASK) @@ -327,8 +336,8 @@ typedef struct { (B)->u.carrier) # define ABLK_TO_MBC(B) \ (ASSERT(IS_MBC_BLK(B) && !IS_FREE_BLK(B)), \ - (Carrier_t*)((MSEG_UNIT_FLOOR((UWord)(B)) - \ - (((B)->bhdr >> MBC_ABLK_OFFSET_SHIFT) << MSEG_UNIT_SHIFT)))) + (Carrier_t*)((ERTS_SACRR_UNIT_FLOOR((UWord)(B)) - \ + (((B)->bhdr >> MBC_ABLK_OFFSET_SHIFT) << ERTS_SACRR_UNIT_SHIFT)))) # define BLK_TO_MBC(B) (IS_FREE_BLK(B) ? FBLK_TO_MBC(B) : ABLK_TO_MBC(B)) #else # define FBLK_TO_MBC(B) ((B)->carrier) diff --git a/erts/emulator/beam/erl_ao_firstfit_alloc.c b/erts/emulator/beam/erl_ao_firstfit_alloc.c index 4e6c8b317e..396aa88e0b 100644 --- a/erts/emulator/beam/erl_ao_firstfit_alloc.c +++ b/erts/emulator/beam/erl_ao_firstfit_alloc.c @@ -85,9 +85,6 @@ #define SET_RED(N) (((AOFF_RBTree_t *) (N))->flags |= RED_FLG) #define SET_BLACK(N) (((AOFF_RBTree_t *) (N))->flags &= ~RED_FLG) -#undef ASSERT -#define ASSERT ASSERT_EXPR - #if 1 #define RBT_ASSERT ASSERT #else diff --git a/erts/emulator/beam/erl_bestfit_alloc.c b/erts/emulator/beam/erl_bestfit_alloc.c index 41f449bb28..59c14899a2 100644 --- a/erts/emulator/beam/erl_bestfit_alloc.c +++ b/erts/emulator/beam/erl_bestfit_alloc.c @@ -75,9 +75,6 @@ #define BF_BLK_SZ(B) MBC_FBLK_SZ(&(B)->hdr) -#undef ASSERT -#define ASSERT ASSERT_EXPR - #if 1 #define RBT_ASSERT ASSERT #else diff --git a/erts/emulator/beam/erl_bif_binary.c b/erts/emulator/beam/erl_bif_binary.c index 0db19a1ee6..ff775691b3 100644 --- a/erts/emulator/beam/erl_bif_binary.c +++ b/erts/emulator/beam/erl_bif_binary.c @@ -927,6 +927,9 @@ static int do_binary_match_compile(Eterm argument, Eterm *tag, Binary **binp) if (binary_bitsize(b) != 0) { goto badarg; } + if (binary_size(b) == 0) { + goto badarg; + } ++words; characters += binary_size(b); } diff --git a/erts/emulator/beam/erl_bif_info.c b/erts/emulator/beam/erl_bif_info.c index 673dfc658c..5fbcbbe250 100755 --- a/erts/emulator/beam/erl_bif_info.c +++ b/erts/emulator/beam/erl_bif_info.c @@ -2091,7 +2091,7 @@ BIF_RETTYPE system_info_1(BIF_ALIST_1) BIF_RET(res); } else if (BIF_ARG_1 == am_sequential_tracer) { val = erts_get_system_seq_tracer(); - ASSERT(is_internal_pid(val) || is_internal_port(val) || val==am_false) + ASSERT(is_internal_pid(val) || is_internal_port(val) || val==am_false); hp = HAlloc(BIF_P, 3); res = TUPLE2(hp, am_sequential_tracer, val); BIF_RET(res); @@ -2636,6 +2636,9 @@ BIF_RETTYPE system_info_1(BIF_ALIST_1) BIF_RET(res); } + else if (ERTS_IS_ATOM_STR("ets_limit",BIF_ARG_1)) { + BIF_RET(make_small(erts_db_get_max_tabs())); + } BIF_ERROR(BIF_P, BADARG); } @@ -3286,6 +3289,9 @@ BIF_RETTYPE erts_debug_get_internal_state_1(BIF_ALIST_1) erts_smp_thr_progress_unblock(); BIF_RET(res); } + else if (ERTS_IS_ATOM_STR("mmap", BIF_ARG_1)) { + BIF_RET(erts_mmap_debug_info(BIF_P)); + } } else if (is_tuple(BIF_ARG_1)) { Eterm* tp = tuple_val(BIF_ARG_1); diff --git a/erts/emulator/beam/erl_binary.h b/erts/emulator/beam/erl_binary.h index 506c4813fa..f7dc20f5e6 100644 --- a/erts/emulator/beam/erl_binary.h +++ b/erts/emulator/beam/erl_binary.h @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2000-2011. All Rights Reserved. + * Copyright Ericsson AB 2000-2013. All Rights Reserved. * * The contents of this file are subject to the Erlang Public License, * Version 1.1, (the "License"); you may not use this file except in @@ -153,7 +153,7 @@ do { \ #define binary_bytes(Bin) \ (*binary_val(Bin) == HEADER_PROC_BIN ? \ ((ProcBin *) binary_val(Bin))->bytes : \ - (ASSERT_EXPR(thing_subtag(*binary_val(Bin)) == HEAP_BINARY_SUBTAG), \ + (ASSERT(thing_subtag(*binary_val(Bin)) == HEAP_BINARY_SUBTAG), \ (byte *)(&(((ErlHeapBin *) binary_val(Bin))->data)))) void erts_init_binary(void); @@ -183,7 +183,7 @@ BIF_RETTYPE erts_binary_part(Process *p, Eterm binary, Eterm epos, Eterm elen); #endif #define ERTS_CHK_BIN_ALIGNMENT(B) \ - do { ASSERT(!(B) || (((UWord) &((Binary *)(B))->orig_bytes[0]) & ERTS_BIN_ALIGNMENT_MASK) == ((UWord) 0)) } while(0) + do { ASSERT(!(B) || (((UWord) &((Binary *)(B))->orig_bytes[0]) & ERTS_BIN_ALIGNMENT_MASK) == ((UWord) 0)); } while(0) ERTS_GLB_INLINE byte* erts_get_aligned_binary_bytes(Eterm bin, byte** base_ptr); ERTS_GLB_INLINE void erts_free_aligned_binary_bytes(byte* buf); diff --git a/erts/emulator/beam/erl_db.c b/erts/emulator/beam/erl_db.c index 98c2988323..41e64fcd4f 100644 --- a/erts/emulator/beam/erl_db.c +++ b/erts/emulator/beam/erl_db.c @@ -2236,7 +2236,7 @@ static BIF_RETTYPE ets_select_trap_1(BIF_ALIST_1) CHECK_TABLES(); tptr = tuple_val(a1); - ASSERT(arityval(*tptr) >= 1) + ASSERT(arityval(*tptr) >= 1); if ((tb = db_get_table(p, tptr[1], DB_READ, kind)) == NULL) { BIF_ERROR(p, BADARG); @@ -2403,7 +2403,7 @@ static BIF_RETTYPE ets_select_count_1(BIF_ALIST_1) CHECK_TABLES(); tptr = tuple_val(a1); - ASSERT(arityval(*tptr) >= 1) + ASSERT(arityval(*tptr) >= 1); if ((tb = db_get_table(p, tptr[1], DB_READ, kind)) == NULL) { BIF_ERROR(p, BADARG); } @@ -3811,6 +3811,13 @@ erts_db_foreach_offheap(DbTable *tb, tb->common.meth->db_foreach_offheap(tb, func, arg); } +/* retrieve max number of ets tables */ +Uint +erts_db_get_max_tabs() +{ + return db_max_tabs; +} + /* * For testing of meta tables only. * diff --git a/erts/emulator/beam/erl_db.h b/erts/emulator/beam/erl_db.h index 6b62e10eb7..5b4681fc90 100644 --- a/erts/emulator/beam/erl_db.h +++ b/erts/emulator/beam/erl_db.h @@ -79,6 +79,8 @@ extern erts_smp_atomic_t erts_ets_misc_mem_size; Eterm erts_ets_colliding_names(Process*, Eterm name, Uint cnt); +Uint erts_db_get_max_tabs(void); + #endif #if defined(ERTS_WANT_DB_INTERNAL__) && !defined(ERTS_HAVE_DB_INTERNAL__) diff --git a/erts/emulator/beam/erl_db_util.h b/erts/emulator/beam/erl_db_util.h index 90b79e6044..328b19dfc9 100644 --- a/erts/emulator/beam/erl_db_util.h +++ b/erts/emulator/beam/erl_db_util.h @@ -457,7 +457,7 @@ int erts_db_is_compiled_ms(Eterm term); && ERTS_MAGIC_BIN_DESTRUCTOR((BP)) == erts_db_match_prog_destructor) #define Binary2MatchProg(BP) \ - (ASSERT_EXPR(IsMatchProgBinary((BP))), \ + (ASSERT(IsMatchProgBinary((BP))), \ ((MatchProg *) ERTS_MAGIC_BIN_DATA((BP)))) /* ** Debugging diff --git a/erts/emulator/beam/erl_driver.h b/erts/emulator/beam/erl_driver.h index d2a11cce05..5cffae92be 100644 --- a/erts/emulator/beam/erl_driver.h +++ b/erts/emulator/beam/erl_driver.h @@ -552,6 +552,11 @@ EXTERN int erl_drv_equal_tids(ErlDrvTid tid1, ErlDrvTid tid2); EXTERN void erl_drv_thread_exit(void *resp); EXTERN int erl_drv_thread_join(ErlDrvTid, void **respp); +EXTERN char* erl_drv_mutex_name(ErlDrvMutex *mtx); +EXTERN char* erl_drv_cond_name(ErlDrvCond *cnd); +EXTERN char* erl_drv_rwlock_name(ErlDrvRWLock *rwlck); +EXTERN char* erl_drv_thread_name(ErlDrvTid tid); + /* * Misc. */ @@ -689,6 +694,3 @@ EXTERN int erl_drv_getenv(char *key, char *value, size_t *value_size); /* also in global.h, but driver's can't include global.h */ void dtrace_drvport_str(ErlDrvPort port, char *port_buf); - - - diff --git a/erts/emulator/beam/erl_drv_thread.c b/erts/emulator/beam/erl_drv_thread.c index a49a155701..4f1bba8657 100644 --- a/erts/emulator/beam/erl_drv_thread.c +++ b/erts/emulator/beam/erl_drv_thread.c @@ -188,6 +188,17 @@ erl_drv_mutex_destroy(ErlDrvMutex *dmtx) #endif } + +char * +erl_drv_mutex_name(ErlDrvMutex *dmtx) +{ +#ifdef USE_THREADS + return dmtx ? dmtx->name : NULL; +#else + return NULL; +#endif +} + int erl_drv_mutex_trylock(ErlDrvMutex *dmtx) { @@ -258,6 +269,15 @@ erl_drv_cond_destroy(ErlDrvCond *dcnd) #endif } +char * +erl_drv_cond_name(ErlDrvCond *dcnd) +{ +#ifdef USE_THREADS + return dcnd ? dcnd->name : NULL; +#else + return NULL; +#endif +} void erl_drv_cond_signal(ErlDrvCond *dcnd) @@ -331,6 +351,16 @@ erl_drv_rwlock_destroy(ErlDrvRWLock *drwlck) #endif } +char * +erl_drv_rwlock_name(ErlDrvRWLock *drwlck) +{ +#ifdef USE_THREADS + return drwlck ? drwlck->name : NULL; +#else + return NULL; +#endif +} + int erl_drv_rwlock_tryrlock(ErlDrvRWLock *drwlck) { @@ -617,6 +647,18 @@ erl_drv_thread_create(char *name, #endif } +char * +erl_drv_thread_name(ErlDrvTid tid) +{ +#ifdef USE_THREADS + struct ErlDrvTid_ *dtid = (struct ErlDrvTid_ *) tid; + return dtid ? dtid->name : NULL; +#else + return NULL; +#endif +} + + ErlDrvTid erl_drv_thread_self(void) { diff --git a/erts/emulator/beam/erl_init.c b/erts/emulator/beam/erl_init.c index 8d137df7ae..8c4fffa75b 100644 --- a/erts/emulator/beam/erl_init.c +++ b/erts/emulator/beam/erl_init.c @@ -549,9 +549,12 @@ void erts_usage(void) ERTS_SCHED_THREAD_MAX_STACK_SIZE); erts_fprintf(stderr, "-spp Bool set port parallelism scheduling hint\n"); erts_fprintf(stderr, "-S n1:n2 set number of schedulers (n1), and number of\n"); - erts_fprintf(stderr, " schedulers online (n2), valid range for both\n"); - erts_fprintf(stderr, " numbers are [1-%d]\n", + erts_fprintf(stderr, " schedulers online (n2), maximum for both\n"); + erts_fprintf(stderr, " numbers is %d\n", ERTS_MAX_NO_OF_SCHEDULERS); + erts_fprintf(stderr, "-SP p1:p2 specify schedulers (p1) and schedulers online (p2)\n"); + erts_fprintf(stderr, " as percentages of logical processors configured and logical\n"); + erts_fprintf(stderr, " processors available, respectively\n"); erts_fprintf(stderr, "-t size set the maximum number of atoms the " "emulator can handle\n"); erts_fprintf(stderr, " valid range is [%d-%d]\n", @@ -631,6 +634,8 @@ early_init(int *argc, char **argv) /* int ncpuavail; int schdlrs; int schdlrs_onln; + int schdlrs_percentage = 100; + int schdlrs_onln_percentage = 100; int max_main_threads; int max_reader_groups; int reader_groups; @@ -758,63 +763,132 @@ early_init(int *argc, char **argv) /* } break; } - case 'S' : { - int tot, onln; - char *arg = get_arg(argv[i]+2, argv[i+1], &i); - switch (sscanf(arg, "%d:%d", &tot, &onln)) { - case 0: - switch (sscanf(arg, ":%d", &onln)) { + case 'S' : + if (argv[i][2] == 'P') { + int ptot, ponln; + char *arg = get_arg(argv[i]+3, argv[i+1], &i); + switch (sscanf(arg, "%d:%d", &ptot, &ponln)) { + case 0: + switch (sscanf(arg, ":%d", &ponln)) { + case 1: + if (ponln < 0) + goto bad_SP; + ptot = 100; + goto chk_SP; + default: + goto bad_SP; + } case 1: - tot = no_schedulers; - goto chk_S; + if (ptot < 0) + goto bad_SP; + ponln = ptot < 100 ? ptot : 100; + goto chk_SP; + case 2: + if (ptot < 0 || ponln < 0) + goto bad_SP; + chk_SP: + schdlrs_percentage = ptot; + schdlrs_onln_percentage = ponln; + break; default: - goto bad_S; - } - case 1: - onln = tot < schdlrs_onln ? tot : schdlrs_onln; - case 2: - chk_S: - if (tot > 0) - schdlrs = tot; - else - schdlrs = no_schedulers + tot; - if (onln > 0) - schdlrs_onln = onln; - else - schdlrs_onln = no_schedulers_online + onln; - if (schdlrs < 1 || ERTS_MAX_NO_OF_SCHEDULERS < schdlrs) { - erts_fprintf(stderr, - "bad amount of schedulers %d\n", - tot); - erts_usage(); - } - if (schdlrs_onln < 1 || schdlrs < schdlrs_onln) { + bad_SP: + erts_fprintf(stderr, + "bad schedulers percentage specifier %s\n", + arg); + erts_usage(); + break; + } + + VERBOSE(DEBUG_SYSTEM, + ("using %d:%d scheduler percentages\n", + schdlrs_percentage, schdlrs_onln_percentage)); + } else { + int tot, onln; + char *arg = get_arg(argv[i]+2, argv[i+1], &i); + switch (sscanf(arg, "%d:%d", &tot, &onln)) { + case 0: + switch (sscanf(arg, ":%d", &onln)) { + case 1: + tot = no_schedulers; + goto chk_S; + default: + goto bad_S; + } + case 1: + onln = tot < schdlrs_onln ? tot : schdlrs_onln; + case 2: + chk_S: + if (tot > 0) + schdlrs = tot; + else + schdlrs = no_schedulers + tot; + if (onln > 0) + schdlrs_onln = onln; + else + schdlrs_onln = no_schedulers_online + onln; + if (schdlrs < 1 || ERTS_MAX_NO_OF_SCHEDULERS < schdlrs) { + erts_fprintf(stderr, + "bad amount of schedulers %d\n", + tot); + erts_usage(); + } + if (schdlrs_onln < 1 || schdlrs < schdlrs_onln) { + erts_fprintf(stderr, + "bad amount of schedulers online %d " + "(total amount of schedulers %d)\n", + schdlrs_onln, schdlrs); + erts_usage(); + } + break; + default: + bad_S: erts_fprintf(stderr, - "bad amount of schedulers online %d " - "(total amount of schedulers %d)\n", - schdlrs_onln, schdlrs); + "bad amount of schedulers %s\n", + arg); erts_usage(); + break; } - break; - default: - bad_S: - erts_fprintf(stderr, - "bad amount of schedulers %s\n", - arg); - erts_usage(); - break; - } - VERBOSE(DEBUG_SYSTEM, - ("using %d:%d scheduler(s)\n", tot, onln)); - break; - } + VERBOSE(DEBUG_SYSTEM, + ("using %d:%d scheduler(s)\n", tot, onln)); + } + break; default: break; } } i++; } + +#ifdef ERTS_SMP + /* apply any scheduler percentages */ + if (schdlrs_percentage != 100 || schdlrs_onln_percentage != 100) { + schdlrs = schdlrs * schdlrs_percentage / 100; + schdlrs_onln = schdlrs_onln * schdlrs_onln_percentage / 100; + if (schdlrs < 1) + schdlrs = 1; + if (ERTS_MAX_NO_OF_SCHEDULERS < schdlrs) { + erts_fprintf(stderr, + "bad schedulers percentage %d " + "(total amount of schedulers %d)\n", + schdlrs_percentage, schdlrs); + erts_usage(); + } + if (schdlrs_onln < 1) + schdlrs_onln = 1; + if (schdlrs < schdlrs_onln) { + erts_fprintf(stderr, + "bad schedulers online percentage %d " + "(total amount of schedulers %d, online %d)\n", + schdlrs_onln_percentage, schdlrs, schdlrs_onln); + erts_usage(); + } + } +#else + /* Silence gcc warnings */ + (void)schdlrs_percentage; + (void)schdlrs_onln_percentage; +#endif } #ifndef USE_THREADS @@ -1312,7 +1386,10 @@ erl_start(int argc, char **argv) break; case 'S' : /* Was handled in early_init() just read past it */ - (void) get_arg(argv[i]+2, argv[i+1], &i); + if (argv[i][2] == 'P') + (void) get_arg(argv[i]+3, argv[i+1], &i); + else + (void) get_arg(argv[i]+2, argv[i+1], &i); break; case 's' : { diff --git a/erts/emulator/beam/erl_lock_check.c b/erts/emulator/beam/erl_lock_check.c index 2114d0c001..0dd83fa6ed 100644 --- a/erts/emulator/beam/erl_lock_check.c +++ b/erts/emulator/beam/erl_lock_check.c @@ -132,6 +132,7 @@ static erts_lc_lock_order_t erts_lock_order[] = { #endif /* __WIN32__ */ { "alcu_init_atoms", NULL }, { "mseg_init_atoms", NULL }, + { "mmap_init_atoms", NULL }, { "drv_tsd", NULL }, { "async_enq_mtx", NULL }, #ifdef ERTS_SMP @@ -185,7 +186,9 @@ static erts_lc_lock_order_t erts_lock_order[] = { { "sys_gethrtime", NULL }, #endif #endif - { "erts_alloc_hard_debug", NULL } + { "erts_alloc_hard_debug", NULL }, + { "hard_dbg_mseg", NULL }, + { "erts_mmap", NULL } }; #define ERTS_LOCK_ORDER_SIZE \ diff --git a/erts/emulator/beam/erl_node_container_utils.h b/erts/emulator/beam/erl_node_container_utils.h index 0f93a3a9f0..17f6b32bb1 100644 --- a/erts/emulator/beam/erl_node_container_utils.h +++ b/erts/emulator/beam/erl_node_container_utils.h @@ -106,7 +106,7 @@ #define dist_entry_channel_no(x) \ ((x) == erts_this_dist_entry \ ? ((Uint) 0) \ - : (ASSERT_EXPR(is_atom((x)->sysname)), \ + : (ASSERT(is_atom((x)->sysname)), \ (Uint) atom_val((x)->sysname))) #define internal_channel_no(x) ((Uint) ERST_INTERNAL_CHANNEL_NO) #define external_channel_no(x) \ @@ -122,10 +122,10 @@ extern ErtsPTab erts_proc; (D), \ _TAG_IMMED1_PID) -#define internal_pid_index(PID) (ASSERT_EXPR(is_internal_pid((PID))), \ +#define internal_pid_index(PID) (ASSERT(is_internal_pid((PID))), \ erts_ptab_id2pix(&erts_proc, (PID))) -#define internal_pid_data(PID) (ASSERT_EXPR(is_internal_pid((PID))), \ +#define internal_pid_data(PID) (ASSERT(is_internal_pid((PID))), \ erts_ptab_id2data(&erts_proc, (PID))) #define internal_pid_number(x) _GET_PID_NUM(internal_pid_data((x))) @@ -193,10 +193,10 @@ extern ErtsPTab erts_port; (D), \ _TAG_IMMED1_PORT) -#define internal_port_index(PRT) (ASSERT_EXPR(is_internal_port((PRT))), \ +#define internal_port_index(PRT) (ASSERT(is_internal_port((PRT))), \ erts_ptab_id2pix(&erts_port, (PRT))) -#define internal_port_data(PRT) (ASSERT_EXPR(is_internal_port((PRT))), \ +#define internal_port_data(PRT) (ASSERT(is_internal_port((PRT))), \ erts_ptab_id2data(&erts_port, (PRT))) #define internal_port_number(x) _GET_PORT_NUM(internal_port_data((x))) diff --git a/erts/emulator/beam/erl_port_task.c b/erts/emulator/beam/erl_port_task.c index 7d53ce7152..547a42beb2 100644 --- a/erts/emulator/beam/erl_port_task.c +++ b/erts/emulator/beam/erl_port_task.c @@ -1838,6 +1838,16 @@ release_port(void *vport) { erts_port_dec_refc((Port *) vport); } + +static void +schedule_release_port(void *vport) { + Port *pp = (Port*)vport; + /* This is only used when a port release was ordered from a non-scheduler */ + erts_schedule_thr_prgr_later_op(release_port, + (void *) pp, + &pp->common.u.release); +} + #endif static void @@ -2033,10 +2043,15 @@ begin_port_cleanup(Port *pp, ErtsPortTask **execqp, int *processing_busy_q_p) * Schedule cleanup of port structure... */ #ifdef ERTS_SMP - /* Has to be more or less immediate to release any driver */ - erts_schedule_thr_prgr_later_op(release_port, - (void *) pp, - &pp->common.u.release); + /* We might not be a scheduler, eg. traceing to port we are sys_msg_dispatcher */ + if (!erts_get_scheduler_data()) { + erts_schedule_misc_aux_work(1, schedule_release_port, (void*)pp); + } else { + /* Has to be more or less immediate to release any driver */ + erts_schedule_thr_prgr_later_op(release_port, + (void *) pp, + &pp->common.u.release); + } #else pp->cleanup = 1; #endif diff --git a/erts/emulator/beam/erl_process.c b/erts/emulator/beam/erl_process.c index 2439a46ab6..79f382674a 100644 --- a/erts/emulator/beam/erl_process.c +++ b/erts/emulator/beam/erl_process.c @@ -294,7 +294,7 @@ ERTS_SCHED_PREF_QUICK_ALLOC_IMPL(proclist, ERTS_ALC_T_PROC_LIST) #define ERTS_SCHED_SLEEP_INFO_IX(IX) \ - (ASSERT_EXPR(-1 <= ((int) (IX)) \ + (ASSERT(-1 <= ((int) (IX)) \ && ((int) (IX)) < ((int) erts_no_schedulers)), \ &aligned_sched_sleep_info[(IX)].ssi) @@ -7237,7 +7237,7 @@ erts_sched_stat_modify(int what) break; case ERTS_SCHED_STAT_MODIFY_DISABLE: erts_smp_thr_progress_block(); - erts_sched_stat.enabled = 1; + erts_sched_stat.enabled = 0; erts_smp_thr_progress_unblock(); break; case ERTS_SCHED_STAT_MODIFY_CLEAR: diff --git a/erts/emulator/beam/erl_process.h b/erts/emulator/beam/erl_process.h index 8e5467f196..8d136f6e8b 100644 --- a/erts/emulator/beam/erl_process.h +++ b/erts/emulator/beam/erl_process.h @@ -1135,10 +1135,10 @@ extern struct erts_system_profile_flags_t erts_system_profile_flags; } while (0) #define ERTS_RUNQ_IX(IX) \ - (ASSERT_EXPR(0 <= (IX) && (IX) < erts_no_run_queues), \ + (ASSERT(0 <= (IX) && (IX) < erts_no_run_queues), \ &erts_aligned_run_queues[(IX)].runq) #define ERTS_SCHEDULER_IX(IX) \ - (ASSERT_EXPR(0 <= (IX) && (IX) < erts_no_schedulers), \ + (ASSERT(0 <= (IX) && (IX) < erts_no_schedulers), \ &erts_aligned_scheduler_data[(IX)].esd) void erts_pre_init_process(void); diff --git a/erts/emulator/beam/erl_trace.c b/erts/emulator/beam/erl_trace.c index fa015ee4b9..ff7fdfcfca 100644 --- a/erts/emulator/beam/erl_trace.c +++ b/erts/emulator/beam/erl_trace.c @@ -2184,7 +2184,7 @@ trace_gc(Process *p, Eterm what) AM_bin_old_vheap_block_size }; - Uint values[] = { + UWord values[] = { OLD_HEAP(p) ? OLD_HEND(p) - OLD_HEAP(p) : 0, HEAP_SIZE(p), MBUF_SIZE(p), @@ -2198,7 +2198,7 @@ trace_gc(Process *p, Eterm what) BIN_OLD_VHEAP_SZ(p) }; #define LOCAL_HEAP_SIZE \ - (sizeof(values)/sizeof(Eterm)) * \ + (sizeof(values)/sizeof(*values)) * \ (2/*cons*/ + 3/*2-tuple*/ + BIG_UINT_HEAP_SIZE) + \ 5/*4-tuple */ + TS_HEAP_WORDS DeclareTmpHeap(local_heap,LOCAL_HEAP_SIZE,p); @@ -2206,7 +2206,7 @@ trace_gc(Process *p, Eterm what) Eterm* limit; #endif - ASSERT(sizeof(values)/sizeof(Uint) == sizeof(tags)/sizeof(Eterm)); + ASSERT(sizeof(values)/sizeof(*values) == sizeof(tags)/sizeof(Eterm)); UseTmpHeap(LOCAL_HEAP_SIZE,p); @@ -2214,9 +2214,9 @@ trace_gc(Process *p, Eterm what) hp = local_heap; #ifdef DEBUG size = 0; - (void) erts_bld_atom_uint_2tup_list(NULL, + (void) erts_bld_atom_uword_2tup_list(NULL, &size, - sizeof(values)/sizeof(Uint), + sizeof(values)/sizeof(*values), tags, values); size += 5/*4-tuple*/ + TS_SIZE(p); @@ -2229,9 +2229,9 @@ trace_gc(Process *p, Eterm what) ERTS_TRACE_FLAGS(p)); size = 0; - (void) erts_bld_atom_uint_2tup_list(NULL, + (void) erts_bld_atom_uword_2tup_list(NULL, &size, - sizeof(values)/sizeof(Uint), + sizeof(values)/sizeof(*values), tags, values); size += 5/*4-tuple*/ + TS_SIZE(p); @@ -2244,9 +2244,9 @@ trace_gc(Process *p, Eterm what) ASSERT(size <= LOCAL_HEAP_SIZE); #endif - msg = erts_bld_atom_uint_2tup_list(&hp, + msg = erts_bld_atom_uword_2tup_list(&hp, NULL, - sizeof(values)/sizeof(Uint), + sizeof(values)/sizeof(*values), tags, values); @@ -2415,7 +2415,7 @@ monitor_long_gc(Process *p, Uint time) { am_old_heap_size, am_heap_size }; - Eterm values[] = { + UWord values[] = { time, OLD_HEAP(p) ? OLD_HEND(p) - OLD_HEAP(p) : 0, HEAP_SIZE(p), @@ -2436,9 +2436,9 @@ monitor_long_gc(Process *p, Uint time) { #endif hsz = 0; - (void) erts_bld_atom_uint_2tup_list(NULL, + (void) erts_bld_atom_uword_2tup_list(NULL, &hsz, - sizeof(values)/sizeof(Uint), + sizeof(values)/sizeof(*values), tags, values); hsz += 5 /* 4-tuple */; @@ -2449,9 +2449,9 @@ monitor_long_gc(Process *p, Uint time) { hp_end = hp + hsz; #endif - list = erts_bld_atom_uint_2tup_list(&hp, + list = erts_bld_atom_uword_2tup_list(&hp, NULL, - sizeof(values)/sizeof(Uint), + sizeof(values)/sizeof(*values), tags, values); msg = TUPLE4(hp, am_monitor, p->common.id, am_long_gc, list); @@ -2489,7 +2489,7 @@ monitor_large_heap(Process *p) { am_old_heap_size, am_heap_size }; - Uint values[] = { + UWord values[] = { OLD_HEAP(p) ? OLD_HEND(p) - OLD_HEAP(p) : 0, HEAP_SIZE(p), MBUF_SIZE(p), @@ -2511,9 +2511,9 @@ monitor_large_heap(Process *p) { #endif hsz = 0; - (void) erts_bld_atom_uint_2tup_list(NULL, + (void) erts_bld_atom_uword_2tup_list(NULL, &hsz, - sizeof(values)/sizeof(Uint), + sizeof(values)/sizeof(*values), tags, values); hsz += 5 /* 4-tuple */; @@ -2524,9 +2524,9 @@ monitor_large_heap(Process *p) { hp_end = hp + hsz; #endif - list = erts_bld_atom_uint_2tup_list(&hp, + list = erts_bld_atom_uword_2tup_list(&hp, NULL, - sizeof(values)/sizeof(Uint), + sizeof(values)/sizeof(*values), tags, values); msg = TUPLE4(hp, am_monitor, p->common.id, am_large_heap, list); diff --git a/erts/emulator/beam/erl_unicode.c b/erts/emulator/beam/erl_unicode.c index ec8ea5f044..7e3c6681d9 100644 --- a/erts/emulator/beam/erl_unicode.c +++ b/erts/emulator/beam/erl_unicode.c @@ -1476,6 +1476,9 @@ static Eterm do_utf8_to_list_normalize(Process *p, Uint num, byte *bytes, Uint s Uint16 savepoints[4]; int numpoints = 0; + if (num == 0) + return NIL; + ASSERT(num > 0); hp = HAlloc(p,num * 2); /* May be to much */ diff --git a/erts/emulator/beam/erl_utils.h b/erts/emulator/beam/erl_utils.h index 80d29d554a..292d135946 100644 --- a/erts/emulator/beam/erl_utils.h +++ b/erts/emulator/beam/erl_utils.h @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2012. All Rights Reserved. + * Copyright Ericsson AB 2012-2013. All Rights Reserved. * * The contents of this file are subject to the Erlang Public License, * Version 1.1, (the "License"); you may not use this file except in @@ -168,6 +168,10 @@ Eterm erts_bld_uint64(Uint **hpp, Uint *szp, Uint64 ui64); Eterm erts_bld_sint64(Uint **hpp, Uint *szp, Sint64 si64); Eterm erts_bld_cons(Uint **hpp, Uint *szp, Eterm car, Eterm cdr); Eterm erts_bld_tuple(Uint **hpp, Uint *szp, Uint arity, ...); +#define erts_bld_tuple2(H,S,E1,E2) erts_bld_tuple(H,S,2,E1,E2) +#define erts_bld_tuple3(H,S,E1,E2,E3) erts_bld_tuple(H,S,3,E1,E2,E3) +#define erts_bld_tuple4(H,S,E1,E2,E3,E4) erts_bld_tuple(H,S,4,E1,E2,E3,E4) +#define erts_bld_tuple5(H,S,E1,E2,E3,E4,E5) erts_bld_tuple(H,S,5,E1,E2,E3,E4,E5) Eterm erts_bld_tuplev(Uint **hpp, Uint *szp, Uint arity, Eterm terms[]); Eterm erts_bld_string_n(Uint **hpp, Uint *szp, const char *str, Sint len); #define erts_bld_string(hpp,szp,str) erts_bld_string_n(hpp,szp,str,strlen(str)) @@ -175,8 +179,8 @@ Eterm erts_bld_list(Uint **hpp, Uint *szp, Sint length, Eterm terms[]); Eterm erts_bld_2tup_list(Uint **hpp, Uint *szp, Sint length, Eterm terms1[], Uint terms2[]); Eterm -erts_bld_atom_uint_2tup_list(Uint **hpp, Uint *szp, - Sint length, Eterm atoms[], Uint uints[]); +erts_bld_atom_uword_2tup_list(Uint **hpp, Uint *szp, + Sint length, Eterm atoms[], UWord uints[]); Eterm erts_bld_atom_2uint_3tup_list(Uint **hpp, Uint *szp, Sint length, Eterm atoms[], Uint uints1[], Uint uints2[]); diff --git a/erts/emulator/beam/erl_vm.h b/erts/emulator/beam/erl_vm.h index c962955de9..337422eead 100644 --- a/erts/emulator/beam/erl_vm.h +++ b/erts/emulator/beam/erl_vm.h @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1996-2012. All Rights Reserved. + * Copyright Ericsson AB 1996-2013. All Rights Reserved. * * The contents of this file are subject to the Erlang Public License, * Version 1.1, (the "License"); you may not use this file except in @@ -80,7 +80,7 @@ # ifdef CHECK_FOR_HOLES # define INIT_HEAP_MEM(p,sz) erts_set_hole_marker(HEAP_TOP(p), (sz)) # else -# define INIT_HEAP_MEM(p,sz) memset(HEAP_TOP(p),DEBUG_BAD_BYTE,(sz)*sizeof(Eterm*)) +# define INIT_HEAP_MEM(p,sz) memset(HEAP_TOP(p),0x01,(sz)*sizeof(Eterm*)) # endif #else # define INIT_HEAP_MEM(p,sz) ((void)0) @@ -98,7 +98,7 @@ * failing that, in a heap fragment. */ #define HAllocX(p, sz, xtra) \ - (ASSERT_EXPR((sz) >= 0), \ + (ASSERT((sz) >= 0), \ ErtsHAllocLockCheck(p), \ (IS_FORCE_HEAP_FRAGS || (((HEAP_LIMIT(p) - HEAP_TOP(p)) < (sz))) \ ? erts_heap_alloc((p),(sz),(xtra)) \ @@ -135,14 +135,14 @@ */ #ifdef CHECK_FOR_HOLES # define HeapOnlyAlloc(p, sz) \ - (ASSERT_EXPR((sz) >= 0), \ - (ASSERT_EXPR(((HEAP_LIMIT(p) - HEAP_TOP(p)) >= (sz))), \ + (ASSERT((sz) >= 0), \ + (ASSERT(((HEAP_LIMIT(p) - HEAP_TOP(p)) >= (sz))), \ (erts_set_hole_marker(HEAP_TOP(p), (sz)), \ (HEAP_TOP(p) = HEAP_TOP(p) + (sz), HEAP_TOP(p) - (sz))))) #else # define HeapOnlyAlloc(p, sz) \ - (ASSERT_EXPR((sz) >= 0), \ - (ASSERT_EXPR(((HEAP_LIMIT(p) - HEAP_TOP(p)) >= (sz))), \ + (ASSERT((sz) >= 0), \ + (ASSERT(((HEAP_LIMIT(p) - HEAP_TOP(p)) >= (sz))), \ (HEAP_TOP(p) = HEAP_TOP(p) + (sz), HEAP_TOP(p) - (sz)))) #endif diff --git a/erts/emulator/beam/external.h b/erts/emulator/beam/external.h index e37d47919e..ff29e84972 100644 --- a/erts/emulator/beam/external.h +++ b/erts/emulator/beam/external.h @@ -138,8 +138,8 @@ typedef struct { #define ERTS_DIST_EXT_SIZE(EDEP) \ (sizeof(ErtsDistExternal) \ - (((EDEP)->flags & ERTS_DIST_EXT_ATOM_TRANS_TAB) \ - ? (ASSERT_EXPR(0 <= (EDEP)->attab.size \ - && (EDEP)->attab.size <= ERTS_ATOM_CACHE_SIZE), \ + ? (ASSERT(0 <= (EDEP)->attab.size \ + && (EDEP)->attab.size <= ERTS_ATOM_CACHE_SIZE), \ sizeof(Eterm)*(ERTS_ATOM_CACHE_SIZE - (EDEP)->attab.size)) \ : sizeof(ErtsAtomTranslationTable))) diff --git a/erts/emulator/beam/global.h b/erts/emulator/beam/global.h index c040b259a0..c1fda3f96c 100755 --- a/erts/emulator/beam/global.h +++ b/erts/emulator/beam/global.h @@ -867,13 +867,13 @@ Eterm store_external_or_ref_in_proc_(Process *, Eterm); Eterm store_external_or_ref_(Uint **, ErlOffHeap*, Eterm); #define NC_HEAP_SIZE(NC) \ - (ASSERT_EXPR(is_node_container((NC))), \ + (ASSERT(is_node_container((NC))), \ IS_CONST((NC)) ? 0 : (thing_arityval(*boxed_val((NC))) + 1)) #define STORE_NC(Hpp, ETpp, NC) \ - (ASSERT_EXPR(is_node_container((NC))), \ + (ASSERT(is_node_container((NC))), \ IS_CONST((NC)) ? (NC) : store_external_or_ref_((Hpp), (ETpp), (NC))) #define STORE_NC_IN_PROC(Pp, NC) \ - (ASSERT_EXPR(is_node_container((NC))), \ + (ASSERT(is_node_container((NC))), \ IS_CONST((NC)) ? (NC) : store_external_or_ref_in_proc_((Pp), (NC))) /* duplicates from big.h */ diff --git a/erts/emulator/beam/io.c b/erts/emulator/beam/io.c index fb39c18d9d..b2803747eb 100644 --- a/erts/emulator/beam/io.c +++ b/erts/emulator/beam/io.c @@ -1330,7 +1330,7 @@ force_imm_drv_call(ErtsTryImmDrvCallState *sp) erts_aint32_t invalid_state; Port *prt = sp->port; - ASSERT(ERTS_IS_CRASH_DUMPING) + ASSERT(ERTS_IS_CRASH_DUMPING); ASSERT(is_atom(sp->port_op)); invalid_state = sp->state; diff --git a/erts/emulator/beam/sys.h b/erts/emulator/beam/sys.h index 05bff430e3..9561c0be96 100644 --- a/erts/emulator/beam/sys.h +++ b/erts/emulator/beam/sys.h @@ -149,19 +149,14 @@ typedef ERTS_SYS_FD_TYPE ErtsSysFdType; # define ERTS_EXIT_AFTER_DUMP exit #endif +#define ERTS_ASSERT(e) \ + ((void) ((e) ? 1 : (erl_assert_error(#e, __func__, __FILE__, __LINE__), 0))) +void erl_assert_error(const char* expr, const char *func, const char* file, int line); + #ifdef DEBUG -# define ASSERT(e) \ - if (e) { \ - ; \ - } else { \ - erl_assert_error(#e, __FILE__, __LINE__); \ - } -# define ASSERT_EXPR(e) \ - ((void) ((e) ? 1 : (erl_assert_error(#e, __FILE__, __LINE__), 0))) -void erl_assert_error(char* expr, char* file, int line); +# define ASSERT(e) ERTS_ASSERT(e) #else -# define ASSERT(e) -# define ASSERT_EXPR(e) ((void) 1) +# define ASSERT(e) ((void) 1) #endif /* @@ -282,16 +277,19 @@ typedef unsigned long UWord; typedef long SWord; #define SWORD_CONSTANT(Const) Const##L #define UWORD_CONSTANT(Const) Const##UL +#define ERTS_SWORD_MAX LONG_MAX #elif SIZEOF_VOID_P == SIZEOF_INT typedef unsigned int UWord; typedef int SWord; #define SWORD_CONSTANT(Const) Const #define UWORD_CONSTANT(Const) Const##U +#define ERTS_SWORD_MAX INT_MAX #elif SIZEOF_VOID_P == SIZEOF_LONG_LONG typedef unsigned long long UWord; typedef long long SWord; #define SWORD_CONSTANT(Const) Const##LL #define UWORD_CONSTANT(Const) Const##ULL +#define ERTS_SWORD_MAX LLONG_MAX #else #error Found no appropriate type to use for 'Eterm', 'Uint' and 'Sint' #endif @@ -304,6 +302,7 @@ typedef unsigned long Uint; typedef long Sint; #define SWORD_CONSTANT(Const) Const##L #define UWORD_CONSTANT(Const) Const##UL +#define ERTS_SWORD_MAX LONG_MAX #define ERTS_SIZEOF_ETERM SIZEOF_LONG #define ErtsStrToSint strtol #elif SIZEOF_VOID_P == SIZEOF_INT @@ -312,6 +311,7 @@ typedef unsigned int Uint; typedef int Sint; #define SWORD_CONSTANT(Const) Const #define UWORD_CONSTANT(Const) Const##U +#define ERTS_SWORD_MAX INT_MAX #define ERTS_SIZEOF_ETERM SIZEOF_INT #define ErtsStrToSint strtol #elif SIZEOF_VOID_P == SIZEOF_LONG_LONG @@ -320,6 +320,7 @@ typedef unsigned long long Uint; typedef long long Sint; #define SWORD_CONSTANT(Const) Const##LL #define UWORD_CONSTANT(Const) Const##ULL +#define ERTS_SWORD_MAX LLONG_MAX #define ERTS_SIZEOF_ETERM SIZEOF_LONG_LONG #if defined(__WIN32__) #define ErtsStrToSint _strtoi64 @@ -1012,6 +1013,9 @@ void erl_bin_write(unsigned char *, int, int); #define ERTS_SMALL_ABS(Small) labs(Small) #endif +#ifndef ERTS_HAVE_ERTS_SYS_ALIGNED_ALLOC +# define ERTS_HAVE_ERTS_SYS_ALIGNED_ALLOC 0 +#endif #ifdef __WIN32__ void call_break_handler(void); diff --git a/erts/emulator/beam/utils.c b/erts/emulator/beam/utils.c index 43720084d1..605a625282 100644 --- a/erts/emulator/beam/utils.c +++ b/erts/emulator/beam/utils.c @@ -576,8 +576,8 @@ erts_bld_2tup_list(Uint **hpp, Uint *szp, } Eterm -erts_bld_atom_uint_2tup_list(Uint **hpp, Uint *szp, - Sint length, Eterm atoms[], Uint uints[]) +erts_bld_atom_uword_2tup_list(Uint **hpp, Uint *szp, + Sint length, Eterm atoms[], UWord uints[]) { Sint i; Eterm res = THE_NON_VALUE; diff --git a/erts/emulator/drivers/common/efile_drv.c b/erts/emulator/drivers/common/efile_drv.c index c997fe1bf9..8de578d8b7 100644 --- a/erts/emulator/drivers/common/efile_drv.c +++ b/erts/emulator/drivers/common/efile_drv.c @@ -542,84 +542,84 @@ static void *ef_safe_realloc(void *op, Uint s) */ /* char EV_CHAR_P(ErlIOVec *ev, int p, int q) */ -#define EV_CHAR_P(ev, p, q) \ - (((char *)(ev)->iov[(q)].iov_base) + (p)) +#define EV_CHAR_P(ev, p, q) \ + (((char *)(ev)->iov[q].iov_base) + (p)) /* int EV_GET_CHAR(ErlIOVec *ev, char *p, int *pp, int *qp) */ #define EV_GET_CHAR(ev, p, pp, qp) efile_ev_get_char(ev, p ,pp, qp) static int -efile_ev_get_char(ErlIOVec *ev, char *p, int *pp, int *qp) { - if (*(pp)+1 <= (ev)->iov[*(qp)].iov_len) { - *(p) = *EV_CHAR_P(ev, *(pp), *(qp)); - if (*(pp)+1 < (ev)->iov[*(qp)].iov_len) - *(pp) = *(pp)+1; - else { - (*(qp))++; - *pp = 0; +efile_ev_get_char(ErlIOVec *ev, char *p, size_t *pp, size_t *qp) { + if (*pp + 1 <= ev->iov[*qp].iov_len) { + *p = *EV_CHAR_P(ev, *pp, *qp); + if (*pp + 1 < ev->iov[*qp].iov_len) + *pp += 1; + else { + *qp += 1; + *pp = 0; + } + return !0; } - return !0; - } - return 0; + return 0; } /* Uint32 EV_UINT32(ErlIOVec *ev, int p, int q)*/ -#define EV_UINT32(ev, p, q) \ - ((Uint32) *(((unsigned char *)(ev)->iov[(q)].iov_base) + (p))) +#define EV_UINT32(ev, p, q) \ + ((Uint32) ((unsigned char *)(ev)->iov[q].iov_base)[p]) /* int EV_GET_UINT32(ErlIOVec *ev, Uint32 *p, int *pp, int *qp) */ -#define EV_GET_UINT32(ev, p, pp, qp) efile_ev_get_uint32(ev,p,pp,qp) +#define EV_GET_UINT32(ev, p, pp, qp) efile_ev_get_uint32(ev, p, pp, qp) static int -efile_ev_get_uint32(ErlIOVec *ev, Uint32 *p, int *pp, int *qp) { - if (*(pp)+4 <= (ev)->iov[*(qp)].iov_len) { - *(p) = (EV_UINT32(ev, *(pp), *(qp)) << 24) - | (EV_UINT32(ev, *(pp)+1, *(qp)) << 16) - | (EV_UINT32(ev, *(pp)+2, *(qp)) << 8) - | (EV_UINT32(ev, *(pp)+3, *(qp))); - if (*(pp)+4 < (ev)->iov[*(qp)].iov_len) - *(pp) = *(pp)+4; - else { - (*(qp))++; - *pp = 0; +efile_ev_get_uint32(ErlIOVec *ev, Uint32 *p, size_t *pp, size_t *qp) { + if (*pp + 4 <= ev->iov[*qp].iov_len) { + *p = (EV_UINT32(ev, *pp, *qp) << 24) + | (EV_UINT32(ev, *pp + 1, *qp) << 16) + | (EV_UINT32(ev, *pp + 2, *qp) << 8) + | (EV_UINT32(ev, *pp + 3, *qp)); + if (*pp + 4 < ev->iov[*qp].iov_len) + *pp += 4; + else { + *qp += 1; + *pp = 0; + } + return !0; } - return !0; - } - return 0; + return 0; } /* Uint64 EV_UINT64(ErlIOVec *ev, int p, int q)*/ -#define EV_UINT64(ev, p, q) \ - ((Uint64) *(((unsigned char *)(ev)->iov[(q)].iov_base) + (p))) +#define EV_UINT64(ev, p, q) \ + ((Uint64) ((unsigned char *)(ev)->iov[q].iov_base)[p]) /* int EV_GET_UINT64(ErlIOVec *ev, Uint64 *p, int *pp, int *qp) */ -#define EV_GET_UINT64(ev, p, pp, qp) efile_ev_get_uint64(ev,p,pp,qp) +#define EV_GET_UINT64(ev, p, pp, qp) efile_ev_get_uint64(ev, p, pp, qp) static int -efile_ev_get_uint64(ErlIOVec *ev, Uint64 *p, int *pp, int *qp) { - if (*(pp)+8 <= (ev)->iov[*(qp)].iov_len) { - *(p) = (EV_UINT64(ev, *(pp), *(qp)) << 56) - | (EV_UINT64(ev, *(pp)+1, *(qp)) << 48) - | (EV_UINT64(ev, *(pp)+2, *(qp)) << 40) - | (EV_UINT64(ev, *(pp)+3, *(qp)) << 32) - | (EV_UINT64(ev, *(pp)+4, *(qp)) << 24) - | (EV_UINT64(ev, *(pp)+5, *(qp)) << 16) - | (EV_UINT64(ev, *(pp)+6, *(qp)) << 8) - | (EV_UINT64(ev, *(pp)+7, *(qp))); - if (*(pp)+8 < (ev)->iov[*(qp)].iov_len) - *(pp) = *(pp)+8; - else { - (*(qp))++; - *pp = 0; +efile_ev_get_uint64(ErlIOVec *ev, Uint64 *p, size_t *pp, size_t *qp) { + if (*pp + 8 <= ev->iov[*qp].iov_len) { + *p = (EV_UINT64(ev, *pp, *qp) << 56) + | (EV_UINT64(ev, *pp + 1, *qp) << 48) + | (EV_UINT64(ev, *pp + 2, *qp) << 40) + | (EV_UINT64(ev, *pp + 3, *qp) << 32) + | (EV_UINT64(ev, *pp + 4, *qp) << 24) + | (EV_UINT64(ev, *pp + 5, *qp) << 16) + | (EV_UINT64(ev, *pp + 6, *qp) << 8) + | (EV_UINT64(ev, *pp + 7, *qp)); + if (*pp + 8 < ev->iov[*qp].iov_len) + *pp += 8; + else { + *qp += 1; + *pp = 0; + } + return !0; } - return !0; - } - return 0; + return 0; } /* int EV_GET_SINT64(ErlIOVec *ev, Uint64 *p, int *pp, int *qp) */ -#define EV_GET_SINT64(ev, p, pp, qp) efile_ev_get_sint64(ev,p,pp,qp) +#define EV_GET_SINT64(ev, p, pp, qp) efile_ev_get_sint64(ev, p, pp, qp) static int -efile_ev_get_sint64(ErlIOVec *ev, Sint64 *p, int *pp, int *qp) { - Uint64 *tmp = (Uint64*)p; - return EV_GET_UINT64(ev,tmp,pp,qp); +efile_ev_get_sint64(ErlIOVec *ev, Sint64 *p, size_t *pp, size_t *qp) { + Uint64 *tmp = (Uint64*)p; + return EV_GET_UINT64(ev, tmp, pp, qp); } #if 0 @@ -1139,7 +1139,7 @@ static void invoke_read(void *data) read_size = erts_gzread((gzFile)d->fd, d->c.read.binp->orig_bytes + d->c.read.bin_offset, size); - status = (read_size != -1); + status = (read_size != (size_t) -1); if (!status) { d->errInfo.posix_errno = EIO; } @@ -1213,7 +1213,7 @@ static void invoke_read_line(void *data) d->c.read_line.binp->orig_bytes + d->c.read_line.read_offset + d->c.read_line.read_size, size); - status = (read_size != -1); + status = (read_size != (size_t) -1); if (!status) { d->errInfo.posix_errno = EIO; } @@ -1707,8 +1707,9 @@ static void invoke_pwritev(void *data) { ASSERT(written == size); d->again = 0; } - } else + } else { ASSERT(written >= FILE_SEGMENT_WRITE); + } MUTEX_LOCK(d->c.writev.q_mtx); driver_deq(d->c.pwritev.port, written); @@ -3205,7 +3206,7 @@ static void file_outputv(ErlDrvData e, ErlIOVec *ev) { file_descriptor* desc = (file_descriptor*)e; char command; - int p, q; + size_t p, q; int err; struct t_data *d = NULL; #ifdef USE_VM_PROBES diff --git a/erts/emulator/drivers/common/inet_drv.c b/erts/emulator/drivers/common/inet_drv.c index 301ce2d0e2..4fb20bf1b0 100644 --- a/erts/emulator/drivers/common/inet_drv.c +++ b/erts/emulator/drivers/common/inet_drv.c @@ -86,6 +86,13 @@ #endif typedef unsigned long long llu_t; +#ifndef INT16_MIN +#define INT16_MIN (-32768) +#endif +#ifndef INT16_MAX +#define INT16_MAX (32767) +#endif + #ifdef __WIN32__ #define STRNCASECMP strncasecmp @@ -282,7 +289,7 @@ static BOOL (WINAPI *fpSetHandleInformation)(HANDLE,DWORD,DWORD); static unsigned long zero_value = 0; static unsigned long one_value = 1; -#else +#else /* #ifdef __WIN32__ */ #include <sys/time.h> #ifdef NETDB_H_NEEDS_IN_H @@ -315,9 +322,17 @@ static unsigned long one_value = 1; #include <net/if.h> +#ifdef HAVE_SCHED_H +#include <sched.h> +#endif + +#ifdef HAVE_SETNS_H +#include <setns.h> +#endif + /* SCTP support -- currently for UNIX platforms only: */ #undef HAVE_SCTP -#if (!defined(__WIN32__) && defined(HAVE_SCTP_H)) +#if defined(HAVE_SCTP_H) #include <netinet/sctp.h> @@ -418,7 +433,7 @@ static int (*p_sctp_bindx)(int sd, struct sockaddr *addrs, static int (*p_sctp_peeloff)(int sd, sctp_assoc_t assoc_id) = NULL; #endif -#endif /* SCTP supported */ +#endif /* #if defined(HAVE_SCTP_H) */ #ifndef WANT_NONBLOCKING #define WANT_NONBLOCKING @@ -512,7 +527,7 @@ static int my_strncasecmp(const char *s1, const char *s2, size_t n) } while(0) -#endif /* __WIN32__ */ +#endif /* #ifdef __WIN32__ #else */ #ifdef HAVE_SOCKLEN_T # define SOCKLEN_T socklen_t @@ -573,6 +588,7 @@ static int my_strncasecmp(const char *s1, const char *s2, size_t n) #define INET_PASSIVE 0 /* false */ #define INET_ACTIVE 1 /* true */ #define INET_ONCE 2 /* true; active once then passive */ +#define INET_MULTI 3 /* true; active N then passive */ /* INET_REQ_GETSTATUS enumeration */ #define INET_F_OPEN 0x0001 @@ -680,6 +696,7 @@ static int my_strncasecmp(const char *s1, const char *s2, size_t n) #define INET_LOPT_TCP_SEND_TIMEOUT_CLOSE 35 /* auto-close on send timeout or not */ #define INET_LOPT_MSGQ_HIWTRMRK 36 /* set local msgq high watermark */ #define INET_LOPT_MSGQ_LOWTRMRK 37 /* set local msgq low watermark */ +#define INET_LOPT_NETNS 38 /* Network namespace pathname */ /* SCTP options: a separate range, from 100: */ #define SCTP_OPT_RTOINFO 100 #define SCTP_OPT_ASSOCINFO 101 @@ -916,6 +933,7 @@ typedef struct { inet_async_op op_queue[INET_MAX_ASYNC]; /* call queue */ int active; /* 0 = passive, 1 = active, 2 = active once */ + Sint16 active_count; /* counter for {active,N} */ int stype; /* socket type: SOCK_STREAM/SOCK_DGRAM/SOCK_SEQPACKET */ int sprotocol; /* socket protocol: @@ -955,6 +973,10 @@ typedef struct { int is_ignored; /* if a fd is ignored by the inet_drv. This flag should be set to true when the fd is used outside of inet_drv. */ +#ifdef HAVE_SETNS + char *netns; /* Socket network namespace name + as full file path */ +#endif } inet_descriptor; @@ -1147,22 +1169,36 @@ static int packet_inet_output(udp_descriptor* udesc, HANDLE event); static int async_ref = 0; /* async reference id generator */ #define NEW_ASYNC_ID() ((async_ref++) & 0xffff) +/* check for transition from active to passive */ +#define INET_CHECK_ACTIVE_TO_PASSIVE(inet) \ + do { \ + if ((inet)->active == INET_ONCE) \ + (inet)->active = INET_PASSIVE; \ + else if ((inet)->active == INET_MULTI && --((inet)->active_count) == 0) { \ + (inet)->active = INET_PASSIVE; \ + packet_passive_message(inet); \ + } \ + } while (0) static ErlDrvTermData am_ok; static ErlDrvTermData am_tcp; static ErlDrvTermData am_udp; static ErlDrvTermData am_error; +static ErlDrvTermData am_einval; static ErlDrvTermData am_inet_async; static ErlDrvTermData am_inet_reply; static ErlDrvTermData am_timeout; static ErlDrvTermData am_closed; +static ErlDrvTermData am_tcp_passive; static ErlDrvTermData am_tcp_closed; static ErlDrvTermData am_tcp_error; +static ErlDrvTermData am_udp_passive; static ErlDrvTermData am_udp_error; static ErlDrvTermData am_empty_out_q; static ErlDrvTermData am_ssl_tls; #ifdef HAVE_SCTP static ErlDrvTermData am_sctp; +static ErlDrvTermData am_sctp_passive; static ErlDrvTermData am_sctp_error; static ErlDrvTermData am_true; static ErlDrvTermData am_false; @@ -1172,6 +1208,7 @@ static ErlDrvTermData am_list; static ErlDrvTermData am_binary; static ErlDrvTermData am_active; static ErlDrvTermData am_once; +static ErlDrvTermData am_multi; static ErlDrvTermData am_buffer; static ErlDrvTermData am_linger; static ErlDrvTermData am_recbuf; @@ -1181,6 +1218,7 @@ static ErlDrvTermData am_dontroute; static ErlDrvTermData am_priority; static ErlDrvTermData am_tos; static ErlDrvTermData am_ipv6_v6only; +static ErlDrvTermData am_netns; #endif /* speical errors for bad ports and sequences */ @@ -3323,6 +3361,34 @@ static int packet_binary_message } /* +** active mode message: send active-to-passive transition message +** {tcp_passive, S} or +** {udp_passive, S} or +** {sctp_passive, S} +*/ + static int packet_passive_message(inet_descriptor* desc) + { + ErlDrvTermData spec[6]; + int i = 0; + + DEBUGF(("packet_passive_message(%ld):\r\n", (long)desc->port)); + + if (desc->sprotocol == IPPROTO_TCP) + i = LOAD_ATOM(spec, i, am_tcp_passive); + else { +#ifdef HAVE_SCTP + i = LOAD_ATOM(spec, i, IS_SCTP(desc) ? am_sctp_passive : am_udp_passive); +#else + i = LOAD_ATOM(spec, i, am_udp_passive); +#endif + } + i = LOAD_PORT(spec, i, desc->dport); + i = LOAD_TUPLE(spec, i, 2); + ASSERT(i <= 6); + return erl_drv_output_term(desc->dport, spec, i); + } + +/* ** send active message {udp_error|sctp_error, S, Error} */ static int packet_error_message(udp_descriptor* udesc, int err) @@ -3364,7 +3430,7 @@ static int tcp_reply_data(tcp_descriptor* desc, char* buf, int len) int code; const char* body = buf; int bodylen = len; - + packet_get_body(desc->inet.htype, &body, &bodylen); if (desc->inet.deliver == INET_DELIVER_PORT) { @@ -3382,8 +3448,7 @@ static int tcp_reply_data(tcp_descriptor* desc, char* buf, int len) if (code < 0) return code; - if (desc->inet.active == INET_ONCE) - desc->inet.active = INET_PASSIVE; + INET_CHECK_ACTIVE_TO_PASSIVE(INETP(desc)); return code; } @@ -3410,8 +3475,7 @@ tcp_reply_binary_data(tcp_descriptor* desc, ErlDrvBinary* bin, int offs, int len } if (code < 0) return code; - if (desc->inet.active == INET_ONCE) - desc->inet.active = INET_PASSIVE; + INET_CHECK_ACTIVE_TO_PASSIVE(INETP(desc)); return code; } @@ -3434,8 +3498,7 @@ packet_reply_binary_data(inet_descriptor* desc, unsigned int hsz, code = packet_binary_message(desc, bin, offs, len, extra); if (code < 0) return code; - if (desc->active == INET_ONCE) - desc->active = INET_PASSIVE; + INET_CHECK_ACTIVE_TO_PASSIVE(desc); return code; } } @@ -3480,6 +3543,7 @@ sock_init(void) /* May be called multiple times. */ #ifdef HAVE_SCTP static void inet_init_sctp(void) { INIT_ATOM(sctp); + INIT_ATOM(sctp_passive); INIT_ATOM(sctp_error); INIT_ATOM(true); INIT_ATOM(false); @@ -3489,6 +3553,7 @@ static void inet_init_sctp(void) { INIT_ATOM(binary); INIT_ATOM(active); INIT_ATOM(once); + INIT_ATOM(multi); INIT_ATOM(buffer); INIT_ATOM(linger); INIT_ATOM(recbuf); @@ -3498,6 +3563,7 @@ static void inet_init_sctp(void) { INIT_ATOM(priority); INIT_ATOM(tos); INIT_ATOM(ipv6_v6only); + INIT_ATOM(netns); /* Option names */ INIT_ATOM(sctp_rtoinfo); @@ -3613,12 +3679,15 @@ static int inet_init() INIT_ATOM(tcp); INIT_ATOM(udp); INIT_ATOM(error); + INIT_ATOM(einval); INIT_ATOM(inet_async); INIT_ATOM(inet_reply); INIT_ATOM(timeout); INIT_ATOM(closed); + INIT_ATOM(tcp_passive); INIT_ATOM(tcp_closed); INIT_ATOM(tcp_error); + INIT_ATOM(udp_passive); INIT_ATOM(udp_error); INIT_ATOM(empty_out_q); INIT_ATOM(ssl_tls); @@ -3908,12 +3977,81 @@ static int erl_inet_close(inet_descriptor* desc) static ErlDrvSSizeT inet_ctl_open(inet_descriptor* desc, int domain, int type, char** rbuf, ErlDrvSizeT rsize) { + int save_errno; +#ifdef HAVE_SETNS + int current_ns, new_ns; + current_ns = new_ns = 0; +#endif + save_errno = 0; + if (desc->state != INET_STATE_CLOSED) return ctl_xerror(EXBADSEQ, rbuf, rsize); + +#ifdef HAVE_SETNS + if (desc->netns != NULL) { + /* Temporarily change network namespace for this thread + * while creating the socket + */ + current_ns = open("/proc/self/ns/net", O_RDONLY); + if (current_ns == INVALID_SOCKET) + return ctl_error(sock_errno(), rbuf, rsize); + new_ns = open(desc->netns, O_RDONLY); + if (new_ns == INVALID_SOCKET) { + save_errno = sock_errno(); + while (close(current_ns) == INVALID_SOCKET && + sock_errno() == EINTR); + return ctl_error(save_errno, rbuf, rsize); + } + if (setns(new_ns, CLONE_NEWNET) != 0) { + save_errno = sock_errno(); + while (close(new_ns) == INVALID_SOCKET && + sock_errno() == EINTR); + while (close(current_ns) == INVALID_SOCKET && + sock_errno() == EINTR); + return ctl_error(save_errno, rbuf, rsize); + } + else { + while (close(new_ns) == INVALID_SOCKET && + sock_errno() == EINTR); + } + } +#endif if ((desc->s = sock_open(domain, type, desc->sprotocol)) == INVALID_SOCKET) - return ctl_error(sock_errno(), rbuf, rsize); - if ((desc->event = sock_create_event(desc)) == INVALID_EVENT) - return ctl_error(sock_errno(), rbuf, rsize); + save_errno = sock_errno(); +#ifdef HAVE_SETNS + if (desc->netns != NULL) { + /* Restore network namespace */ + if (setns(current_ns, CLONE_NEWNET) != 0) { + /* XXX Failed to restore network namespace. + * What to do? Tidy up and return an error... + * Note that the thread now might still be in the namespace. + * Can this even happen? Should the emulator be aborted? + */ + if (desc->s != INVALID_SOCKET) + save_errno = sock_errno(); + while (close(desc->s) == INVALID_SOCKET && + sock_errno() == EINTR); + desc->s = INVALID_SOCKET; + while (close(current_ns) == INVALID_SOCKET && + sock_errno() == EINTR); + return ctl_error(save_errno, rbuf, rsize); + } + else { + while (close(current_ns) == INVALID_SOCKET && + sock_errno() == EINTR); + } + } +#endif + if (desc->s == INVALID_SOCKET) + return ctl_error(save_errno, rbuf, rsize); + + if ((desc->event = sock_create_event(desc)) == INVALID_EVENT) { + save_errno = sock_errno(); + while (close(desc->s) == INVALID_SOCKET && + sock_errno() == EINTR); + desc->s = INVALID_SOCKET; + return ctl_error(save_errno, rbuf, rsize); + } SET_NONBLOCKING(desc->s); #ifdef __WIN32__ driver_select(desc->port, desc->event, ERL_DRV_READ, 1); @@ -4349,7 +4487,7 @@ static ErlDrvSSizeT inet_ctl_getiflist(inet_descriptor* desc, case AF_INET6: #endif case AF_INET: - ASSERT(sp+IFNAMSIZ+1 < sbuf+ifc.ifc_len+1) + ASSERT(sp+IFNAMSIZ+1 < sbuf+ifc.ifc_len+1); strncpy(sp, ifrp->ifr_name, IFNAMSIZ); sp[IFNAMSIZ] = '\0'; sp += strlen(sp), ++sp; @@ -5424,8 +5562,25 @@ static int inet_set_opts(inet_descriptor* desc, char* ptr, int len) case INET_LOPT_ACTIVE: DEBUGF(("inet_set_opts(%ld): s=%d, ACTIVE=%d\r\n", - (long)desc->port, desc->s,ival)); + (long)desc->port, desc->s, ival)); desc->active = ival; + if (desc->active == INET_MULTI) { + long ac = desc->active_count; + Sint16 nval = get_int16(ptr); + ptr += 2; + len -= 2; + ac += nval; + if (ac > INT16_MAX || ac < INT16_MIN) + return -1; + desc->active_count += nval; + if (desc->active_count < 0) + desc->active_count = 0; + if (desc->active_count == 0) { + desc->active = INET_PASSIVE; + packet_passive_message(desc); + } + } else + desc->active_count = 0; if ((desc->stype == SOCK_STREAM) && (desc->active != INET_PASSIVE) && (desc->state == INET_STATE_CLOSED)) { tcp_closed_message((tcp_descriptor *) desc); @@ -5529,6 +5684,20 @@ static int inet_set_opts(inet_descriptor* desc, char* ptr, int len) } continue; +#ifdef HAVE_SETNS + case INET_LOPT_NETNS: + /* It is annoying that ival and len are both (signed) int */ + if (ival < 0) return -1; + if (len < ival) return -1; + if (desc->netns != NULL) FREE(desc->netns); + desc->netns = ALLOC(((unsigned int) ival) + 1); + memcpy(desc->netns, ptr, ival); + desc->netns[ival] = '\0'; + ptr += ival; + len -= ival; + continue; +#endif + case INET_OPT_REUSEADDR: #ifdef __WIN32__ continue; /* Bjorn says */ @@ -5722,7 +5891,8 @@ static int inet_set_opts(inet_descriptor* desc, char* ptr, int len) /* XXX fprintf(stderr,"desc->htype == %d, old_htype == %d, desc->active == %d, old_active == %d\r\n",(int)desc->htype, (int) old_htype, (int) desc->active, (int) old_active );*/ - return 1+(desc->htype == old_htype && desc->active == INET_ONCE); + return 1+(desc->htype == old_htype && + (desc->active == INET_ONCE || desc->active == INET_MULTI)); } return 0; } @@ -5855,9 +6025,39 @@ static int sctp_set_opts(inet_descriptor* desc, char* ptr, int len) case INET_LOPT_ACTIVE: desc->active = get_int32(curr); curr += 4; + if (desc->active == INET_MULTI) { + long ac = desc->active_count; + Sint16 nval = get_int16(curr); curr += 2; + ac += nval; + if (ac > INT16_MAX || ac < INT16_MIN) + return -1; + desc->active_count += nval; + if (desc->active_count < 0) + desc->active_count = 0; + if (desc->active_count == 0) { + desc->active = INET_PASSIVE; + packet_passive_message(desc); + } + } else + desc->active_count = 0; res = 0; continue; +#ifdef HAVE_SETNS + case INET_LOPT_NETNS: + { + size_t ns_len; + ns_len = get_int32(curr); curr += 4; + CHKLEN(curr, ns_len); + if (desc->netns != NULL) FREE(desc->netns); + desc->netns = ALLOC(ns_len + 1); + memcpy(desc->netns, curr, ns_len); + desc->netns[ns_len] = '\0'; + curr += ns_len; + } + continue; +#endif + /* SCTP options and applicable generic INET options: */ case SCTP_OPT_RTOINFO: @@ -6362,6 +6562,11 @@ static ErlDrvSSizeT inet_fill_opts(inet_descriptor* desc, case INET_LOPT_ACTIVE: *ptr++ = opt; put_int32(desc->active, ptr); + if (desc->active == INET_MULTI) { + PLACE_FOR(2,ptr); + put_int16(desc->active_count, ptr); + ptr += 2; + } continue; case INET_LOPT_PACKET: *ptr++ = opt; @@ -6454,6 +6659,22 @@ static ErlDrvSSizeT inet_fill_opts(inet_descriptor* desc, } continue; +#ifdef HAVE_SETNS + case INET_LOPT_NETNS: + if (desc->netns != NULL) { + size_t netns_len; + netns_len = strlen(desc->netns); + *ptr++ = opt; + put_int32(netns_len, ptr); + PLACE_FOR(netns_len, ptr); + memcpy(ptr, desc->netns, netns_len); + ptr += netns_len; + } else { + TRUNCATE_TO(0,ptr); + } + continue; +#endif + case INET_OPT_PRIORITY: #ifdef SO_PRIORITY type = SO_PRIORITY; @@ -6718,7 +6939,10 @@ static ErlDrvSSizeT sctp_fill_opts(inet_descriptor* desc, } case INET_LOPT_ACTIVE: { - PLACE_FOR(spec, i, 2*LOAD_ATOM_CNT + LOAD_TUPLE_CNT); + if (desc->active == INET_MULTI) + PLACE_FOR(spec, i, LOAD_ATOM_CNT + LOAD_INT_CNT + LOAD_TUPLE_CNT); + else + PLACE_FOR(spec, i, 2*LOAD_ATOM_CNT + LOAD_TUPLE_CNT); i = LOAD_ATOM (spec, i, am_active); switch (desc->active) { @@ -6731,12 +6955,31 @@ static ErlDrvSSizeT sctp_fill_opts(inet_descriptor* desc, case INET_ONCE : { i = LOAD_ATOM (spec, i, am_once); break; } + case INET_MULTI : + { i = LOAD_INT(spec, i, desc->active_count); break; } + default: ASSERT (0); } i = LOAD_TUPLE (spec, i, 2); break; } +#ifdef HAVE_SETNS + case INET_LOPT_NETNS: + if (desc->netns != NULL) { + PLACE_FOR + (spec, i, + LOAD_ATOM_CNT + LOAD_BUF2BINARY_CNT + LOAD_TUPLE_CNT); + i = LOAD_ATOM (spec, i, am_netns); + i = LOAD_BUF2BINARY + (spec, i, desc->netns, strlen(desc->netns)); + i = LOAD_TUPLE (spec, i, 2); + break; + } + else + continue; /* Ignore */ +#endif + /* SCTP and generic INET options: */ case SCTP_OPT_RTOINFO: @@ -7458,6 +7701,10 @@ static ErlDrvSSizeT inet_subscribe(inet_descriptor* desc, static void inet_stop(inet_descriptor* desc) { erl_inet_close(desc); +#ifdef HAVE_SETNS + if (desc->netns != NULL) + FREE(desc->netns); +#endif FREE(desc); } @@ -7507,6 +7754,7 @@ static ErlDrvData inet_start(ErlDrvPort port, int size, int protocol) socket */ desc->deliver = INET_DELIVER_TERM; /* standard term format */ desc->active = INET_PASSIVE; /* start passive */ + desc->active_count = 0; desc->oph = NULL; desc->opt = NULL; @@ -7537,6 +7785,10 @@ static ErlDrvData inet_start(ErlDrvPort port, int size, int protocol) desc->is_ignored = 0; +#ifdef HAVE_SETNS + desc->netns = NULL; +#endif + return (ErlDrvData)desc; } diff --git a/erts/emulator/drivers/unix/ttsl_drv.c b/erts/emulator/drivers/unix/ttsl_drv.c index 1e436830e7..491e0a090e 100644 --- a/erts/emulator/drivers/unix/ttsl_drv.c +++ b/erts/emulator/drivers/unix/ttsl_drv.c @@ -745,7 +745,7 @@ static Sint16 get_sint16(char *s) { return ((*s << 8) | ((byte*)s)[1]); } - + static int start_lbuf(void) { if (!lbuf && !(lbuf = ( Uint32*) driver_alloc(lbuf_size * sizeof(Uint32)))) @@ -1091,7 +1091,7 @@ static int move_cursor(int from, int to) move_left(-dc); return TRUE; } - + static int start_termcap(void) { int eres; @@ -1187,7 +1187,7 @@ static int move_down(int n) tputs(down, 1, outc); return TRUE; } - + /* * Updates cols if terminal has resized (SIGWINCH). Should be called @@ -1209,7 +1209,7 @@ static void update_cols(void) cols = width; } } - + /* * Put a terminal device into non-canonical mode with ECHO off. diff --git a/erts/emulator/drivers/win32/win_efile.c b/erts/emulator/drivers/win32/win_efile.c index b36a103f8e..319065f57b 100644 --- a/erts/emulator/drivers/win32/win_efile.c +++ b/erts/emulator/drivers/win32/win_efile.c @@ -1216,7 +1216,7 @@ int flags; return 1; } - + /* * is_root_unc_name - returns TRUE if the argument is a UNC name specifying * a root share. That is, if it is of the form \\server\share\. diff --git a/erts/emulator/sys/common/erl_mmap.c b/erts/emulator/sys/common/erl_mmap.c new file mode 100644 index 0000000000..a9da7430fb --- /dev/null +++ b/erts/emulator/sys/common/erl_mmap.c @@ -0,0 +1,2832 @@ +/* + * %CopyrightBegin% + * + * Copyright Ericsson AB 2002-2013. All Rights Reserved. + * + * The contents of this file are subject to the Erlang Public License, + * Version 1.1, (the "License"); you may not use this file except in + * compliance with the License. You should have received a copy of the + * Erlang Public License along with this software. If not, it can be + * retrieved online at http://www.erlang.org/. + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + * the License for the specific language governing rights and limitations + * under the License. + * + * %CopyrightEnd% + */ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "sys.h" +#include "erl_process.h" +#include "erl_smp.h" +#include "atom.h" +#include "erl_mmap.h" +#include <stddef.h> + +/* #define ERTS_MMAP_OP_RINGBUF_SZ 100 */ + +#if defined(DEBUG) || 0 +# undef ERTS_MMAP_DEBUG +# define ERTS_MMAP_DEBUG +# ifndef ERTS_MMAP_OP_RINGBUF_SZ +# define ERTS_MMAP_OP_RINGBUF_SZ 100 +# endif +#endif + +#ifndef ERTS_MMAP_OP_RINGBUF_SZ +# define ERTS_MMAP_OP_RINGBUF_SZ 0 +#endif + +/* #define ERTS_MMAP_DEBUG_FILL_AREAS */ + +#ifdef ERTS_MMAP_DEBUG +# define ERTS_MMAP_ASSERT ERTS_ASSERT +#else +# define ERTS_MMAP_ASSERT(A) ((void) 1) +#endif + +/* + * `mmap_state.sa.bot` and `mmap_state.sua.top` are read only after + * initialization, but the other pointers are not; i.e., only + * ERTS_MMAP_IN_SUPERCARRIER() is allowed without the mutex held. + */ +#define ERTS_MMAP_IN_SUPERCARRIER(PTR) \ + (((UWord) (PTR)) - ((UWord) mmap_state.sa.bot) \ + < ((UWord) mmap_state.sua.top) - ((UWord) mmap_state.sa.bot)) +#define ERTS_MMAP_IN_SUPERALIGNED_AREA(PTR) \ + (ERTS_SMP_LC_ASSERT(erts_lc_mtx_is_locked(&mmap_state.mtx)), \ + (((UWord) (PTR)) - ((UWord) mmap_state.sa.bot) \ + < ((UWord) mmap_state.sa.top) - ((UWord) mmap_state.sa.bot))) +#define ERTS_MMAP_IN_SUPERUNALIGNED_AREA(PTR) \ + (ERTS_SMP_LC_ASSERT(erts_lc_mtx_is_locked(&mmap_state.mtx)), \ + (((UWord) (PTR)) - ((UWord) mmap_state.sua.bot) \ + < ((UWord) mmap_state.sua.top) - ((UWord) mmap_state.sua.bot))) + +int erts_have_erts_mmap; +UWord erts_page_inv_mask; + +#if defined(DEBUG) || defined(ERTS_MMAP_DEBUG) +# undef RBT_DEBUG +# define RBT_DEBUG +#endif +#ifdef RBT_DEBUG +# define RBT_ASSERT ERTS_ASSERT +# define IF_RBT_DEBUG(C) C +#else +# define RBT_ASSERT(x) +# define IF_RBT_DEBUG(C) +#endif + +typedef struct RBTNode_ RBTNode; +struct RBTNode_ { + UWord parent_and_color; /* color in bit 0 of parent ptr */ + RBTNode *left; + RBTNode *right; +}; + +#define RED_FLG (1) +#define IS_RED(N) ((N) && ((N)->parent_and_color & RED_FLG)) +#define IS_BLACK(N) (!IS_RED(N)) +#define SET_RED(N) ((N)->parent_and_color |= RED_FLG) +#define SET_BLACK(N) ((N)->parent_and_color &= ~RED_FLG) + +static ERTS_INLINE RBTNode* parent(RBTNode* node) +{ + return (RBTNode*) (node->parent_and_color & ~RED_FLG); +} + +static ERTS_INLINE void set_parent(RBTNode* node, RBTNode* parent) +{ + RBT_ASSERT(!((UWord)parent & RED_FLG)); + node->parent_and_color = ((UWord)parent) | (node->parent_and_color & RED_FLG); +} + +static ERTS_INLINE UWord parent_and_color(RBTNode* parent, int color) +{ + RBT_ASSERT(!((UWord)parent & RED_FLG)); + RBT_ASSERT(!(color & ~RED_FLG)); + return ((UWord)parent) | color; +} + + +enum SortOrder { + ADDR_ORDER, /* only address order */ + SA_SZ_ADDR_ORDER, /* first super-aligned size then address order */ + SZ_REVERSE_ADDR_ORDER /* first size then reverse address order */ +}; +#ifdef HARD_DEBUG +static const char* sort_order_names[] = {"Address","SuperAlignedSize-Address","Size-RevAddress"}; +#endif + +typedef struct { + RBTNode* root; + enum SortOrder order; +}RBTree; + +#ifdef HARD_DEBUG +# define HARD_CHECK_IS_MEMBER(ROOT,NODE) rbt_assert_is_member(ROOT,NODE) +# define HARD_CHECK_TREE(TREE,SZ) check_tree(TREE, SZ) +static int rbt_assert_is_member(RBTNode* root, RBTNode* node); +static RBTNode* check_tree(RBTree* tree, Uint); +#else +# define HARD_CHECK_IS_MEMBER(ROOT,NODE) +# define HARD_CHECK_TREE(TREE,SZ) +#endif + +#if ERTS_MMAP_OP_RINGBUF_SZ + +static int mmap_op_ix; + +typedef enum { + ERTS_OP_TYPE_NONE, + ERTS_OP_TYPE_MMAP, + ERTS_OP_TYPE_MUNMAP, + ERTS_OP_TYPE_MREMAP +} ErtsMMapOpType; + +typedef struct { + ErtsMMapOpType type; + void *result; + UWord in_size; + UWord out_size; + void *old_ptr; + UWord old_size; +} ErtsMMapOp; + +static ErtsMMapOp mmap_ops[ERTS_MMAP_OP_RINGBUF_SZ]; + +#define ERTS_MMAP_OP_RINGBUF_INIT() \ + do { \ + int ix__; \ + for (ix__ = 0; ix__ < ERTS_MMAP_OP_RINGBUF_SZ; ix__++) {\ + mmap_ops[ix__].type = ERTS_OP_TYPE_NONE; \ + mmap_ops[ix__].result = NULL; \ + mmap_ops[ix__].in_size = 0; \ + mmap_ops[ix__].out_size = 0; \ + mmap_ops[ix__].old_ptr = NULL; \ + mmap_ops[ix__].old_size = 0; \ + } \ + mmap_op_ix = ERTS_MMAP_OP_RINGBUF_SZ-1; \ + } while (0) + +#define ERTS_MMAP_OP_START(SZ) \ + do { \ + int ix__; \ + if (++mmap_op_ix >= ERTS_MMAP_OP_RINGBUF_SZ) \ + mmap_op_ix = 0; \ + ix__ = mmap_op_ix; \ + mmap_ops[ix__].type = ERTS_OP_TYPE_MMAP; \ + mmap_ops[ix__].result = NULL; \ + mmap_ops[ix__].in_size = (SZ); \ + mmap_ops[ix__].out_size = 0; \ + mmap_ops[ix__].old_ptr = NULL; \ + mmap_ops[ix__].old_size = 0; \ + } while (0) + +#define ERTS_MMAP_OP_END(PTR, SZ) \ + do { \ + int ix__ = mmap_op_ix; \ + mmap_ops[ix__].result = (PTR); \ + mmap_ops[ix__].out_size = (SZ); \ + } while (0) + +#define ERTS_MMAP_OP_LCK(RES, IN_SZ, OUT_SZ) \ + do { \ + erts_smp_mtx_lock(&mmap_state.mtx); \ + ERTS_MMAP_OP_START((IN_SZ)); \ + ERTS_MMAP_OP_END((RES), (OUT_SZ)); \ + erts_smp_mtx_unlock(&mmap_state.mtx); \ + } while (0) + +#define ERTS_MUNMAP_OP(PTR, SZ) \ + do { \ + int ix__; \ + if (++mmap_op_ix >= ERTS_MMAP_OP_RINGBUF_SZ) \ + mmap_op_ix = 0; \ + ix__ = mmap_op_ix; \ + mmap_ops[ix__].type = ERTS_OP_TYPE_MUNMAP; \ + mmap_ops[ix__].result = NULL; \ + mmap_ops[ix__].in_size = 0; \ + mmap_ops[ix__].out_size = 0; \ + mmap_ops[ix__].old_ptr = (PTR); \ + mmap_ops[ix__].old_size = (SZ); \ + } while (0) + +#define ERTS_MUNMAP_OP_LCK(PTR, SZ) \ + do { \ + erts_smp_mtx_lock(&mmap_state.mtx); \ + ERTS_MUNMAP_OP((PTR), (SZ)); \ + erts_smp_mtx_unlock(&mmap_state.mtx); \ + } while (0) + +#define ERTS_MREMAP_OP_START(OLD_PTR, OLD_SZ, IN_SZ) \ + do { \ + int ix__; \ + if (++mmap_op_ix >= ERTS_MMAP_OP_RINGBUF_SZ) \ + mmap_op_ix = 0; \ + ix__ = mmap_op_ix; \ + mmap_ops[ix__].type = ERTS_OP_TYPE_MREMAP; \ + mmap_ops[ix__].result = NULL; \ + mmap_ops[ix__].in_size = (IN_SZ); \ + mmap_ops[ix__].out_size = (OLD_SZ); \ + mmap_ops[ix__].old_ptr = (OLD_PTR); \ + mmap_ops[ix__].old_size = (OLD_SZ); \ + } while (0) + +#define ERTS_MREMAP_OP_END(PTR, SZ) \ + do { \ + int ix__ = mmap_op_ix; \ + mmap_ops[ix__].result = (PTR); \ + mmap_ops[mmap_op_ix].out_size = (SZ); \ + } while (0) + +#define ERTS_MREMAP_OP_LCK(RES, OLD_PTR, OLD_SZ, IN_SZ, OUT_SZ) \ + do { \ + erts_smp_mtx_lock(&mmap_state.mtx); \ + ERTS_MREMAP_OP_START((OLD_PTR), (OLD_SZ), (IN_SZ)); \ + ERTS_MREMAP_OP_END((RES), (OUT_SZ)); \ + erts_smp_mtx_unlock(&mmap_state.mtx); \ + } while (0) + +#define ERTS_MMAP_OP_ABORT() \ + do { \ + int ix__ = mmap_op_ix; \ + mmap_ops[ix__].type = ERTS_OP_TYPE_NONE; \ + mmap_ops[ix__].result = NULL; \ + mmap_ops[ix__].in_size = 0; \ + mmap_ops[ix__].out_size = 0; \ + mmap_ops[ix__].old_ptr = NULL; \ + mmap_ops[ix__].old_size = 0; \ + if (--mmap_op_ix < 0) \ + mmap_op_ix = ERTS_MMAP_OP_RINGBUF_SZ-1; \ + } while (0) + +#else + +#define ERTS_MMAP_OP_RINGBUF_INIT() +#define ERTS_MMAP_OP_START(SZ) +#define ERTS_MMAP_OP_END(PTR, SZ) +#define ERTS_MMAP_OP_LCK(RES, IN_SZ, OUT_SZ) +#define ERTS_MUNMAP_OP(PTR, SZ) +#define ERTS_MUNMAP_OP_LCK(PTR, SZ) +#define ERTS_MREMAP_OP_START(OLD_PTR, OLD_SZ, IN_SZ) +#define ERTS_MREMAP_OP_END(PTR, SZ) +#define ERTS_MREMAP_OP_LCK(RES, OLD_PTR, OLD_SZ, IN_SZ, OUT_SZ) +#define ERTS_MMAP_OP_ABORT() + +#endif + +typedef struct { + RBTNode snode; /* node in 'stree' */ + RBTNode anode; /* node in 'atree' */ + char* start; + char* end; +}ErtsFreeSegDesc; + +typedef struct { + RBTree stree; /* size ordered tree */ + RBTree atree; /* address ordered tree */ + Uint nseg; +}ErtsFreeSegMap; + +static struct { + int (*reserve_physical)(char *, UWord); + void (*unreserve_physical)(char *, UWord); + int supercarrier; + int no_os_mmap; + /* + * Super unaligend area is located above super aligned + * area. That is, `sa.bot` is beginning of the super + * carrier, `sua.top` is the end of the super carrier, + * and sa.top and sua.bot moves towards eachother. + */ + struct { + char *top; + char *bot; + ErtsFreeSegMap map; + } sua; + struct { + char *top; + char *bot; + ErtsFreeSegMap map; + } sa; +#if HAVE_MMAP && (!defined(MAP_ANON) && !defined(MAP_ANONYMOUS)) + int mmap_fd; +#endif + erts_smp_mtx_t mtx; + struct { + char *free_list; + char *unused_start; + char *unused_end; + char *new_area_hint; + Uint reserved; + } desc; + struct { + UWord free_seg_descs; + struct { + UWord curr; + UWord max; + } free_segs; + } no; + struct { + struct { + UWord total; + struct { + UWord total; + UWord sa; + UWord sua; + } used; + } supercarrier; + struct { + UWord used; + } os; + } size; +} mmap_state; + +#define ERTS_MMAP_SIZE_SC_SA_INC(SZ) \ + do { \ + mmap_state.size.supercarrier.used.total += (SZ); \ + mmap_state.size.supercarrier.used.sa += (SZ); \ + ERTS_MMAP_ASSERT(mmap_state.size.supercarrier.used.total \ + <= mmap_state.size.supercarrier.total); \ + ERTS_MMAP_ASSERT(mmap_state.size.supercarrier.used.sa \ + <= mmap_state.size.supercarrier.used.total); \ + } while (0) +#define ERTS_MMAP_SIZE_SC_SA_DEC(SZ) \ + do { \ + ERTS_MMAP_ASSERT(mmap_state.size.supercarrier.used.total >= (SZ)); \ + mmap_state.size.supercarrier.used.total -= (SZ); \ + ERTS_MMAP_ASSERT(mmap_state.size.supercarrier.used.sa >= (SZ)); \ + mmap_state.size.supercarrier.used.sa -= (SZ); \ + } while (0) +#define ERTS_MMAP_SIZE_SC_SUA_INC(SZ) \ + do { \ + mmap_state.size.supercarrier.used.total += (SZ); \ + mmap_state.size.supercarrier.used.sua += (SZ); \ + ERTS_MMAP_ASSERT(mmap_state.size.supercarrier.used.total \ + <= mmap_state.size.supercarrier.total); \ + ERTS_MMAP_ASSERT(mmap_state.size.supercarrier.used.sua \ + <= mmap_state.size.supercarrier.used.total); \ + } while (0) +#define ERTS_MMAP_SIZE_SC_SUA_DEC(SZ) \ + do { \ + ERTS_MMAP_ASSERT(mmap_state.size.supercarrier.used.total >= (SZ)); \ + mmap_state.size.supercarrier.used.total -= (SZ); \ + ERTS_MMAP_ASSERT(mmap_state.size.supercarrier.used.sua >= (SZ)); \ + mmap_state.size.supercarrier.used.sua -= (SZ); \ + } while (0) +#define ERTS_MMAP_SIZE_OS_INC(SZ) \ + do { \ + ERTS_MMAP_ASSERT(mmap_state.size.os.used + (SZ) >= (SZ)); \ + mmap_state.size.os.used += (SZ); \ + } while (0) +#define ERTS_MMAP_SIZE_OS_DEC(SZ) \ + do { \ + ERTS_MMAP_ASSERT(mmap_state.size.os.used >= (SZ)); \ + mmap_state.size.os.used -= (SZ); \ + } while (0) + + +static void +add_free_desc_area(char *start, char *end) +{ + ERTS_MMAP_ASSERT(end == (void *) 0 || end > start); + if (sizeof(ErtsFreeSegDesc) <= ((UWord) end) - ((UWord) start)) { + UWord no; + ErtsFreeSegDesc *prev_desc, *desc; + char *desc_end; + + no = 1; + prev_desc = (ErtsFreeSegDesc *) start; + prev_desc->start = mmap_state.desc.free_list; + desc = (ErtsFreeSegDesc *) (start + sizeof(ErtsFreeSegDesc)); + desc_end = start + 2*sizeof(ErtsFreeSegDesc); + + while (desc_end <= end) { + desc->start = (char *) prev_desc; + prev_desc = desc; + desc = (ErtsFreeSegDesc *) desc_end; + desc_end += sizeof(ErtsFreeSegDesc); + no++; + } + mmap_state.desc.free_list = (char *) prev_desc; + mmap_state.no.free_seg_descs += no; + } +} + +static ErtsFreeSegDesc * +add_unused_free_desc_area(void) +{ + char *ptr; + if (!mmap_state.desc.unused_start) + return NULL; + + ERTS_MMAP_ASSERT(mmap_state.desc.unused_end); + ERTS_MMAP_ASSERT(ERTS_PAGEALIGNED_SIZE + <= mmap_state.desc.unused_end - mmap_state.desc.unused_start); + + ptr = mmap_state.desc.unused_start + ERTS_PAGEALIGNED_SIZE; + add_free_desc_area(mmap_state.desc.unused_start, ptr); + + if ((mmap_state.desc.unused_end - ptr) >= ERTS_PAGEALIGNED_SIZE) + mmap_state.desc.unused_start = ptr; + else + mmap_state.desc.unused_end = mmap_state.desc.unused_start = NULL; + + ERTS_MMAP_ASSERT(mmap_state.desc.free_list); + return (ErtsFreeSegDesc *) mmap_state.desc.free_list; +} + +static ERTS_INLINE ErtsFreeSegDesc * +alloc_desc(void) +{ + ErtsFreeSegDesc *res; + res = (ErtsFreeSegDesc *) mmap_state.desc.free_list; + if (!res) { + res = add_unused_free_desc_area(); + if (!res) + return NULL; + } + mmap_state.desc.free_list = res->start; + ASSERT(mmap_state.no.free_segs.curr < mmap_state.no.free_seg_descs); + mmap_state.no.free_segs.curr++; + if (mmap_state.no.free_segs.max < mmap_state.no.free_segs.curr) + mmap_state.no.free_segs.max = mmap_state.no.free_segs.curr; + return res; +} + +static ERTS_INLINE void +free_desc(ErtsFreeSegDesc *desc) +{ + desc->start = mmap_state.desc.free_list; + mmap_state.desc.free_list = (char *) desc; + ERTS_MMAP_ASSERT(mmap_state.no.free_segs.curr > 0); + mmap_state.no.free_segs.curr--; +} + +static ERTS_INLINE ErtsFreeSegDesc* anode_to_desc(RBTNode* anode) +{ + return (ErtsFreeSegDesc*) ((char*)anode - offsetof(ErtsFreeSegDesc, anode)); +} + +static ERTS_INLINE ErtsFreeSegDesc* snode_to_desc(RBTNode* snode) +{ + return (ErtsFreeSegDesc*) ((char*)snode - offsetof(ErtsFreeSegDesc, snode)); +} + +static ERTS_INLINE ErtsFreeSegDesc* node_to_desc(enum SortOrder order, RBTNode* node) +{ + return order==ADDR_ORDER ? anode_to_desc(node) : snode_to_desc(node); +} + +static ERTS_INLINE SWord usable_size(enum SortOrder order, + ErtsFreeSegDesc* desc) +{ + return ((order == SA_SZ_ADDR_ORDER) ? + ERTS_SUPERALIGNED_FLOOR(desc->end) - ERTS_SUPERALIGNED_CEILING(desc->start) + : desc->end - desc->start); +} + +#ifdef HARD_DEBUG +static ERTS_INLINE SWord cmp_nodes(enum SortOrder order, + RBTNode* lhs, RBTNode* rhs) +{ + ErtsFreeSegDesc* ldesc = node_to_desc(order, lhs); + ErtsFreeSegDesc* rdesc = node_to_desc(order, rhs); + RBT_ASSERT(lhs != rhs); + if (order != ADDR_ORDER) { + SWord diff = usable_size(order, ldesc) - usable_size(order, rdesc); + if (diff) return diff; + } + if (order != SZ_REVERSE_ADDR_ORDER) { + return (char*)ldesc->start - (char*)rdesc->start; + } + else { + return (char*)rdesc->start - (char*)ldesc->start; + } +} +#endif /* HARD_DEBUG */ + +static ERTS_INLINE SWord cmp_with_node(enum SortOrder order, + SWord sz, char* addr, RBTNode* rhs) +{ + ErtsFreeSegDesc* rdesc; + if (order != ADDR_ORDER) { + SWord diff; + rdesc = snode_to_desc(rhs); + diff = sz - usable_size(order, rdesc); + if (diff) return diff; + } + else + rdesc = anode_to_desc(rhs); + + if (order != SZ_REVERSE_ADDR_ORDER) + return addr - (char*)rdesc->start; + else + return (char*)rdesc->start - addr; +} + + +static ERTS_INLINE void +left_rotate(RBTNode **root, RBTNode *x) +{ + RBTNode *y = x->right; + x->right = y->left; + if (y->left) + set_parent(y->left, x); + set_parent(y, parent(x)); + if (!parent(y)) { + RBT_ASSERT(*root == x); + *root = y; + } + else if (x == parent(x)->left) + parent(x)->left = y; + else { + RBT_ASSERT(x == parent(x)->right); + parent(x)->right = y; + } + y->left = x; + set_parent(x, y); +} + +static ERTS_INLINE void +right_rotate(RBTNode **root, RBTNode *x) +{ + RBTNode *y = x->left; + x->left = y->right; + if (y->right) + set_parent(y->right, x); + set_parent(y, parent(x)); + if (!parent(y)) { + RBT_ASSERT(*root == x); + *root = y; + } + else if (x == parent(x)->right) + parent(x)->right = y; + else { + RBT_ASSERT(x == parent(x)->left); + parent(x)->left = y; + } + y->right = x; + set_parent(x, y); +} + +/* + * Replace node x with node y + * NOTE: segment descriptor of y is not changed + */ +static ERTS_INLINE void +replace(RBTNode **root, RBTNode *x, RBTNode *y) +{ + + if (!parent(x)) { + RBT_ASSERT(*root == x); + *root = y; + } + else if (x == parent(x)->left) + parent(x)->left = y; + else { + RBT_ASSERT(x == parent(x)->right); + parent(x)->right = y; + } + if (x->left) { + RBT_ASSERT(parent(x->left) == x); + set_parent(x->left, y); + } + if (x->right) { + RBT_ASSERT(parent(x->right) == x); + set_parent(x->right, y); + } + + y->parent_and_color = x->parent_and_color; + y->right = x->right; + y->left = x->left; +} + +static void +tree_insert_fixup(RBTNode** root, RBTNode *node) +{ + RBTNode *x = node, *y, *papa_x, *granpa_x; + + /* + * Rearrange the tree so that it satisfies the Red-Black Tree properties + */ + + papa_x = parent(x); + RBT_ASSERT(x != *root && IS_RED(papa_x)); + do { + + /* + * x and its parent are both red. Move the red pair up the tree + * until we get to the root or until we can separate them. + */ + + granpa_x = parent(papa_x); + RBT_ASSERT(IS_RED(x)); + RBT_ASSERT(IS_BLACK(granpa_x)); + RBT_ASSERT(granpa_x); + + if (papa_x == granpa_x->left) { + y = granpa_x->right; + if (IS_RED(y)) { + SET_BLACK(y); + SET_BLACK(papa_x); + SET_RED(granpa_x); + x = granpa_x; + } + else { + + if (x == papa_x->right) { + left_rotate(root, papa_x); + papa_x = x; + x = papa_x->left; + } + + RBT_ASSERT(x == granpa_x->left->left); + RBT_ASSERT(IS_RED(x)); + RBT_ASSERT(IS_RED(papa_x)); + RBT_ASSERT(IS_BLACK(granpa_x)); + RBT_ASSERT(IS_BLACK(y)); + + SET_BLACK(papa_x); + SET_RED(granpa_x); + right_rotate(root, granpa_x); + + RBT_ASSERT(x == parent(x)->left); + RBT_ASSERT(IS_RED(x)); + RBT_ASSERT(IS_RED(parent(x)->right)); + RBT_ASSERT(IS_BLACK(parent(x))); + break; + } + } + else { + RBT_ASSERT(papa_x == granpa_x->right); + y = granpa_x->left; + if (IS_RED(y)) { + SET_BLACK(y); + SET_BLACK(papa_x); + SET_RED(granpa_x); + x = granpa_x; + } + else { + + if (x == papa_x->left) { + right_rotate(root, papa_x); + papa_x = x; + x = papa_x->right; + } + + RBT_ASSERT(x == granpa_x->right->right); + RBT_ASSERT(IS_RED(x)); + RBT_ASSERT(IS_RED(papa_x)); + RBT_ASSERT(IS_BLACK(granpa_x)); + RBT_ASSERT(IS_BLACK(y)); + + SET_BLACK(papa_x); + SET_RED(granpa_x); + left_rotate(root, granpa_x); + + RBT_ASSERT(x == parent(x)->right); + RBT_ASSERT(IS_RED(x)); + RBT_ASSERT(IS_RED(parent(x)->left)); + RBT_ASSERT(IS_BLACK(parent(x))); + break; + } + } + } while (x != *root && (papa_x=parent(x), IS_RED(papa_x))); + + SET_BLACK(*root); +} + +static void +rbt_delete(RBTree* tree, RBTNode* del) +{ + Uint spliced_is_black; + RBTNode *x, *y, *z = del, *papa_y; + RBTNode null_x; /* null_x is used to get the fixup started when we + splice out a node without children. */ + + HARD_CHECK_IS_MEMBER(tree->root, del); + HARD_CHECK_TREE(tree, 0); + + null_x.parent_and_color = parent_and_color(NULL, !RED_FLG); + + /* Remove node from tree... */ + + /* Find node to splice out */ + if (!z->left || !z->right) + y = z; + else + /* Set y to z:s successor */ + for(y = z->right; y->left; y = y->left); + /* splice out y */ + x = y->left ? y->left : y->right; + spliced_is_black = IS_BLACK(y); + papa_y = parent(y); + if (x) { + set_parent(x, papa_y); + } + else if (spliced_is_black) { + x = &null_x; + x->right = x->left = NULL; + x->parent_and_color = parent_and_color(papa_y, !RED_FLG); + y->left = x; + } + + if (!papa_y) { + RBT_ASSERT(tree->root == y); + tree->root = x; + } + else { + if (y == papa_y->left) { + papa_y->left = x; + } + else { + RBT_ASSERT(y == papa_y->right); + papa_y->right = x; + } + } + if (y != z) { + /* We spliced out the successor of z; replace z by the successor */ + RBT_ASSERT(z != &null_x); + replace(&tree->root, z, y); + } + + if (spliced_is_black) { + RBTNode* papa_x; + /* We removed a black node which makes the resulting tree + violate the Red-Black Tree properties. Fixup tree... */ + + papa_x = parent(x); + while (IS_BLACK(x) && papa_x) { + + /* + * x has an "extra black" which we move up the tree + * until we reach the root or until we can get rid of it. + * + * y is the sibbling of x + */ + + if (x == papa_x->left) { + y = papa_x->right; + RBT_ASSERT(y); + if (IS_RED(y)) { + RBT_ASSERT(y->right); + RBT_ASSERT(y->left); + SET_BLACK(y); + RBT_ASSERT(IS_BLACK(papa_x)); + SET_RED(papa_x); + left_rotate(&tree->root, papa_x); + RBT_ASSERT(papa_x == parent(x)); + y = papa_x->right; + } + RBT_ASSERT(y); + RBT_ASSERT(IS_BLACK(y)); + if (IS_BLACK(y->left) && IS_BLACK(y->right)) { + SET_RED(y); + } + else { + if (IS_BLACK(y->right)) { + SET_BLACK(y->left); + SET_RED(y); + right_rotate(&tree->root, y); + RBT_ASSERT(papa_x == parent(x)); + y = papa_x->right; + } + RBT_ASSERT(y); + if (IS_RED(papa_x)) { + + SET_BLACK(papa_x); + SET_RED(y); + } + RBT_ASSERT(y->right); + SET_BLACK(y->right); + left_rotate(&tree->root, papa_x); + x = tree->root; + break; + } + } + else { + RBT_ASSERT(x == papa_x->right); + y = papa_x->left; + RBT_ASSERT(y); + if (IS_RED(y)) { + RBT_ASSERT(y->right); + RBT_ASSERT(y->left); + SET_BLACK(y); + RBT_ASSERT(IS_BLACK(papa_x)); + SET_RED(papa_x); + right_rotate(&tree->root, papa_x); + RBT_ASSERT(papa_x == parent(x)); + y = papa_x->left; + } + RBT_ASSERT(y); + RBT_ASSERT(IS_BLACK(y)); + if (IS_BLACK(y->right) && IS_BLACK(y->left)) { + SET_RED(y); + } + else { + if (IS_BLACK(y->left)) { + SET_BLACK(y->right); + SET_RED(y); + left_rotate(&tree->root, y); + RBT_ASSERT(papa_x == parent(x)); + y = papa_x->left; + } + RBT_ASSERT(y); + if (IS_RED(papa_x)) { + SET_BLACK(papa_x); + SET_RED(y); + } + RBT_ASSERT(y->left); + SET_BLACK(y->left); + right_rotate(&tree->root, papa_x); + x = tree->root; + break; + } + } + x = papa_x; + papa_x = parent(x); + } + SET_BLACK(x); + + papa_x = parent(&null_x); + if (papa_x) { + if (papa_x->left == &null_x) + papa_x->left = NULL; + else { + RBT_ASSERT(papa_x->right == &null_x); + papa_x->right = NULL; + } + RBT_ASSERT(!null_x.left); + RBT_ASSERT(!null_x.right); + } + else if (tree->root == &null_x) { + tree->root = NULL; + RBT_ASSERT(!null_x.left); + RBT_ASSERT(!null_x.right); + } + } + HARD_CHECK_TREE(tree, 0); +} + + +static void +rbt_insert(RBTree* tree, RBTNode* node) +{ +#ifdef RBT_DEBUG + ErtsFreeSegDesc *dbg_under=NULL, *dbg_over=NULL; +#endif + ErtsFreeSegDesc* desc = node_to_desc(tree->order, node); + char* seg_addr = desc->start; + SWord seg_sz = desc->end - desc->start; + + HARD_CHECK_TREE(tree, 0); + + node->left = NULL; + node->right = NULL; + + if (!tree->root) { + node->parent_and_color = parent_and_color(NULL, !RED_FLG); + tree->root = node; + } + else { + RBTNode *x = tree->root; + while (1) { + SWord diff = cmp_with_node(tree->order, seg_sz, seg_addr, x); + if (diff < 0) { + IF_RBT_DEBUG(dbg_over = node_to_desc(tree->order, x)); + if (!x->left) { + node->parent_and_color = parent_and_color(x, RED_FLG); + x->left = node; + break; + } + x = x->left; + } + else { + RBT_ASSERT(diff > 0); + IF_RBT_DEBUG(dbg_under = node_to_desc(tree->order, x)); + if (!x->right) { + node->parent_and_color = parent_and_color(x, RED_FLG); + x->right = node; + break; + } + x = x->right; + } + } + + RBT_ASSERT(parent(node)); +#ifdef RBT_DEBUG + if (tree->order == ADDR_ORDER) { + RBT_ASSERT(!dbg_under || dbg_under->end < desc->start); + RBT_ASSERT(!dbg_over || dbg_over->start > desc->end); + } +#endif + RBT_ASSERT(IS_RED(node)); + if (IS_RED(parent(node))) + tree_insert_fixup(&tree->root, node); + } + HARD_CHECK_TREE(tree, 0); +} + +/* + * Traverse tree in (reverse) sorting order + */ +static void +rbt_foreach_node(RBTree* tree, + void (*fn)(RBTNode*,void*), + void* arg, int reverse) +{ +#ifdef HARD_DEBUG + Sint blacks = -1; + Sint curr_blacks = 1; + Uint depth = 1; + Uint max_depth = 0; + Uint node_cnt = 0; +#endif + enum { RECURSE_LEFT, DO_NODE, RECURSE_RIGHT, RETURN_TO_PARENT }state; + RBTNode *x = tree->root; + + RBT_ASSERT(!x || !parent(x)); + + state = reverse ? RECURSE_RIGHT : RECURSE_LEFT; + while (x) { + switch (state) { + case RECURSE_LEFT: + if (x->left) { + RBT_ASSERT(parent(x->left) == x); + #ifdef HARD_DEBUG + ++depth; + if (IS_BLACK(x->left)) + curr_blacks++; + #endif + x = x->left; + state = reverse ? RECURSE_RIGHT : RECURSE_LEFT; + } + else { + #ifdef HARD_DEBUG + if (blacks < 0) + blacks = curr_blacks; + RBT_ASSERT(blacks == curr_blacks); + #endif + state = reverse ? RETURN_TO_PARENT : DO_NODE; + } + break; + + case DO_NODE: + #ifdef HARD_DEBUG + ++node_cnt; + if (depth > max_depth) + max_depth = depth; + #endif + (*fn) (x, arg); /* Do it! */ + state = reverse ? RECURSE_LEFT : RECURSE_RIGHT; + break; + + case RECURSE_RIGHT: + if (x->right) { + RBT_ASSERT(parent(x->right) == x); + #ifdef HARD_DEBUG + ++depth; + if (IS_BLACK(x->right)) + curr_blacks++; + #endif + x = x->right; + state = reverse ? RECURSE_RIGHT : RECURSE_LEFT; + } + else { + #ifdef HARD_DEBUG + if (blacks < 0) + blacks = curr_blacks; + RBT_ASSERT(blacks == curr_blacks); + #endif + state = reverse ? DO_NODE : RETURN_TO_PARENT; + } + break; + + case RETURN_TO_PARENT: + #ifdef HARD_DEBUG + if (IS_BLACK(x)) + curr_blacks--; + --depth; + #endif + if (parent(x)) { + if (x == parent(x)->left) { + state = reverse ? RETURN_TO_PARENT : DO_NODE; + } + else { + RBT_ASSERT(x == parent(x)->right); + state = reverse ? DO_NODE : RETURN_TO_PARENT; + } + } + x = parent(x); + break; + } + } +#ifdef HARD_DEBUG + RBT_ASSERT(depth == 0 || (!tree->root && depth==1)); + RBT_ASSERT(curr_blacks == 0); + RBT_ASSERT((1 << (max_depth/2)) <= node_cnt); +#endif +} + +#if defined(RBT_DEBUG) || defined(HARD_DEBUG_MSEG) +static RBTNode* rbt_prev_node(RBTNode* node) +{ + RBTNode* x; + if (node->left) { + for (x=node->left; x->right; x=x->right) + ; + return x; + } + for (x=node; parent(x); x=parent(x)) { + if (parent(x)->right == x) + return parent(x); + } + return NULL; +} +static RBTNode* rbt_next_node(RBTNode* node) +{ + RBTNode* x; + if (node->right) { + for (x=node->right; x->left; x=x->left) + ; + return x; + } + for (x=node; parent(x); x=parent(x)) { + if (parent(x)->left == x) + return parent(x); + } + return NULL; +} +#endif /* RBT_DEBUG || HARD_DEBUG_MSEG */ + + +/* The API to keep track of a bunch of separated (free) segments + (non-overlapping and non-adjacent). + */ +static void init_free_seg_map(ErtsFreeSegMap*, enum SortOrder); +static void adjacent_free_seg(ErtsFreeSegMap*, char* start, char* end, + ErtsFreeSegDesc** under, ErtsFreeSegDesc** over); +static void insert_free_seg(ErtsFreeSegMap*, ErtsFreeSegDesc*, char* start, char* end); +static void resize_free_seg(ErtsFreeSegMap*, ErtsFreeSegDesc*, char* start, char* end); +static void delete_free_seg(ErtsFreeSegMap*, ErtsFreeSegDesc*); +static ErtsFreeSegDesc* lookup_free_seg(ErtsFreeSegMap*, SWord sz); + + +static void init_free_seg_map(ErtsFreeSegMap* map, enum SortOrder order) +{ + map->atree.root = NULL; + map->atree.order = ADDR_ORDER; + map->stree.root = NULL; + map->stree.order = order; + map->nseg = 0; +} + +/* Lookup directly adjacent free segments to the given area [start->end]. + * The given area must not contain any free segments. + */ +static void adjacent_free_seg(ErtsFreeSegMap* map, char* start, char* end, + ErtsFreeSegDesc** under, ErtsFreeSegDesc** over) +{ + RBTNode* x = map->atree.root; + + *under = NULL; + *over = NULL; + while (x) { + if (start < anode_to_desc(x)->start) { + RBT_ASSERT(end <= anode_to_desc(x)->start); + if (end == anode_to_desc(x)->start) { + RBT_ASSERT(!*over); + *over = anode_to_desc(x); + } + x = x->left; + } + else { + RBT_ASSERT(start >= anode_to_desc(x)->end); + if (start == anode_to_desc(x)->end) { + RBT_ASSERT(!*under); + *under = anode_to_desc(x); + } + x = x->right; + } + } +} + +/* Initialize 'desc' and insert as new free segment [start->end]. + * The new segment must not contain or be adjacent to any free segment in 'map'. + */ +static void insert_free_seg(ErtsFreeSegMap* map, ErtsFreeSegDesc* desc, + char* start, char* end) +{ + desc->start = start; + desc->end = end; + rbt_insert(&map->atree, &desc->anode); + rbt_insert(&map->stree, &desc->snode); + map->nseg++; +} + +/* Resize existing free segment 'desc' to [start->end]. + * The new segment location must overlap the old location and + * it must not contain or be adjacent to any other free segment in 'map'. + */ +static void resize_free_seg(ErtsFreeSegMap* map, ErtsFreeSegDesc* desc, + char* start, char* end) +{ +#ifdef RBT_DEBUG + RBTNode* prev = rbt_prev_node(&desc->anode); + RBTNode* next = rbt_next_node(&desc->anode); + RBT_ASSERT(!prev || anode_to_desc(prev)->end < start); + RBT_ASSERT(!next || anode_to_desc(next)->start > end); +#endif + rbt_delete(&map->stree, &desc->snode); + desc->start = start; + desc->end = end; + rbt_insert(&map->stree, &desc->snode); +} + +/* Delete existing free segment 'desc' from 'map'. + */ +static void delete_free_seg(ErtsFreeSegMap* map, ErtsFreeSegDesc* desc) +{ + rbt_delete(&map->atree, &desc->anode); + rbt_delete(&map->stree, &desc->snode); + map->nseg--; +} + +/* Lookup a free segment in 'map' with a size of at least 'need_sz' usable bytes. + */ +static ErtsFreeSegDesc* lookup_free_seg(ErtsFreeSegMap* map, SWord need_sz) +{ + RBTNode* x = map->stree.root; + ErtsFreeSegDesc* best_desc = NULL; + const enum SortOrder order = map->stree.order; + + while (x) { + ErtsFreeSegDesc* desc = snode_to_desc(x); + SWord seg_sz = usable_size(order, desc); + + if (seg_sz < need_sz) { + x = x->right; + } + else { + best_desc = desc; + x = x->left; + } + } + return best_desc; +} + +struct build_arg_t +{ + Process* p; + Eterm* hp; + Eterm acc; +}; + +static void build_free_seg_tuple(RBTNode* node, void* arg) +{ + struct build_arg_t* a = (struct build_arg_t*)arg; + ErtsFreeSegDesc* desc = anode_to_desc(node); + Eterm start= erts_bld_uword(&a->hp, NULL, (UWord)desc->start); + Eterm end = erts_bld_uword(&a->hp, NULL, (UWord)desc->end); + Eterm tpl = TUPLE2(a->hp, start, end); + + a->hp += 3; + a->acc = CONS(a->hp, tpl, a->acc); + a->hp += 2; +} + +static +Eterm build_free_seg_list(Process* p, ErtsFreeSegMap* map) +{ + struct build_arg_t barg; + Eterm* hp_end; + const Uint may_need = map->nseg * (2 + 3 + 2*2); /* cons + tuple + bigs */ + + barg.p = p; + barg.hp = HAlloc(p, may_need); + hp_end = barg.hp + may_need; + barg.acc = NIL; + rbt_foreach_node(&map->atree, build_free_seg_tuple, &barg, 1); + + RBT_ASSERT(barg.hp <= hp_end); + HRelease(p, hp_end, barg.hp); + return barg.acc; +} + +#if ERTS_HAVE_OS_MMAP +/* Implementation of os_mmap()/os_munmap()/os_mremap()... */ + +#if HAVE_MMAP +# define ERTS_MMAP_PROT (PROT_READ|PROT_WRITE) +# if defined(MAP_ANONYMOUS) +# define ERTS_MMAP_FLAGS (MAP_ANON|MAP_PRIVATE) +# define ERTS_MMAP_FD (-1) +# elif defined(MAP_ANON) +# define ERTS_MMAP_FLAGS (MAP_ANON|MAP_PRIVATE) +# define ERTS_MMAP_FD (-1) +# else +# define ERTS_MMAP_FLAGS (MAP_PRIVATE) +# define ERTS_MMAP_FD mmap_state.mmap_fd +# endif +#endif + +static ERTS_INLINE void * +os_mmap(void *hint_ptr, UWord size, int try_superalign) +{ +#if HAVE_MMAP + void *res; +#ifdef MAP_ALIGN + if (try_superalign) + res = mmap((void *) ERTS_SUPERALIGNED_SIZE, size, ERTS_MMAP_PROT, + ERTS_MMAP_FLAGS|MAP_ALIGN, ERTS_MMAP_FD, 0); + else +#endif + res = mmap((void *) hint_ptr, size, ERTS_MMAP_PROT, + ERTS_MMAP_FLAGS, ERTS_MMAP_FD, 0); + if (res == MAP_FAILED) + return NULL; + return res; +#elif HAVE_VIRTUALALLOC + return (void *) VirtualAlloc(NULL, (SIZE_T) size, + MEM_COMMIT|MEM_RESERVE, PAGE_READWRITE); +#else +# error "missing mmap() or similar" +#endif +} + +static ERTS_INLINE void +os_munmap(void *ptr, UWord size) +{ +#if HAVE_MMAP +#ifdef ERTS_MMAP_DEBUG + int res = +#endif + munmap(ptr, size); + ERTS_MMAP_ASSERT(res == 0); +#elif HAVE_VIRTUALALLOC +#ifdef DEBUG + BOOL res = +#endif + VirtualFree((LPVOID) ptr, (SIZE_T) 0, MEM_RELEASE); + ERTS_MMAP_ASSERT(res != 0); +#else +# error "missing munmap() or similar" +#endif +} + +#ifdef ERTS_HAVE_OS_MREMAP +# if HAVE_MREMAP +# if defined(__NetBSD__) +# define ERTS_MREMAP_FLAGS (0) +# else +# define ERTS_MREMAP_FLAGS (MREMAP_MAYMOVE) +# endif +# endif +static ERTS_INLINE void * +os_mremap(void *ptr, UWord old_size, UWord new_size, int try_superalign) +{ + void *new_seg; +#if HAVE_MREMAP + new_seg = mremap(ptr, (size_t) old_size, +# if defined(__NetBSD__) + NULL, +# endif + (size_t) new_size, ERTS_MREMAP_FLAGS); + if (new_seg == (void *) MAP_FAILED) + return NULL; + return new_seg; +#else +# error "missing mremap() or similar" +#endif +} +#endif + +#ifdef ERTS_HAVE_OS_PHYSICAL_MEMORY_RESERVATION +#if HAVE_MMAP + +#define ERTS_MMAP_RESERVE_PROT (ERTS_MMAP_PROT) +#define ERTS_MMAP_RESERVE_FLAGS (ERTS_MMAP_FLAGS|MAP_FIXED) +#define ERTS_MMAP_UNRESERVE_PROT (PROT_NONE) +#define ERTS_MMAP_UNRESERVE_FLAGS (ERTS_MMAP_FLAGS|MAP_NORESERVE|MAP_FIXED) +#define ERTS_MMAP_VIRTUAL_PROT (PROT_NONE) +#define ERTS_MMAP_VIRTUAL_FLAGS (ERTS_MMAP_FLAGS|MAP_NORESERVE) + +static int +os_reserve_physical(char *ptr, UWord size) +{ + void *res = mmap((void *) ptr, (size_t) size, ERTS_MMAP_RESERVE_PROT, + ERTS_MMAP_RESERVE_FLAGS, ERTS_MMAP_FD, 0); + if (res == (void *) MAP_FAILED) + return 0; + return 1; +} + +static void +os_unreserve_physical(char *ptr, UWord size) +{ + void *res = mmap((void *) ptr, (size_t) size, ERTS_MMAP_UNRESERVE_PROT, + ERTS_MMAP_UNRESERVE_FLAGS, ERTS_MMAP_FD, 0); + if (res == (void *) MAP_FAILED) + erl_exit(ERTS_ABORT_EXIT, "Failed to unreserve memory"); +} + +static void * +os_mmap_virtual(char *ptr, UWord size) +{ + void *res = mmap((void *) ptr, (size_t) size, ERTS_MMAP_VIRTUAL_PROT, + ERTS_MMAP_VIRTUAL_FLAGS, ERTS_MMAP_FD, 0); + if (res == (void *) MAP_FAILED) + return NULL; + return res; +} + +#else +#error "Missing reserve/unreserve physical memory implementation" +#endif +#endif /* ERTS_HAVE_OS_RESERVE_PHYSICAL_MEMORY */ + +#endif /* ERTS_HAVE_OS_MMAP */ + +static int reserve_noop(char *ptr, UWord size) +{ +#ifdef ERTS_MMAP_DEBUG_FILL_AREAS + Uint32 *uip, *end = (Uint32 *) (ptr + size); + + for (uip = (Uint32 *) ptr; uip < end; uip++) + ERTS_MMAP_ASSERT(*uip == (Uint32) 0xdeadbeef); + for (uip = (Uint32 *) ptr; uip < end; uip++) + *uip = (Uint32) 0xfeedfeed; +#endif + return 1; +} + +static void unreserve_noop(char *ptr, UWord size) +{ +#ifdef ERTS_MMAP_DEBUG_FILL_AREAS + Uint32 *uip, *end = (Uint32 *) (ptr + size); + + for (uip = (Uint32 *) ptr; uip < end; uip++) + *uip = (Uint32) 0xdeadbeef; +#endif +} + +static UWord +alloc_desc_insert_free_seg(ErtsFreeSegMap *map, char* start, char* end) +{ + char *ptr; + ErtsFreeSegMap *da_map; + ErtsFreeSegDesc *desc = alloc_desc(); + if (desc) { + insert_free_seg(map, desc, start, end); + return 0; + } + + /* + * Ahh; ran out of free segment descriptors. + * + * First try to map a new page... + */ + +#if ERTS_HAVE_OS_MMAP + if (!mmap_state.no_os_mmap) { + ptr = os_mmap(mmap_state.desc.new_area_hint, ERTS_PAGEALIGNED_SIZE, 0); + if (ptr) { + mmap_state.desc.new_area_hint = ptr+ERTS_PAGEALIGNED_SIZE; + ERTS_MMAP_SIZE_OS_INC(ERTS_PAGEALIGNED_SIZE); + add_free_desc_area(ptr, ptr+ERTS_PAGEALIGNED_SIZE); + desc = alloc_desc(); + ERTS_MMAP_ASSERT(desc); + insert_free_seg(map, desc, start, end); + return 0; + } + } +#endif + + /* + * ...then try to find a good place in the supercarrier... + */ + da_map = &mmap_state.sua.map; + desc = lookup_free_seg(da_map, ERTS_PAGEALIGNED_SIZE); + if (desc) { + if (mmap_state.reserve_physical(desc->start, ERTS_PAGEALIGNED_SIZE)) + ERTS_MMAP_SIZE_SC_SUA_INC(ERTS_PAGEALIGNED_SIZE); + else + desc = NULL; + + } + else { + da_map = &mmap_state.sa.map; + desc = lookup_free_seg(da_map, ERTS_PAGEALIGNED_SIZE); + if (desc) { + if (mmap_state.reserve_physical(desc->start, ERTS_PAGEALIGNED_SIZE)) + ERTS_MMAP_SIZE_SC_SA_INC(ERTS_PAGEALIGNED_SIZE); + else + desc = NULL; + } + } + if (desc) { + char *da_end = desc->start + ERTS_PAGEALIGNED_SIZE; + add_free_desc_area(desc->start, da_end); + if (da_end != desc->end) + resize_free_seg(da_map, desc, da_end, desc->end); + else { + delete_free_seg(da_map, desc); + free_desc(desc); + } + + desc = alloc_desc(); + ERTS_MMAP_ASSERT(desc); + insert_free_seg(map, desc, start, end); + return 0; + } + + /* + * ... and then as last resort use the first page of the + * free segment we are trying to insert for free descriptors. + */ + ptr = start + ERTS_PAGEALIGNED_SIZE; + ERTS_MMAP_ASSERT(ptr <= end); + + add_free_desc_area(start, ptr); + + if (ptr != end) { + desc = alloc_desc(); + ERTS_MMAP_ASSERT(desc); + insert_free_seg(map, desc, ptr, end); + } + + return ERTS_PAGEALIGNED_SIZE; +} + +void * +erts_mmap(Uint32 flags, UWord *sizep) +{ + char *seg; + UWord asize = ERTS_PAGEALIGNED_CEILING(*sizep); + + /* Map in premapped supercarrier */ + if (mmap_state.supercarrier && !(ERTS_MMAPFLG_OS_ONLY & flags)) { + char *end; + ErtsFreeSegDesc *desc; + Uint32 superaligned = (ERTS_MMAPFLG_SUPERALIGNED & flags); + + erts_smp_mtx_lock(&mmap_state.mtx); + + ERTS_MMAP_OP_START(*sizep); + + if (!superaligned) { + desc = lookup_free_seg(&mmap_state.sua.map, asize); + if (desc) { + seg = desc->start; + end = seg+asize; + if (!mmap_state.reserve_physical(seg, asize)) + goto supercarrier_reserve_failure; + if (desc->end == end) { + delete_free_seg(&mmap_state.sua.map, desc); + free_desc(desc); + } + else { + ERTS_MMAP_ASSERT(end < desc->end); + resize_free_seg(&mmap_state.sua.map, desc, end, desc->end); + } + ERTS_MMAP_SIZE_SC_SUA_INC(asize); + goto supercarrier_success; + } + + if (asize <= mmap_state.sua.bot - mmap_state.sa.top) { + if (!mmap_state.reserve_physical(mmap_state.sua.bot - asize, + asize)) + goto supercarrier_reserve_failure; + mmap_state.sua.bot -= asize; + seg = mmap_state.sua.bot; + ERTS_MMAP_SIZE_SC_SUA_INC(asize); + goto supercarrier_success; + } + } + + asize = ERTS_SUPERALIGNED_CEILING(asize); + + desc = lookup_free_seg(&mmap_state.sa.map, asize); + if (desc) { + char *start = seg = desc->start; + seg = (char *) ERTS_SUPERALIGNED_CEILING(seg); + end = seg+asize; + if (!mmap_state.reserve_physical(start, (UWord) (end - start))) + goto supercarrier_reserve_failure; + ERTS_MMAP_SIZE_SC_SA_INC(asize); + if (desc->end == end) { + if (start != seg) + resize_free_seg(&mmap_state.sa.map, desc, start, seg); + else { + delete_free_seg(&mmap_state.sa.map, desc); + free_desc(desc); + } + } + else { + ERTS_MMAP_ASSERT(end < desc->end); + resize_free_seg(&mmap_state.sa.map, desc, end, desc->end); + if (start != seg) { + UWord ad_sz; + ad_sz = alloc_desc_insert_free_seg(&mmap_state.sua.map, + start, seg); + start += ad_sz; + if (start != seg) + mmap_state.unreserve_physical(start, (UWord) (seg - start)); + } + } + goto supercarrier_success; + } + + if (superaligned) { + char *start = mmap_state.sa.top; + seg = (char *) ERTS_SUPERALIGNED_CEILING(start); + + if (asize + (seg - start) <= mmap_state.sua.bot - start) { + end = seg + asize; + if (!mmap_state.reserve_physical(start, (UWord) (end - start))) + goto supercarrier_reserve_failure; + mmap_state.sa.top = end; + ERTS_MMAP_SIZE_SC_SA_INC(asize); + if (start != seg) { + UWord ad_sz; + ad_sz = alloc_desc_insert_free_seg(&mmap_state.sua.map, + start, seg); + start += ad_sz; + if (start != seg) + mmap_state.unreserve_physical(start, (UWord) (seg - start)); + } + goto supercarrier_success; + } + + desc = lookup_free_seg(&mmap_state.sua.map, asize + ERTS_SUPERALIGNED_SIZE); + if (desc) { + char *org_start = desc->start; + char *org_end = desc->end; + + seg = (char *) ERTS_SUPERALIGNED_CEILING(org_start); + end = seg + asize; + if (!mmap_state.reserve_physical(seg, (UWord) (org_end - seg))) + goto supercarrier_reserve_failure; + ERTS_MMAP_SIZE_SC_SUA_INC(asize); + if (org_start != seg) { + ERTS_MMAP_ASSERT(org_start < seg); + resize_free_seg(&mmap_state.sua.map, desc, org_start, seg); + desc = NULL; + } + if (end != org_end) { + UWord ad_sz = 0; + ERTS_MMAP_ASSERT(end < org_end); + if (desc) + resize_free_seg(&mmap_state.sua.map, desc, end, org_end); + else + ad_sz = alloc_desc_insert_free_seg(&mmap_state.sua.map, + end, org_end); + end += ad_sz; + if (end != org_end) + mmap_state.unreserve_physical(end, + (UWord) (org_end - end)); + } + goto supercarrier_success; + } + } + + ERTS_MMAP_OP_ABORT(); + erts_smp_mtx_unlock(&mmap_state.mtx); + } + +#if ERTS_HAVE_OS_MMAP + /* Map using OS primitives */ + if (!(ERTS_MMAPFLG_SUPERCARRIER_ONLY & flags) && !mmap_state.no_os_mmap) { + if (!(ERTS_MMAPFLG_SUPERALIGNED & flags)) { + seg = os_mmap(NULL, asize, 0); + if (!seg) + goto failure; + } + else { + asize = ERTS_SUPERALIGNED_CEILING(*sizep); + seg = os_mmap(NULL, asize, 1); + if (!seg) + goto failure; + + if (!ERTS_IS_SUPERALIGNED(seg)) { + char *ptr; + UWord sz; + + os_munmap(seg, asize); + + ptr = os_mmap(NULL, asize + ERTS_SUPERALIGNED_SIZE, 1); + if (!ptr) + goto failure; + + seg = (char *) ERTS_SUPERALIGNED_CEILING(ptr); + sz = (UWord) (seg - ptr); + ERTS_MMAP_ASSERT(sz <= ERTS_SUPERALIGNED_SIZE); + if (sz) + os_munmap(ptr, sz); + sz = ERTS_SUPERALIGNED_SIZE - sz; + if (sz) + os_munmap(seg+asize, sz); + } + } + + ERTS_MMAP_OP_LCK(seg, *sizep, asize); + ERTS_MMAP_SIZE_OS_INC(asize); + *sizep = asize; + return (void *) seg; + } +failure: +#endif + ERTS_MMAP_OP_LCK(NULL, *sizep, 0); + *sizep = 0; + return NULL; + +supercarrier_success: + +#ifdef ERTS_MMAP_DEBUG + if (ERTS_MMAPFLG_SUPERALIGNED & flags) { + ERTS_MMAP_ASSERT(ERTS_IS_SUPERALIGNED(seg)); + ERTS_MMAP_ASSERT(ERTS_IS_SUPERALIGNED(asize)); + } + else { + ERTS_MMAP_ASSERT(ERTS_IS_PAGEALIGNED(seg)); + ERTS_MMAP_ASSERT(ERTS_IS_PAGEALIGNED(asize)); + } +#endif + + ERTS_MMAP_OP_END(seg, asize); + erts_smp_mtx_unlock(&mmap_state.mtx); + + *sizep = asize; + return (void *) seg; + +supercarrier_reserve_failure: + erts_smp_mtx_unlock(&mmap_state.mtx); + *sizep = 0; + return NULL; +} + +void +erts_munmap(Uint32 flags, void *ptr, UWord size) +{ + ERTS_MMAP_ASSERT(ERTS_IS_PAGEALIGNED(ptr)); + ERTS_MMAP_ASSERT(ERTS_IS_PAGEALIGNED(size)); + + if (!ERTS_MMAP_IN_SUPERCARRIER(ptr)) { + ERTS_MMAP_ASSERT(!mmap_state.no_os_mmap); +#if ERTS_HAVE_OS_MMAP + ERTS_MUNMAP_OP_LCK(ptr, size); + ERTS_MMAP_SIZE_OS_DEC(size); + os_munmap(ptr, size); +#endif + } + else { + char *start, *end; + ErtsFreeSegMap *map; + ErtsFreeSegDesc *prev, *next, *desc; + UWord ad_sz = 0; + + ERTS_MMAP_ASSERT(mmap_state.supercarrier); + + start = (char *) ptr; + end = start + size; + + erts_smp_mtx_lock(&mmap_state.mtx); + + ERTS_MUNMAP_OP(ptr, size); + + if (ERTS_MMAP_IN_SUPERALIGNED_AREA(ptr)) { + + map = &mmap_state.sa.map; + adjacent_free_seg(map, start, end, &prev, &next); + + ERTS_MMAP_SIZE_SC_SA_DEC(size); + if (end == mmap_state.sa.top) { + ERTS_MMAP_ASSERT(!next); + if (prev) { + start = prev->start; + delete_free_seg(map, prev); + free_desc(prev); + } + mmap_state.sa.top = start; + goto supercarrier_success; + } + } + else { + map = &mmap_state.sua.map; + adjacent_free_seg(map, start, end, &prev, &next); + + ERTS_MMAP_SIZE_SC_SUA_DEC(size); + if (start == mmap_state.sua.bot) { + ERTS_MMAP_ASSERT(!prev); + if (next) { + end = next->end; + delete_free_seg(map, next); + free_desc(next); + } + mmap_state.sua.bot = end; + goto supercarrier_success; + } + } + + desc = NULL; + + if (next) { + ERTS_MMAP_ASSERT(end < next->end); + end = next->end; + if (prev) { + delete_free_seg(map, next); + free_desc(next); + goto save_prev; + } + desc = next; + } else if (prev) { + save_prev: + ERTS_MMAP_ASSERT(prev->start < start); + start = prev->start; + desc = prev; + } + + if (desc) + resize_free_seg(map, desc, start, end); + else + ad_sz = alloc_desc_insert_free_seg(map, start, end); + + supercarrier_success: { + UWord unres_sz; + + ERTS_MMAP_ASSERT(size >= ad_sz); + unres_sz = size - ad_sz; + if (unres_sz) + mmap_state.unreserve_physical(((char *) ptr) + ad_sz, unres_sz); + + erts_smp_mtx_unlock(&mmap_state.mtx); + } + } +} + +static void * +remap_move(Uint32 flags, void *ptr, UWord old_size, UWord *sizep) +{ + UWord size = *sizep; + void *new_ptr = erts_mmap(flags, &size); + if (!new_ptr) + return NULL; + *sizep = size; + if (old_size < size) + size = old_size; + sys_memcpy(new_ptr, ptr, (size_t) size); + erts_munmap(flags, ptr, old_size); + return new_ptr; +} + +void * +erts_mremap(Uint32 flags, void *ptr, UWord old_size, UWord *sizep) +{ + void *new_ptr; + Uint32 superaligned; + UWord asize; + + ERTS_MMAP_ASSERT(ERTS_IS_PAGEALIGNED(ptr)); + ERTS_MMAP_ASSERT(ERTS_IS_PAGEALIGNED(old_size)); + ERTS_MMAP_ASSERT(sizep && ERTS_IS_PAGEALIGNED(*sizep)); + + if (!ERTS_MMAP_IN_SUPERCARRIER(ptr)) { + + ERTS_MMAP_ASSERT(!mmap_state.no_os_mmap); + + if (!(ERTS_MMAPFLG_OS_ONLY & flags) && mmap_state.supercarrier) { + new_ptr = remap_move(ERTS_MMAPFLG_SUPERCARRIER_ONLY|flags, ptr, + old_size, sizep); + if (new_ptr) + return new_ptr; + } + + if (ERTS_MMAPFLG_SUPERCARRIER_ONLY & flags) { + ERTS_MREMAP_OP_LCK(NULL, ptr, old_size, *sizep, old_size); + return NULL; + } + +#if ERTS_HAVE_OS_MREMAP || ERTS_HAVE_GENUINE_OS_MMAP + superaligned = (ERTS_MMAPFLG_SUPERALIGNED & flags); + + if (superaligned) { + asize = ERTS_SUPERALIGNED_CEILING(*sizep); + if (asize == old_size && ERTS_IS_SUPERALIGNED(ptr)) { + ERTS_MREMAP_OP_LCK(ptr, ptr, old_size, *sizep, asize); + *sizep = asize; + return ptr; + } + } + else { + asize = ERTS_PAGEALIGNED_CEILING(*sizep); + if (asize == old_size) { + ERTS_MREMAP_OP_LCK(ptr, ptr, old_size, *sizep, asize); + *sizep = asize; + return ptr; + } + } + +#if ERTS_HAVE_GENUINE_OS_MMAP + if (asize < old_size + && (!superaligned + || ERTS_IS_SUPERALIGNED(ptr))) { + UWord um_sz; + new_ptr = ((char *) ptr) + asize; + ERTS_MMAP_ASSERT((((char *)ptr) + old_size) > (char *) new_ptr); + um_sz = (UWord) ((((char *) ptr) + old_size) - (char *) new_ptr); + ERTS_MMAP_SIZE_OS_DEC(um_sz); + os_munmap(new_ptr, um_sz); + ERTS_MREMAP_OP_LCK(ptr, ptr, old_size, *sizep, asize); + *sizep = asize; + return ptr; + } +#endif +#if ERTS_HAVE_OS_MREMAP + if (superaligned) + return remap_move(flags, new_ptr, old_size, sizep); + else { + new_ptr = os_mremap(ptr, old_size, asize, 0); + if (!new_ptr) + return NULL; + if (asize > old_size) + ERTS_MMAP_SIZE_OS_INC(asize - old_size); + else + ERTS_MMAP_SIZE_OS_DEC(old_size - asize); + ERTS_MREMAP_OP_LCK(new_ptr, ptr, old_size, *sizep, asize); + *sizep = asize; + return new_ptr; + } +#endif +#endif + } + else { /* In super carrier */ + char *start, *end, *new_end; + ErtsFreeSegMap *map; + ErtsFreeSegDesc *prev, *next; + UWord ad_sz = 0; + + ERTS_MMAP_ASSERT(mmap_state.supercarrier); + + if (ERTS_MMAPFLG_OS_ONLY & flags) + return remap_move(flags, ptr, old_size, sizep); + + superaligned = (ERTS_MMAPFLG_SUPERALIGNED & flags); + + asize = (superaligned + ? ERTS_SUPERALIGNED_CEILING(*sizep) + : ERTS_PAGEALIGNED_CEILING(*sizep)); + + erts_smp_mtx_lock(&mmap_state.mtx); + + if (ERTS_MMAP_IN_SUPERALIGNED_AREA(ptr) + ? (!superaligned && lookup_free_seg(&mmap_state.sua.map, asize)) + : (superaligned && lookup_free_seg(&mmap_state.sa.map, asize))) { + erts_smp_mtx_unlock(&mmap_state.mtx); + /* + * Segment currently in wrong area (due to a previous memory + * shortage), move it to the right area. + * (remap_move() will succeed) + */ + return remap_move(ERTS_MMAPFLG_SUPERCARRIER_ONLY|flags, ptr, + old_size, sizep); + } + + ERTS_MREMAP_OP_START(ptr, old_size, *sizep); + + if (asize == old_size) { + new_ptr = ptr; + goto supercarrier_resize_success; + } + + start = (char *) ptr; + end = start + old_size; + new_end = start+asize; + + ERTS_MMAP_ASSERT(ERTS_IS_PAGEALIGNED(ptr)); + ERTS_MMAP_ASSERT(ERTS_IS_PAGEALIGNED(old_size)); + ERTS_MMAP_ASSERT(ERTS_IS_PAGEALIGNED(asize)); + + if (asize < old_size) { + UWord unres_sz; + new_ptr = ptr; + if (!ERTS_MMAP_IN_SUPERALIGNED_AREA(ptr)) { + map = &mmap_state.sua.map; + ERTS_MMAP_SIZE_SC_SUA_DEC(old_size - asize); + } + else { + if (end == mmap_state.sa.top) { + mmap_state.sa.top = new_end; + mmap_state.unreserve_physical(((char *) ptr) + asize, + old_size - asize); + goto supercarrier_resize_success; + } + ERTS_MMAP_SIZE_SC_SA_DEC(old_size - asize); + map = &mmap_state.sa.map; + } + + adjacent_free_seg(map, start, end, &prev, &next); + + if (next) + resize_free_seg(map, next, new_end, next->end); + else + ad_sz = alloc_desc_insert_free_seg(map, new_end, end); + ERTS_MMAP_ASSERT(old_size - asize >= ad_sz); + unres_sz = old_size - asize - ad_sz; + if (unres_sz) + mmap_state.unreserve_physical(((char *) ptr) + asize + ad_sz, + unres_sz); + goto supercarrier_resize_success; + } + + if (!ERTS_MMAP_IN_SUPERALIGNED_AREA(ptr)) { + ERTS_MMAP_ASSERT(ERTS_IS_PAGEALIGNED(ptr)); + ERTS_MMAP_ASSERT(ERTS_IS_PAGEALIGNED(old_size)); + ERTS_MMAP_ASSERT(ERTS_IS_PAGEALIGNED(asize)); + + adjacent_free_seg(&mmap_state.sua.map, start, end, &prev, &next); + + if (next && new_end <= next->end) { + if (!mmap_state.reserve_physical(((char *) ptr) + old_size, + asize - old_size)) + goto supercarrier_reserve_failure; + if (new_end < next->end) + resize_free_seg(&mmap_state.sua.map, next, new_end, next->end); + else { + delete_free_seg(&mmap_state.sua.map, next); + free_desc(next); + } + new_ptr = ptr; + ERTS_MMAP_SIZE_SC_SUA_INC(asize - old_size); + goto supercarrier_resize_success; + } + } + else { /* Superaligned area */ + + if (end == mmap_state.sa.top) { + if (new_end <= mmap_state.sua.bot) { + if (!mmap_state.reserve_physical(((char *) ptr) + old_size, + asize - old_size)) + goto supercarrier_reserve_failure; + mmap_state.sa.top = new_end; + new_ptr = ptr; + ERTS_MMAP_SIZE_SC_SA_INC(asize - old_size); + goto supercarrier_resize_success; + } + } + else { + adjacent_free_seg(&mmap_state.sa.map, start, end, &prev, &next); + if (next && new_end <= next->end) { + if (!mmap_state.reserve_physical(((char *) ptr) + old_size, + asize - old_size)) + goto supercarrier_reserve_failure; + if (new_end < next->end) + resize_free_seg(&mmap_state.sa.map, next, new_end, next->end); + else { + delete_free_seg(&mmap_state.sa.map, next); + free_desc(next); + } + new_ptr = ptr; + ERTS_MMAP_SIZE_SC_SA_INC(asize - old_size); + goto supercarrier_resize_success; + } + } + } + + ERTS_MMAP_OP_ABORT(); + erts_smp_mtx_unlock(&mmap_state.mtx); + + /* Failed to resize... */ + } + + return remap_move(flags, ptr, old_size, sizep); + +supercarrier_resize_success: + +#ifdef ERTS_MMAP_DEBUG + if ((ERTS_MMAPFLG_SUPERALIGNED & flags) + || ERTS_MMAP_IN_SUPERALIGNED_AREA(new_ptr)) { + ERTS_MMAP_ASSERT(ERTS_IS_SUPERALIGNED(new_ptr)); + ERTS_MMAP_ASSERT(ERTS_IS_SUPERALIGNED(asize)); + } + else { + ERTS_MMAP_ASSERT(ERTS_IS_PAGEALIGNED(new_ptr)); + ERTS_MMAP_ASSERT(ERTS_IS_PAGEALIGNED(asize)); + } +#endif + + ERTS_MREMAP_OP_END(new_ptr, asize); + erts_smp_mtx_unlock(&mmap_state.mtx); + + *sizep = asize; + return new_ptr; + +supercarrier_reserve_failure: + ERTS_MREMAP_OP_END(NULL, old_size); + erts_smp_mtx_unlock(&mmap_state.mtx); + *sizep = old_size; + return NULL; + +} + +int erts_mmap_in_supercarrier(void *ptr) +{ + return ERTS_MMAP_IN_SUPERCARRIER(ptr); +} + + +static struct { + Eterm total; + Eterm total_sa; + Eterm total_sua; + Eterm used; + Eterm used_sa; + Eterm used_sua; + Eterm max; + Eterm allocated; + Eterm reserved; + Eterm sizes; + Eterm free_segs; + Eterm supercarrier; + Eterm os; + Eterm scs; + Eterm sco; + Eterm scrpm; + Eterm scmgc; + + int is_initialized; + erts_mtx_t init_mutex; +}am; + +static void ERTS_INLINE atom_init(Eterm *atom, char *name) +{ + *atom = am_atom_put(name, strlen(name)); +} +#define AM_INIT(AM) atom_init(&am.AM, #AM) + +static void init_atoms(void) +{ + erts_mtx_lock(&am.init_mutex); + + if (!am.is_initialized) { + AM_INIT(total); + AM_INIT(total_sa); + AM_INIT(total_sua); + AM_INIT(used); + AM_INIT(used_sa); + AM_INIT(used_sua); + AM_INIT(max); + AM_INIT(allocated); + AM_INIT(reserved); + AM_INIT(sizes); + AM_INIT(free_segs); + AM_INIT(supercarrier); + AM_INIT(os); + AM_INIT(scs); + AM_INIT(sco); + AM_INIT(scrpm); + AM_INIT(scmgc); + am.is_initialized = 1; + } + erts_mtx_unlock(&am.init_mutex); +}; + + +#ifdef HARD_DEBUG_MSEG +static void hard_dbg_mseg_init(void); +#endif + +void +erts_mmap_init(ErtsMMapInit *init) +{ + int virtual_map = 0; + char *start = NULL, *end = NULL; + UWord pagesize; +#if defined(__WIN32__) + SYSTEM_INFO sysinfo; + GetSystemInfo(&sysinfo); + pagesize = (UWord) sysinfo.dwPageSize; +#elif defined(_SC_PAGESIZE) + pagesize = (UWord) sysconf(_SC_PAGESIZE); +#elif defined(HAVE_GETPAGESIZE) + pagesize = (UWord) getpagesize(); +#else +# error "Do not know how to get page size" +#endif +#if defined(HARD_DEBUG) || 0 + erts_fprintf(stderr, "erts_mmap: scs = %bpu\n", init->scs); + erts_fprintf(stderr, "erts_mmap: sco = %i\n", init->sco); + erts_fprintf(stderr, "erts_mmap: scmgc = %i\n", init->scmgc); +#endif + erts_page_inv_mask = pagesize - 1; + if (pagesize & erts_page_inv_mask) + erl_exit(-1, "erts_mmap: Invalid pagesize: %bpu\n", + pagesize); + + ERTS_MMAP_OP_RINGBUF_INIT(); + + erts_have_erts_mmap = 0; + + mmap_state.supercarrier = 0; + mmap_state.reserve_physical = reserve_noop; + mmap_state.unreserve_physical = unreserve_noop; + +#if HAVE_MMAP && !defined(MAP_ANON) + mmap_state.mmap_fd = open("/dev/zero", O_RDWR); + if (mmap_state.mmap_fd < 0) + erl_exit(-1, "erts_mmap: Failed to open /dev/zero\n"); +#endif + + erts_smp_mtx_init(&mmap_state.mtx, "erts_mmap"); + erts_mtx_init(&am.init_mutex, "mmap_init_atoms"); + +#ifdef ERTS_HAVE_OS_PHYSICAL_MEMORY_RESERVATION + if (init->virtual_range.start) { + char *ptr; + UWord sz; + ptr = (char *) ERTS_PAGEALIGNED_CEILING(init->virtual_range.start); + end = (char *) ERTS_PAGEALIGNED_FLOOR(init->virtual_range.end); + sz = end - ptr; + start = os_mmap_virtual(ptr, sz); + if (!start || start > ptr || start >= end) + erl_exit(-1, + "erts_mmap: Failed to create virtual range for super carrier\n"); + sz = start - ptr; + if (sz) + os_munmap(end, sz); + mmap_state.reserve_physical = os_reserve_physical; + mmap_state.unreserve_physical = os_unreserve_physical; + virtual_map = 1; + } + else +#endif + if (init->predefined_area.start) { + start = init->predefined_area.start; + end = init->predefined_area.end; + if (end != (void *) 0 && end < start) + end = start; + } +#if ERTS_HAVE_OS_MMAP + else if (init->scs) { + UWord sz; + sz = ERTS_PAGEALIGNED_CEILING(init->scs); +#ifdef ERTS_HAVE_OS_PHYSICAL_MEMORY_RESERVATION + if (!init->scrpm) { + start = os_mmap_virtual(NULL, sz); + mmap_state.reserve_physical = os_reserve_physical; + mmap_state.unreserve_physical = os_unreserve_physical; + virtual_map = 1; + } + else +#endif + { + /* + * The whole supercarrier will by physically + * reserved all the time. + */ + start = os_mmap(NULL, sz, 1); + } + if (!start) + erl_exit(-1, + "erts_mmap: Failed to create super carrier of size %bpu MB\n", + init->scs/1024/1024); + end = start + sz; +#ifdef ERTS_MMAP_DEBUG_FILL_AREAS + if (!virtual_map) { + Uint32 *uip; + + for (uip = (Uint32 *) start; uip < (Uint32 *) end; uip++) + *uip = (Uint32) 0xdeadbeef; + } +#endif + } + if (!mmap_state.no_os_mmap) + erts_have_erts_mmap |= ERTS_HAVE_ERTS_OS_MMAP; +#endif + + mmap_state.no.free_seg_descs = 0; + mmap_state.no.free_segs.curr = 0; + mmap_state.no.free_segs.max = 0; + + mmap_state.size.supercarrier.total = 0; + mmap_state.size.supercarrier.used.total = 0; + mmap_state.size.supercarrier.used.sa = 0; + mmap_state.size.supercarrier.used.sua = 0; + mmap_state.size.os.used = 0; + + mmap_state.desc.new_area_hint = NULL; + + if (!start) { + mmap_state.sa.bot = NULL; + mmap_state.sua.top = NULL; + mmap_state.sa.bot = NULL; + mmap_state.sua.top = NULL; + mmap_state.no_os_mmap = 0; + mmap_state.supercarrier = 0; + } + else { + size_t desc_size; + + mmap_state.no_os_mmap = init->sco; + + desc_size = init->scmgc; + if (desc_size < 100) + desc_size = 100; + desc_size *= sizeof(ErtsFreeSegDesc); + if ((desc_size + + ERTS_SUPERALIGNED_SIZE + + ERTS_PAGEALIGNED_SIZE) > end - start) + erl_exit(-1, "erts_mmap: No space for segments in super carrier\n"); + + mmap_state.sa.bot = start; + mmap_state.sa.bot += desc_size; + mmap_state.sa.bot = (char *) ERTS_SUPERALIGNED_CEILING(mmap_state.sa.bot); + mmap_state.sa.top = mmap_state.sa.bot; + mmap_state.sua.top = end; + mmap_state.sua.bot = mmap_state.sua.top; + + mmap_state.size.supercarrier.used.total += (UWord) (mmap_state.sa.bot - start); + + mmap_state.desc.free_list = NULL; + mmap_state.desc.reserved = 0; + + if (end == (void *) 0) { + /* + * Very unlikely, but we need a guarantee + * that `mmap_state.sua.top` always will + * compare as larger than all segment pointers + * into the super carrier... + */ + mmap_state.sua.top -= ERTS_PAGEALIGNED_SIZE; + mmap_state.size.supercarrier.used.total += ERTS_PAGEALIGNED_SIZE; +#ifdef ERTS_HAVE_OS_PHYSICAL_MEMORY_RESERVATION + if (!virtual_map || os_reserve_physical(mmap_state.sua.top, ERTS_PAGEALIGNED_SIZE)) +#endif + add_free_desc_area(mmap_state.sua.top, end); + mmap_state.desc.reserved += (end - mmap_state.sua.top) / sizeof(ErtsFreeSegDesc); + } + + mmap_state.size.supercarrier.total = (UWord) (mmap_state.sua.top - start); + + /* + * Area before (and after) super carrier + * will be used for free segment descritors. + */ +#ifdef ERTS_HAVE_OS_PHYSICAL_MEMORY_RESERVATION + if (virtual_map && !os_reserve_physical(start, mmap_state.sa.bot - start)) + erl_exit(-1, "erts_mmap: Failed to reserve physical memory for descriptors\n"); +#endif + mmap_state.desc.unused_start = start; + mmap_state.desc.unused_end = mmap_state.sa.bot; + mmap_state.desc.reserved += ((mmap_state.desc.unused_end - start) + / sizeof(ErtsFreeSegDesc)); + + init_free_seg_map(&mmap_state.sa.map, SA_SZ_ADDR_ORDER); + init_free_seg_map(&mmap_state.sua.map, SZ_REVERSE_ADDR_ORDER); + + mmap_state.supercarrier = 1; + erts_have_erts_mmap |= ERTS_HAVE_ERTS_SUPERCARRIER_MMAP; + + mmap_state.desc.new_area_hint = end; + + } + +#if !ERTS_HAVE_OS_MMAP + mmap_state.no_os_mmap = 1; +#endif + +#ifdef HARD_DEBUG_MSEG + hard_dbg_mseg_init(); +#endif +} + + +static ERTS_INLINE void +add_2tup(Uint **hpp, Uint *szp, Eterm *lp, Eterm el1, Eterm el2) +{ + *lp = erts_bld_cons(hpp, szp, erts_bld_tuple(hpp, szp, 2, el1, el2), *lp); +} + +Eterm erts_mmap_info(int *print_to_p, + void *print_to_arg, + Eterm** hpp, Uint* szp, + struct erts_mmap_info_struct* emis) +{ + Eterm size_tags[] = { am.total, am.total_sa, am.total_sua, am.used, am.used_sa, am.used_sua }; + Eterm seg_tags[] = { am.used, am.max, am.allocated, am.reserved, am.used_sa, am.used_sua }; + Eterm group[2]; + Eterm group_tags[] = { am.sizes, am.free_segs }; + Eterm list[2]; + Eterm list_tags[2]; /* { am.supercarrier, am.os } */ + int lix; + Eterm res = THE_NON_VALUE; + + if (!hpp) { + erts_smp_mtx_lock(&mmap_state.mtx); + emis->sizes[0] = mmap_state.size.supercarrier.total; + emis->sizes[1] = mmap_state.sa.top - mmap_state.sa.bot; + emis->sizes[2] = mmap_state.sua.top - mmap_state.sua.bot; + emis->sizes[3] = mmap_state.size.supercarrier.used.total; + emis->sizes[4] = mmap_state.size.supercarrier.used.sa; + emis->sizes[5] = mmap_state.size.supercarrier.used.sua; + + emis->segs[0] = mmap_state.no.free_segs.curr; + emis->segs[1] = mmap_state.no.free_segs.max; + emis->segs[2] = mmap_state.no.free_seg_descs; + emis->segs[3] = mmap_state.desc.reserved; + emis->segs[4] = mmap_state.sa.map.nseg; + emis->segs[5] = mmap_state.sua.map.nseg; + + emis->os_used = mmap_state.size.os.used; + erts_smp_mtx_unlock(&mmap_state.mtx); + } + + if (print_to_p) { + int to = *print_to_p; + void *arg = print_to_arg; + if (mmap_state.supercarrier) { + const char* prefix = "supercarrier "; + erts_print(to, arg, "%stotal size: %bpu\n", prefix, emis->sizes[0]); + erts_print(to, arg, "%stotal sa size: %bpu\n", prefix, emis->sizes[1]); + erts_print(to, arg, "%stotal sua size: %bpu\n", prefix, emis->sizes[2]); + erts_print(to, arg, "%sused size: %bpu\n", prefix, emis->sizes[3]); + erts_print(to, arg, "%sused sa size: %bpu\n", prefix, emis->sizes[4]); + erts_print(to, arg, "%sused sua size: %bpu\n", prefix, emis->sizes[5]); + erts_print(to, arg, "%sused free segs: %bpu\n", prefix, emis->segs[0]); + erts_print(to, arg, "%smax free segs: %bpu\n", prefix, emis->segs[1]); + erts_print(to, arg, "%sallocated free segs: %bpu\n", prefix, emis->segs[2]); + erts_print(to, arg, "%sreserved free segs: %bpu\n", prefix, emis->segs[3]); + erts_print(to, arg, "%ssa free segs: %bpu\n", prefix, emis->segs[4]); + erts_print(to, arg, "%ssua free segs: %bpu\n", prefix, emis->segs[5]); + } + if (!mmap_state.no_os_mmap) { + erts_print(to, arg, "os mmap size used: %bpu\n", emis->os_used); + } + } + + + if (hpp || szp) { + if (!am.is_initialized) { + init_atoms(); + } + + lix = 0; + if (mmap_state.supercarrier) { + group[0] = erts_bld_atom_uword_2tup_list(hpp, szp, + sizeof(size_tags)/sizeof(Eterm), + size_tags, emis->sizes); + group[1] = erts_bld_atom_uword_2tup_list(hpp, szp, + sizeof(seg_tags)/sizeof(Eterm), + seg_tags, emis->segs); + list[lix] = erts_bld_2tup_list(hpp, szp, 2, group_tags, group); + list_tags[lix] = am.supercarrier; + lix++; + } + + if (!mmap_state.no_os_mmap) { + group[0] = erts_bld_atom_uword_2tup_list(hpp, szp, + 1, &am.used, &emis->os_used); + list[lix] = erts_bld_2tup_list(hpp, szp, 1, group_tags, group); + list_tags[lix] = am.os; + lix++; + } + res = erts_bld_2tup_list(hpp, szp, lix, list_tags, list); + } + return res; +} + +Eterm erts_mmap_info_options(char *prefix, + int *print_to_p, + void *print_to_arg, + Uint **hpp, + Uint *szp) +{ + const UWord scs = mmap_state.sua.top - mmap_state.sa.bot; + const Eterm sco = mmap_state.no_os_mmap ? am_true : am_false; + const Eterm scrpm = (mmap_state.reserve_physical == reserve_noop) ? am_true : am_false; + Eterm res = THE_NON_VALUE; + + if (print_to_p) { + int to = *print_to_p; + void *arg = print_to_arg; + erts_print(to, arg, "%sscs: %bpu\n", prefix, scs); + if (mmap_state.supercarrier) { + erts_print(to, arg, "%ssco: %T\n", prefix, sco); + erts_print(to, arg, "%sscrpm: %T\n", prefix, scrpm); + erts_print(to, arg, "%sscmgc: %beu\n", prefix, mmap_state.desc.reserved); + } + } + + if (hpp || szp) { + if (!am.is_initialized) { + init_atoms(); + } + + res = NIL; + if (mmap_state.supercarrier) { + add_2tup(hpp, szp, &res, am.scmgc, + erts_bld_uint(hpp,szp, mmap_state.desc.reserved)); + add_2tup(hpp, szp, &res, am.scrpm, scrpm); + add_2tup(hpp, szp, &res, am.sco, sco); + } + add_2tup(hpp, szp, &res, am.scs, erts_bld_uword(hpp, szp, scs)); + } + return res; +} + + +Eterm erts_mmap_debug_info(Process* p) +{ + if (mmap_state.supercarrier) { + ERTS_DECL_AM(sabot); + ERTS_DECL_AM(satop); + ERTS_DECL_AM(suabot); + ERTS_DECL_AM(suatop); + Eterm sa_list, sua_list, list; + Eterm tags[] = { AM_sabot, AM_satop, AM_suabot, AM_suatop }; + UWord values[4]; + Eterm *hp, *hp_end; + Uint may_need; + const Uint PTR_BIG_SZ = HALFWORD_HEAP ? 3 : 2; + + erts_smp_mtx_lock(&mmap_state.mtx); + values[0] = (UWord)mmap_state.sa.bot; + values[1] = (UWord)mmap_state.sa.top; + values[2] = (UWord)mmap_state.sua.bot; + values[3] = (UWord)mmap_state.sua.top; + sa_list = build_free_seg_list(p, &mmap_state.sa.map); + sua_list = build_free_seg_list(p, &mmap_state.sua.map); + erts_smp_mtx_unlock(&mmap_state.mtx); + + may_need = 4*(2+3+PTR_BIG_SZ) + 2*(2+3); + hp = HAlloc(p, may_need); + hp_end = hp + may_need; + + list = erts_bld_atom_uword_2tup_list(&hp, NULL, + sizeof(values)/sizeof(*values), + tags, values); + + sa_list = TUPLE2(hp, am_atom_put("sa_free_segs",12), sa_list); hp+=3; + sua_list = TUPLE2(hp, am_atom_put("sua_free_segs",13), sua_list); hp+=3; + list = CONS(hp, sua_list, list); hp+=2; + list = CONS(hp, sa_list, list); hp+=2; + + ASSERT(hp <= hp_end); + HRelease(p, hp_end, hp); + return list; + } + else { + return am_undefined; + } +} + + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\ + * Debug functions * +\* */ + + +#ifdef HARD_DEBUG + +static int rbt_assert_is_member(RBTNode* root, RBTNode* node) +{ + while (node != root) { + RBT_ASSERT(parent(node)); + RBT_ASSERT(parent(node)->left == node || parent(node)->right == node); + node = parent(node); + } + return 1; +} + + +#if 0 +# define PRINT_TREE +#else +# undef PRINT_TREE +#endif + +#ifdef PRINT_TREE +static void print_tree(enum SortOrder order, RBTNode*); +#endif + +/* + * Checks that the order between parent and children are correct, + * and that the Red-Black Tree properies are satisfied. if size > 0, + * check_tree() returns the node that satisfies "address order first fit" + * + * The Red-Black Tree properies are: + * 1. Every node is either red or black. + * 2. Every leaf (NIL) is black. + * 3. If a node is red, then both its children are black. + * 4. Every simple path from a node to a descendant leaf + * contains the same number of black nodes. + * + */ + +struct check_arg_t { + RBTree* tree; + ErtsFreeSegDesc* prev_seg; + Uint size; + RBTNode *res; +}; +static void check_node_callback(RBTNode* x, void* arg); + + +static RBTNode * +check_tree(RBTree* tree, Uint size) +{ + struct check_arg_t carg; + carg.tree = tree; + carg.prev_seg = NULL; + carg.size = size; + carg.res = NULL; + +#ifdef PRINT_TREE + print_tree(tree->order, tree->root); +#endif + + if (!tree->root) + return NULL; + + RBT_ASSERT(IS_BLACK(tree->root)); + RBT_ASSERT(!parent(tree->root)); + + rbt_foreach_node(tree, check_node_callback, &carg, 0); + + return carg.res; +} + +static void check_node_callback(RBTNode* x, void* arg) +{ + struct check_arg_t* a = (struct check_arg_t*) arg; + ErtsFreeSegDesc* seg; + + if (IS_RED(x)) { + RBT_ASSERT(IS_BLACK(x->right)); + RBT_ASSERT(IS_BLACK(x->left)); + } + + RBT_ASSERT(parent(x) || x == a->tree->root); + + if (x->left) { + RBT_ASSERT(cmp_nodes(a->tree->order, x->left, x) < 0); + } + if (x->right) { + RBT_ASSERT(cmp_nodes(a->tree->order, x->right, x) > 0); + } + + seg = node_to_desc(a->tree->order, x); + RBT_ASSERT(seg->start < seg->end); + if (a->size && (seg->end - seg->start) >= a->size) { + if (!a->res || cmp_nodes(a->tree->order, x, a->res) < 0) { + a->res = x; + } + } + if (a->tree->order == ADDR_ORDER) { + RBT_ASSERT(!a->prev_seg || a->prev_seg->end < seg->start); + a->prev_seg = seg; + } +} + +#endif /* HARD_DEBUG */ + + +#ifdef PRINT_TREE +#define INDENT_STEP 2 + +#include <stdio.h> + +static void +print_tree_aux(enum SortOrder order, RBTNode *x, int indent) +{ + int i; + + if (x) { + ErtsFreeSegDesc* desc = node_to_desc(order, x); + print_tree_aux(order, x->right, indent + INDENT_STEP); + for (i = 0; i < indent; i++) { + putc(' ', stderr); + } + fprintf(stderr, "%s: sz=%lx [%p - %p] desc=%p\r\n", + IS_BLACK(x) ? "BLACK" : "RED", + desc->end - desc->start, desc->start, desc->end, desc); + print_tree_aux(order, x->left, indent + INDENT_STEP); + } +} + + +static void +print_tree(enum SortOrder order, RBTNode* root) +{ + fprintf(stderr, " --- %s ordered tree begin ---\r\n", sort_order_names[order]); + print_tree_aux(order, root, 0); + fprintf(stderr, " --- %s ordered tree end ---\r\n", sort_order_names[order]); +} + +#endif /* PRINT_TREE */ + + +#ifdef FREE_SEG_API_SMOKE_TEST + +void test_it(void) +{ + ErtsFreeSegMap map; + ErtsFreeSegDesc *desc, *under, *over, *d1, *d2; + const int i = 1; /* reverse addr order */ + + { + init_free_seg_map(&map, SZ_REVERSE_ADDR_ORDER); + + insert_free_seg(&map, alloc_desc(), (char*)0x11000, (char*)0x12000); + HARD_CHECK_TREE(&map.atree, 0); HARD_CHECK_TREE(&map.stree, 0); + insert_free_seg(&map, alloc_desc(), (char*)0x13000, (char*)0x14000); + HARD_CHECK_TREE(&map.atree, 0); HARD_CHECK_TREE(&map.stree, 0); + insert_free_seg(&map, alloc_desc(), (char*)0x15000, (char*)0x17000); + HARD_CHECK_TREE(&map.atree, 0); HARD_CHECK_TREE(&map.stree, 0); + insert_free_seg(&map, alloc_desc(), (char*)0x8000, (char*)0x10000); + HARD_CHECK_TREE(&map.atree, 0); HARD_CHECK_TREE(&map.stree, 0); + + desc = lookup_free_seg(&map, 0x500); + ERTS_ASSERT(desc->start == (char*)(i?0x13000L:0x11000L)); + + desc = lookup_free_seg(&map, 0x1500); + ERTS_ASSERT(desc->start == (char*)0x15000); + + adjacent_free_seg(&map, (char*)0x6666, (char*)0x7777, &under, &over); + ERTS_ASSERT(!under && !over); + + adjacent_free_seg(&map, (char*)0x6666, (char*)0x8000, &under, &over); + ERTS_ASSERT(!under && over->start == (char*)0x8000); + + adjacent_free_seg(&map, (char*)0x10000, (char*)0x10500, &under, &over); + ERTS_ASSERT(under->end == (char*)0x10000 && !over); + + adjacent_free_seg(&map, (char*)0x10100, (char*)0x10500, &under, &over); + ERTS_ASSERT(!under && !over); + + adjacent_free_seg(&map, (char*)0x10100, (char*)0x11000, &under, &over); + ERTS_ASSERT(!under && over && over->start == (char*)0x11000); + + adjacent_free_seg(&map, (char*)0x12000, (char*)0x12500, &under, &over); + ERTS_ASSERT(under && under->end == (char*)0x12000 && !over); + + adjacent_free_seg(&map, (char*)0x12000, (char*)0x13000, &under, &over); + ERTS_ASSERT(under && under->end == (char*)0x12000 && + over && over->start == (char*)0x13000); + + adjacent_free_seg(&map, (char*)0x12500, (char*)0x13000, &under, &over); + ERTS_ASSERT(!under && over && over->start == (char*)0x13000); + + d1 = lookup_free_seg(&map, 0x500); + ERTS_ASSERT(d1->start == (char*)(i?0x13000L:0x11000L)); + + resize_free_seg(&map, d1, d1->start - 0x800, (char*)d1->end); + HARD_CHECK_TREE(&map.atree, 0); HARD_CHECK_TREE(&map.stree, 0); + + d2 = lookup_free_seg(&map, 0x1200); + ERTS_ASSERT(d2 == d1); + + delete_free_seg(&map, d1); + HARD_CHECK_TREE(&map.atree, 0); HARD_CHECK_TREE(&map.stree, 0); + + d1 = lookup_free_seg(&map, 0x1200); + ERTS_ASSERT(d1->start == (char*)0x15000); + } +} + +#endif /* FREE_SEG_API_SMOKE_TEST */ + + +#ifdef HARD_DEBUG_MSEG + +/* + * Debug stuff used by erl_mseg to check that it does the right thing. + * The reason for keeping it here is that we (ab)use the rb-tree code + * for keeping track of *allocated* segments. + */ + +typedef struct ErtsFreeSegDesc_fake_ { + /*RBTNode snode; Save memory by skipping unused size tree node */ + RBTNode anode; /* node in 'atree' */ + union { + char* start; + struct ErtsFreeSegDesc_fake_* next_free; + }u; + char* end; +}ErtsFreeSegDesc_fake; + +static ErtsFreeSegDesc_fake hard_dbg_mseg_desc_pool[10000]; +static ErtsFreeSegDesc_fake* hard_dbg_mseg_desc_first; +RBTree hard_dbg_mseg_tree; + +static erts_mtx_t hard_dbg_mseg_mtx; + +static void hard_dbg_mseg_init(void) +{ + ErtsFreeSegDesc_fake* p; + + erts_mtx_init(&hard_dbg_mseg_mtx, "hard_dbg_mseg"); + hard_dbg_mseg_tree.root = NULL; + hard_dbg_mseg_tree.order = ADDR_ORDER; + + p = &hard_dbg_mseg_desc_pool[(sizeof(hard_dbg_mseg_desc_pool) / + sizeof(*hard_dbg_mseg_desc_pool)) - 1]; + p->u.next_free = NULL; + while (--p >= hard_dbg_mseg_desc_pool) { + p->u.next_free = (p+1); + } + hard_dbg_mseg_desc_first = &hard_dbg_mseg_desc_pool[0]; +} + +static ErtsFreeSegDesc* hard_dbg_alloc_desc(void) +{ + ErtsFreeSegDesc_fake* p = hard_dbg_mseg_desc_first; + ERTS_ASSERT(p || !"HARD_DEBUG_MSEG: Out of mseg descriptors"); + hard_dbg_mseg_desc_first = p->u.next_free; + + /* Creative pointer arithmetic to return something that looks like + * a ErtsFreeSegDesc as long as we don't use the absent 'snode'. + */ + return (ErtsFreeSegDesc*) ((char*)p - offsetof(ErtsFreeSegDesc,anode)); +} + +static void hard_dbg_free_desc(ErtsFreeSegDesc* desc) +{ + ErtsFreeSegDesc_fake* p = (ErtsFreeSegDesc_fake*) &desc->anode; + memset(p, 0xfe, sizeof(*p)); + p->u.next_free = hard_dbg_mseg_desc_first; + hard_dbg_mseg_desc_first = p; +} + +static void check_seg_writable(void* seg, UWord sz) +{ + UWord* seg_end = (UWord*)((char*)seg + sz); + volatile UWord* p; + ERTS_ASSERT(ERTS_IS_PAGEALIGNED(seg)); + ERTS_ASSERT(ERTS_IS_PAGEALIGNED(sz)); + for (p=(UWord*)seg; p<seg_end; p += (ERTS_INV_PAGEALIGNED_MASK+1)/sizeof(UWord)) { + UWord write_back = *p; + *p = 0xfade2b1acc; + *p = write_back; + } +} + +void hard_dbg_insert_mseg(void* seg, UWord sz) +{ + check_seg_writable(seg, sz); + erts_mtx_lock(&hard_dbg_mseg_mtx); + { + ErtsFreeSegDesc *desc = hard_dbg_alloc_desc(); + RBTNode *prev, *next; + desc->start = (char*)seg; + desc->end = desc->start + sz - 1; /* -1 to allow adjacent segments in tree */ + rbt_insert(&hard_dbg_mseg_tree, &desc->anode); + prev = rbt_prev_node(&desc->anode); + next = rbt_next_node(&desc->anode); + ERTS_ASSERT(!prev || anode_to_desc(prev)->end < desc->start); + ERTS_ASSERT(!next || anode_to_desc(next)->start > desc->end); + } + erts_mtx_unlock(&hard_dbg_mseg_mtx); +} + +static ErtsFreeSegDesc* hard_dbg_lookup_seg_at(RBTree* tree, char* start) +{ + RBTNode* x = tree->root; + + while (x) { + ErtsFreeSegDesc* desc = anode_to_desc(x); + if (start < desc->start) { + x = x->left; + } + else if (start > desc->start) { + ERTS_ASSERT(start > desc->end); + x = x->right; + } + else + return desc; + } + return NULL; +} + +void hard_dbg_remove_mseg(void* seg, UWord sz) +{ + check_seg_writable(seg, sz); + erts_mtx_lock(&hard_dbg_mseg_mtx); + { + ErtsFreeSegDesc* desc = hard_dbg_lookup_seg_at(&hard_dbg_mseg_tree, (char*)seg); + ERTS_ASSERT(desc); + ERTS_ASSERT(desc->start == (char*)seg); + ERTS_ASSERT(desc->end == (char*)seg + sz - 1); + + rbt_delete(&hard_dbg_mseg_tree, &desc->anode); + hard_dbg_free_desc(desc); + } + erts_mtx_unlock(&hard_dbg_mseg_mtx); +} + +#endif /* HARD_DEBUG_MSEG */ diff --git a/erts/emulator/sys/common/erl_mmap.h b/erts/emulator/sys/common/erl_mmap.h new file mode 100644 index 0000000000..e6934dbb26 --- /dev/null +++ b/erts/emulator/sys/common/erl_mmap.h @@ -0,0 +1,134 @@ +/* + * %CopyrightBegin% + * + * Copyright Ericsson AB 2013. All Rights Reserved. + * + * The contents of this file are subject to the Erlang Public License, + * Version 1.1, (the "License"); you may not use this file except in + * compliance with the License. You should have received a copy of the + * Erlang Public License along with this software. If not, it can be + * retrieved online at http://www.erlang.org/. + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + * the License for the specific language governing rights and limitations + * under the License. + * + * %CopyrightEnd% + */ + +#ifndef ERL_MMAP_H__ +#define ERL_MMAP_H__ + +#include "sys.h" + +#define ERTS_MMAP_SUPERALIGNED_BITS (18) +/* Affects hard limits for sbct and lmbcs documented in erts_alloc.xml */ + +#define ERTS_MMAPFLG_OS_ONLY (((Uint32) 1) << 0) +#define ERTS_MMAPFLG_SUPERCARRIER_ONLY (((Uint32) 1) << 1) +#define ERTS_MMAPFLG_SUPERALIGNED (((Uint32) 1) << 2) + +#define ERTS_HAVE_ERTS_OS_MMAP (1 << 0) +#define ERTS_HAVE_ERTS_SUPERCARRIER_MMAP (1 << 1) +extern int erts_have_erts_mmap; +extern UWord erts_page_inv_mask; + +typedef struct { + struct { + char *start; + char *end; + } virtual_range; + struct { + char *start; + char *end; + } predefined_area; + UWord scs; /* super carrier size */ + int sco; /* super carrier only? */ + Uint scmgc; /* super carrier: max guaranteed (number of) carriers */ + int scrpm; +}ErtsMMapInit; + +#define ERTS_MMAP_INIT_DEFAULT_INITER \ + {{NULL, NULL}, {NULL, NULL}, 0, 1, (1 << 16), 1} + +void *erts_mmap(Uint32 flags, UWord *sizep); +void erts_munmap(Uint32 flags, void *ptr, UWord size); +void *erts_mremap(Uint32 flags, void *ptr, UWord old_size, UWord *sizep); +int erts_mmap_in_supercarrier(void *ptr); +void erts_mmap_init(ErtsMMapInit*); +struct erts_mmap_info_struct +{ + UWord sizes[6]; + UWord segs[6]; + UWord os_used; +}; +Eterm erts_mmap_info(int *print_to_p, void *print_to_arg, + Eterm** hpp, Uint* szp, struct erts_mmap_info_struct*); +Eterm erts_mmap_info_options(char *prefix, int *print_to_p, void *print_to_arg, + Uint **hpp, Uint *szp); +struct process; +Eterm erts_mmap_debug_info(struct process*); + +#define ERTS_SUPERALIGNED_SIZE \ + (1 << ERTS_MMAP_SUPERALIGNED_BITS) +#define ERTS_INV_SUPERALIGNED_MASK \ + ((UWord) (ERTS_SUPERALIGNED_SIZE - 1)) +#define ERTS_SUPERALIGNED_MASK \ + (~ERTS_INV_SUPERALIGNED_MASK) +#define ERTS_SUPERALIGNED_FLOOR(X) \ + (((UWord) (X)) & ERTS_SUPERALIGNED_MASK) +#define ERTS_SUPERALIGNED_CEILING(X) \ + ERTS_SUPERALIGNED_FLOOR((X) + ERTS_INV_SUPERALIGNED_MASK) +#define ERTS_IS_SUPERALIGNED(X) \ + (((UWord) (X) & ERTS_INV_SUPERALIGNED_MASK) == 0) + +#define ERTS_INV_PAGEALIGNED_MASK \ + (erts_page_inv_mask) +#define ERTS_PAGEALIGNED_MASK \ + (~ERTS_INV_PAGEALIGNED_MASK) +#define ERTS_PAGEALIGNED_FLOOR(X) \ + (((UWord) (X)) & ERTS_PAGEALIGNED_MASK) +#define ERTS_PAGEALIGNED_CEILING(X) \ + ERTS_PAGEALIGNED_FLOOR((X) + ERTS_INV_PAGEALIGNED_MASK) +#define ERTS_IS_PAGEALIGNED(X) \ + (((UWord) (X) & ERTS_INV_PAGEALIGNED_MASK) == 0) +#define ERTS_PAGEALIGNED_SIZE \ + (ERTS_INV_PAGEALIGNED_MASK + 1) + +#ifndef HAVE_MMAP +# define HAVE_MMAP 0 +#endif +#ifndef HAVE_MREMAP +# define HAVE_MREMAP 0 +#endif +#if HAVE_MMAP +# define ERTS_HAVE_OS_MMAP 1 +# define ERTS_HAVE_GENUINE_OS_MMAP 1 +# if HAVE_MREMAP +# define ERTS_HAVE_OS_MREMAP 1 +# endif +# if defined(MAP_FIXED) && defined(MAP_NORESERVE) +# define ERTS_HAVE_OS_PHYSICAL_MEMORY_RESERVATION 1 +# endif +#endif + +#ifndef HAVE_VIRTUALALLOC +# define HAVE_VIRTUALALLOC 0 +#endif +#if HAVE_VIRTUALALLOC +# define ERTS_HAVE_OS_MMAP 1 +#endif + +/*#define HARD_DEBUG_MSEG*/ +#ifdef HARD_DEBUG_MSEG +# define HARD_DBG_INSERT_MSEG hard_dbg_insert_mseg +# define HARD_DBG_REMOVE_MSEG hard_dbg_remove_mseg +void hard_dbg_insert_mseg(void* seg, UWord sz); +void hard_dbg_remove_mseg(void* seg, UWord sz); +#else +# define HARD_DBG_INSERT_MSEG(SEG,SZ) +# define HARD_DBG_REMOVE_MSEG(SEG,SZ) +#endif + +#endif /* ERL_MMAP_H__ */ diff --git a/erts/emulator/sys/common/erl_mseg.c b/erts/emulator/sys/common/erl_mseg.c index 2748edba02..94a381e168 100644 --- a/erts/emulator/sys/common/erl_mseg.c +++ b/erts/emulator/sys/common/erl_mseg.c @@ -100,45 +100,6 @@ static int atoms_initialized; typedef struct mem_kind_t MemKind; -#if HALFWORD_HEAP -static int initialize_pmmap(void); -static void *pmmap(size_t size); -static int pmunmap(void *p, size_t size); -static void *pmremap(void *old_address, size_t old_size, - size_t new_size); -#endif - -#if HAVE_MMAP -/* Mmap ... */ - -#define MMAP_PROT (PROT_READ|PROT_WRITE) - - -#ifdef MAP_ANON -# define MMAP_FLAGS (MAP_ANON|MAP_PRIVATE) -# define MMAP_FD (-1) -#else -# define MMAP_FLAGS (MAP_PRIVATE) -# define MMAP_FD mmap_fd -static int mmap_fd; -#endif - -#if HAVE_MREMAP -# define HAVE_MSEG_RECREATE 1 -#else -# define HAVE_MSEG_RECREATE 0 -#endif - -#if HALFWORD_HEAP -#define CAN_PARTLY_DESTROY 0 -#else -#define CAN_PARTLY_DESTROY 1 -#endif -#else /* #if HAVE_MMAP */ -#define CAN_PARTLY_DESTROY 0 -#error "Not supported" -#endif /* #if HAVE_MMAP */ - const ErtsMsegOpt_t erts_mseg_default_opt = { 1, /* Use cache */ 1, /* Preserv data */ @@ -163,9 +124,7 @@ typedef struct { CallCounter create; CallCounter create_resize; CallCounter destroy; -#if HAVE_MSEG_RECREATE CallCounter recreate; -#endif CallCounter clear_cache; CallCounter check_cache; } ErtsMsegCalls; @@ -173,7 +132,7 @@ typedef struct { typedef struct cache_t_ cache_t; struct cache_t_ { - Uint size; + UWord size; void *seg; cache_t *next; cache_t *prev; @@ -236,11 +195,6 @@ struct ErtsMsegAllctr_t_ { Uint rel_max_cache_bad_fit; ErtsMsegCalls calls; - -#if CAN_PARTLY_DESTROY - Uint min_seg_size; -#endif - }; typedef union { @@ -344,69 +298,31 @@ schedule_cache_check(ErtsMsegAllctr_t *ma) { } } -/* remove ErtsMsegAllctr_t from arguments? - * only used for statistics - */ -static ERTS_INLINE void * -mmap_align(ErtsMsegAllctr_t *ma, void *addr, size_t length, int prot, int flags, int fd, off_t offset) { - - char *p, *q; - UWord d; - - p = mmap(addr, length, prot, flags, fd, offset); - - if (MAP_IS_ALIGNED(p) || p == MAP_FAILED) - return p; - - if (ma) - INC_CC(ma, create_resize); - - munmap(p, length); - - if ((p = mmap(addr, length + MSEG_ALIGNED_SIZE, prot, flags, fd, offset)) == MAP_FAILED) - return MAP_FAILED; - - q = (void *)ALIGNED_CEILING((char *)p); - d = (UWord)(q - p); - - if (d > 0) - munmap(p, d); - - if (MSEG_ALIGNED_SIZE - d > 0) - munmap((void *)(q + length), MSEG_ALIGNED_SIZE - d); - - return q; -} +/* #define ERTS_PRINT_ERTS_MMAP */ static ERTS_INLINE void * -mseg_create(ErtsMsegAllctr_t *ma, MemKind* mk, Uint size) +mseg_create(ErtsMsegAllctr_t *ma, Uint flags, MemKind* mk, UWord *sizep) { +#ifdef ERTS_PRINT_ERTS_MMAP + UWord req_size = *sizep; +#endif void *seg; - ASSERT(size % MSEG_ALIGNED_SIZE == 0); - + Uint32 mmap_flags = 0; #if HALFWORD_HEAP - if (mk == &ma->low_mem) { - seg = pmmap(size); - if ((unsigned long) seg & CHECK_POINTER_MASK) { - erts_fprintf(stderr,"Pointer mask failure (0x%08lx)\n",(unsigned long) seg); - return NULL; - } - } else + mmap_flags |= ((mk == &ma->low_mem) + ? ERTS_MMAPFLG_SUPERCARRIER_ONLY + : ERTS_MMAPFLG_OS_ONLY); #endif - { -#if HAVE_MMAP - { - seg = (void *) mmap_align(ma, (void *) 0, (size_t) size, - MMAP_PROT, MMAP_FLAGS, MMAP_FD, 0); - if (seg == (void *) MAP_FAILED) - seg = NULL; - - ASSERT(MAP_IS_ALIGNED(seg) || !seg); - } -#else -# error "Missing mseg_create() implementation" + if (MSEG_FLG_IS_2POW(flags)) + mmap_flags |= ERTS_MMAPFLG_SUPERALIGNED; + + seg = erts_mmap(mmap_flags, sizep); + +#ifdef ERTS_PRINT_ERTS_MMAP + erts_fprintf(stderr, "%p = erts_mmap(%s, {%bpu, %bpu});\n", seg, + (mmap_flags & ERTS_MMAPFLG_SUPERALIGNED) ? "sa" : "sua", + req_size, *sizep); #endif - } INC_CC(ma, create); @@ -414,91 +330,55 @@ mseg_create(ErtsMsegAllctr_t *ma, MemKind* mk, Uint size) } static ERTS_INLINE void -mseg_destroy(ErtsMsegAllctr_t *ma, MemKind* mk, void *seg, Uint size) { - ERTS_DECLARE_DUMMY(int res); - +mseg_destroy(ErtsMsegAllctr_t *ma, Uint flags, MemKind* mk, void *seg_p, UWord size) { + + Uint32 mmap_flags = 0; #if HALFWORD_HEAP - if (mk == &ma->low_mem) { - res = pmunmap((void *) seg, size); - } - else + mmap_flags |= ((mk == &ma->low_mem) + ? ERTS_MMAPFLG_SUPERCARRIER_ONLY + : ERTS_MMAPFLG_OS_ONLY); #endif - { -#ifdef HAVE_MMAP - res = munmap((void *) seg, size); -#else -# error "Missing mseg_destroy() implementation" + if (MSEG_FLG_IS_2POW(flags)) + mmap_flags |= ERTS_MMAPFLG_SUPERALIGNED; + + erts_munmap(mmap_flags, seg_p, size); +#ifdef ERTS_PRINT_ERTS_MMAP + erts_fprintf(stderr, "erts_munmap(%s, %p, %bpu);\n", + (mmap_flags & ERTS_MMAPFLG_SUPERALIGNED) ? "sa" : "sua", + seg_p, *size); #endif - } - - ASSERT(size % MSEG_ALIGNED_SIZE == 0); - ASSERT(res == 0); - INC_CC(ma, destroy); } -#if HAVE_MSEG_RECREATE -#if defined(__NetBSD__) -#define MREMAP_FLAGS (0) -#else -#define MREMAP_FLAGS (MREMAP_MAYMOVE) -#endif - - -/* mseg_recreate - * May return *unaligned* segments as in address not aligned to MSEG_ALIGNMENT - * it is still page aligned - * - * This is fine for single block carriers as long as we don't cache misaligned - * segments (since multiblock carriers may use them) - * - * For multiblock carriers we *need* MSEG_ALIGNMENT but mbc's will never be - * reallocated. - * - * This should probably be fixed the following way: - * 1) Use an option to segment allocation - NEED_ALIGNMENT - * 2) Add mremap_align which takes care of aligning a new a mremaped area - * 3) Fix the cache to handle of aligned and unaligned segments - */ - static ERTS_INLINE void * -mseg_recreate(ErtsMsegAllctr_t *ma, MemKind* mk, void *old_seg, Uint old_size, Uint new_size) +mseg_recreate(ErtsMsegAllctr_t *ma, Uint flags, MemKind* mk, void *old_seg, UWord old_size, UWord *sizep) { +#ifdef ERTS_PRINT_ERTS_MMAP + UWord req_size = *sizep; +#endif void *new_seg; - - ASSERT(old_size % MSEG_ALIGNED_SIZE == 0); - ASSERT(new_size % MSEG_ALIGNED_SIZE == 0); - + Uint32 mmap_flags = 0; #if HALFWORD_HEAP - if (mk == &ma->low_mem) { - new_seg = (void *) pmremap((void *) old_seg, - (size_t) old_size, - (size_t) new_size); - } - else + mmap_flags |= ((mk == &ma->low_mem) + ? ERTS_MMAPFLG_SUPERCARRIER_ONLY + : ERTS_MMAPFLG_OS_ONLY); #endif - { -#if HAVE_MREMAP -#if defined(__NetBSD__) - new_seg = mremap(old_seg, (size_t)old_size, NULL, new_size, MREMAP_FLAGS); -#else - new_seg = mremap(old_seg, (size_t)old_size, (size_t)new_size, MREMAP_FLAGS); -#endif - if (new_seg == (void *) MAP_FAILED) - new_seg = NULL; -#else -#error "Missing mseg_recreate() implementation" -#endif - } + if (MSEG_FLG_IS_2POW(flags)) + mmap_flags |= ERTS_MMAPFLG_SUPERALIGNED; + new_seg = erts_mremap(mmap_flags, old_seg, old_size, sizep); + +#ifdef ERTS_PRINT_ERTS_MMAP + erts_fprintf(stderr, "%p = erts_mremap(%s, %p, %bpu, {%bpu, %bpu});\n", + new_seg, (mmap_flags & ERTS_MMAPFLG_SUPERALIGNED) ? "sa" : "sua", + old_seg, old_size, req_size, *sizep); +#endif INC_CC(ma, recreate); return new_seg; } -#endif /* #if HAVE_MSEG_RECREATE */ - #ifdef DEBUG #define ERTS_DBG_MA_CHK_THR_ACCESS(MA) \ do { \ @@ -528,7 +408,7 @@ static ERTS_INLINE void mseg_cache_clear_node(cache_t *c) { c->prev = c; } -static ERTS_INLINE int cache_bless_segment(MemKind *mk, void *seg, Uint size, Uint flags) { +static ERTS_INLINE int cache_bless_segment(MemKind *mk, void *seg, UWord size, Uint flags) { cache_t *c; ERTS_DBG_MK_CHK_THR_ACCESS(mk); @@ -566,14 +446,13 @@ static ERTS_INLINE int cache_bless_segment(MemKind *mk, void *seg, Uint size, Ui return 1; } else if (!MSEG_FLG_IS_2POW(flags) && !erts_circleq_is_empty(&(mk->cache_unpowered_node))) { - /* No free slots. * Evict oldest slot from unpowered cache so we can cache an unpowered (sbc) segment */ c = erts_circleq_tail(&(mk->cache_unpowered_node)); erts_circleq_remove(c); - mseg_destroy(mk->ma, mk, c->seg, c->size); + mseg_destroy(mk->ma, ERTS_MSEG_FLG_NONE, mk, c->seg, c->size); mseg_cache_clear_node(c); c->seg = seg; @@ -599,7 +478,8 @@ static ERTS_INLINE int cache_bless_segment(MemKind *mk, void *seg, Uint size, Ui c = erts_circleq_tail(&(mk->cache_powered_node[i])); erts_circleq_remove(c); - mseg_destroy(mk->ma, mk, c->seg, c->size); + mseg_destroy(mk->ma, ERTS_MSEG_FLG_2POW, mk, c->seg, c->size); + mseg_cache_clear_node(c); c->seg = seg; @@ -614,18 +494,18 @@ static ERTS_INLINE int cache_bless_segment(MemKind *mk, void *seg, Uint size, Ui return 0; } -static ERTS_INLINE void *cache_get_segment(MemKind *mk, Uint *size_p, Uint flags) { +static ERTS_INLINE void *cache_get_segment(MemKind *mk, UWord *size_p, Uint flags) { - Uint size = *size_p; + UWord size = *size_p; ERTS_DBG_MK_CHK_THR_ACCESS(mk); if (MSEG_FLG_IS_2POW(flags)) { int i, ix = SIZE_TO_CACHE_AREA_IDX(size); - void *seg; + char *seg; cache_t *c; - Uint csize; + UWord csize; ASSERT(IS_2POW(size)); @@ -641,7 +521,7 @@ static ERTS_INLINE void *cache_get_segment(MemKind *mk, Uint *size_p, Uint flags ASSERT(MAP_IS_ALIGNED(c->seg)); csize = c->size; - seg = c->seg; + seg = (char*) c->seg; mk->cache_size--; mk->cache_hits++; @@ -652,9 +532,8 @@ static ERTS_INLINE void *cache_get_segment(MemKind *mk, Uint *size_p, Uint flags ASSERT(!(mk->cache_size < 0)); - if (csize != size) { - mseg_destroy(mk->ma, mk, (char *)seg + size, csize - size); - } + if (csize != size) + mseg_destroy(mk->ma, ERTS_MSEG_FLG_2POW, mk, seg + size, csize - size); return seg; } @@ -663,10 +542,10 @@ static ERTS_INLINE void *cache_get_segment(MemKind *mk, Uint *size_p, Uint flags void *seg; cache_t *c; cache_t *best = NULL; - Uint bdiff = 0; - Uint csize; - Uint bad_max_abs = mk->ma->abs_max_cache_bad_fit; - Uint bad_max_rel = mk->ma->rel_max_cache_bad_fit; + UWord bdiff = 0; + UWord csize; + UWord bad_max_abs = mk->ma->abs_max_cache_bad_fit; + UWord bad_max_rel = mk->ma->rel_max_cache_bad_fit; erts_circleq_foreach(c, &(mk->cache_unpowered_node)) { csize = c->size; @@ -728,7 +607,7 @@ static ERTS_INLINE void *cache_get_segment(MemKind *mk, Uint *size_p, Uint flags * using callbacks from aux-work in the scheduler. */ -static ERTS_INLINE Uint mseg_drop_one_memkind_cache_size(MemKind *mk, cache_t *head) { +static ERTS_INLINE Uint mseg_drop_one_memkind_cache_size(MemKind *mk, Uint flags, cache_t *head) { cache_t *c = NULL; c = erts_circleq_tail(head); @@ -737,7 +616,7 @@ static ERTS_INLINE Uint mseg_drop_one_memkind_cache_size(MemKind *mk, cache_t *h if (erts_mtrace_enabled) erts_mtrace_crr_free(SEGTYPE, SEGTYPE, c->seg); - mseg_destroy(mk->ma, mk, c->seg, c->size); + mseg_destroy(mk->ma, flags, mk, c->seg, c->size); mseg_cache_clear_node(c); erts_circleq_push_head(&(mk->cache_free), c); @@ -749,7 +628,7 @@ static ERTS_INLINE Uint mseg_drop_one_memkind_cache_size(MemKind *mk, cache_t *h return mk->cache_size; } -static ERTS_INLINE Uint mseg_drop_memkind_cache_size(MemKind *mk, cache_t *head) { +static ERTS_INLINE Uint mseg_drop_memkind_cache_size(MemKind *mk, Uint flags, cache_t *head) { cache_t *c = NULL; while (!erts_circleq_is_empty(head)) { @@ -760,7 +639,7 @@ static ERTS_INLINE Uint mseg_drop_memkind_cache_size(MemKind *mk, cache_t *head) if (erts_mtrace_enabled) erts_mtrace_crr_free(SEGTYPE, SEGTYPE, c->seg); - mseg_destroy(mk->ma, mk, c->seg, c->size); + mseg_destroy(mk->ma, flags, mk, c->seg, c->size); mseg_cache_clear_node(c); erts_circleq_push_head(&(mk->cache_free), c); @@ -788,11 +667,11 @@ static Uint mseg_check_memkind_cache(MemKind *mk) { for (i = 0; i < CACHE_AREAS; i++) { if (!erts_circleq_is_empty(&(mk->cache_powered_node[i]))) - return mseg_drop_one_memkind_cache_size(mk, &(mk->cache_powered_node[i])); + return mseg_drop_one_memkind_cache_size(mk, ERTS_MSEG_FLG_2POW, &(mk->cache_powered_node[i])); } if (!erts_circleq_is_empty(&(mk->cache_unpowered_node))) - return mseg_drop_one_memkind_cache_size(mk, &(mk->cache_unpowered_node)); + return mseg_drop_one_memkind_cache_size(mk, ERTS_MSEG_FLG_NONE, &(mk->cache_unpowered_node)); return 0; } @@ -851,12 +730,12 @@ static void mseg_clear_memkind_cache(MemKind *mk) { if (erts_circleq_is_empty(&(mk->cache_powered_node[i]))) continue; - mseg_drop_memkind_cache_size(mk, &(mk->cache_powered_node[i])); + mseg_drop_memkind_cache_size(mk, ERTS_MSEG_FLG_2POW, &(mk->cache_powered_node[i])); ASSERT(erts_circleq_is_empty(&(mk->cache_powered_node[i]))); } /* drop varied caches */ if (!erts_circleq_is_empty(&(mk->cache_unpowered_node))) - mseg_drop_memkind_cache_size(mk, &(mk->cache_unpowered_node)); + mseg_drop_memkind_cache_size(mk, ERTS_MSEG_FLG_NONE, &(mk->cache_unpowered_node)); ASSERT(erts_circleq_is_empty(&(mk->cache_unpowered_node))); ASSERT(mk->cache_size == 0); @@ -896,36 +775,35 @@ static ERTS_INLINE MemKind* memkind(ErtsMsegAllctr_t *ma, } static void * -mseg_alloc(ErtsMsegAllctr_t *ma, ErtsAlcType_t atype, Uint *size_p, +mseg_alloc(ErtsMsegAllctr_t *ma, ErtsAlcType_t atype, UWord *size_p, Uint flags, const ErtsMsegOpt_t *opt) { - Uint size; + UWord size; void *seg; MemKind* mk = memkind(ma, opt); INC_CC(ma, alloc); - /* Carrier align */ - size = ALIGNED_CEILING(*size_p); - - /* Cache optim (if applicable) */ - if (MSEG_FLG_IS_2POW(flags) && !IS_2POW(size)) - size = ceil_2pow(size); + if (!MSEG_FLG_IS_2POW(flags)) + size = ERTS_PAGEALIGNED_CEILING(*size_p); + else { + size = ALIGNED_CEILING(*size_p); + if (!IS_2POW(size)) { + /* Cache optim (if applicable) */ + size = ceil_2pow(size); + } + } -#if CAN_PARTLY_DESTROY - if (size < ma->min_seg_size) - ma->min_seg_size = size; -#endif - if (opt->cache && mk->cache_size > 0 && (seg = cache_get_segment(mk, &size, flags)) != NULL) goto done; - if ((seg = mseg_create(ma, mk, size)) == NULL) - size = 0; + seg = mseg_create(ma, flags, mk, &size); + if (!seg) + *size_p = 0; + else { done: - *size_p = size; - if (seg) { + *size_p = size; if (erts_mtrace_enabled) erts_mtrace_crr_alloc(seg, atype, ERTS_MTRACE_SEGMENT_ID, size); @@ -937,7 +815,7 @@ done: static void -mseg_dealloc(ErtsMsegAllctr_t *ma, ErtsAlcType_t atype, void *seg, Uint size, +mseg_dealloc(ErtsMsegAllctr_t *ma, ErtsAlcType_t atype, void *seg, UWord size, Uint flags, const ErtsMsegOpt_t *opt) { MemKind* mk = memkind(ma, opt); @@ -952,7 +830,7 @@ mseg_dealloc(ErtsMsegAllctr_t *ma, ErtsAlcType_t atype, void *seg, Uint size, if (erts_mtrace_enabled) erts_mtrace_crr_free(atype, SEGTYPE, seg); - mseg_destroy(ma, mk, seg, size); + mseg_destroy(ma, flags, mk, seg, size); done: @@ -961,11 +839,11 @@ done: static void * mseg_realloc(ErtsMsegAllctr_t *ma, ErtsAlcType_t atype, void *seg, - Uint old_size, Uint *new_size_p, Uint flags, const ErtsMsegOpt_t *opt) + UWord old_size, UWord *new_size_p, Uint flags, const ErtsMsegOpt_t *opt) { MemKind* mk; void *new_seg; - Uint new_size; + UWord new_size; /* Just allocate a new segment if we didn't have one before */ if (!seg || !old_size) { @@ -985,90 +863,47 @@ mseg_realloc(ErtsMsegAllctr_t *ma, ErtsAlcType_t atype, void *seg, mk = memkind(ma, opt); new_seg = seg; - /* Carrier align */ - new_size = ALIGNED_CEILING(*new_size_p); - - /* Cache optim (if applicable) */ - if (MSEG_FLG_IS_2POW(flags) && !IS_2POW(new_size)) - new_size = ceil_2pow(new_size); - - if (new_size == old_size) - ; - else if (new_size < old_size) { - Uint shrink_sz = old_size - new_size; + if (!MSEG_FLG_IS_2POW(flags)) + new_size = ERTS_PAGEALIGNED_CEILING(*new_size_p); + else { + new_size = ALIGNED_CEILING(*new_size_p); + if (!IS_2POW(new_size)) { + /* Cache optim (if applicable) */ + new_size = ceil_2pow(new_size); + } + } -#if CAN_PARTLY_DESTROY - if (new_size < ma->min_seg_size) - ma->min_seg_size = new_size; -#endif - /* +M<S>rsbcst <ratio> */ - if (shrink_sz < opt->abs_shrink_th - && 100*shrink_sz < opt->rel_shrink_th*old_size) { - new_size = old_size; + if (new_size > old_size) { + if (opt->preserv) { + new_seg = mseg_recreate(ma, flags, mk, (void *) seg, old_size, &new_size); + if (!new_seg) + new_size = old_size; } else { - -#if CAN_PARTLY_DESTROY - - if (erts_mtrace_enabled) - erts_mtrace_crr_realloc(new_seg, atype, SEGTYPE, seg, new_size); - - mseg_destroy(ma, mk, ((char *) seg) + new_size, shrink_sz); - -#elif HAVE_MSEG_RECREATE - goto do_recreate; -#else + mseg_dealloc(ma, atype, seg, old_size, flags, opt); new_seg = mseg_alloc(ma, atype, &new_size, flags, opt); - - ASSERT(MAP_IS_ALIGNED(new_seg) || !new_seg); - if (!new_seg) - new_size = old_size; - else { - sys_memcpy(((char *) new_seg), - ((char *) seg), - MIN(new_size, old_size)); - mseg_dealloc(ma, atype, seg, old_size, flags, opt); - } -#endif + new_size = 0; } } - else { + else if (new_size < old_size) { + UWord shrink_sz = old_size - new_size; - if (!opt->preserv) { - mseg_dealloc(ma, atype, seg, old_size, flags, opt); - new_seg = mseg_alloc(ma, atype, &new_size, flags, opt); - ASSERT(MAP_IS_ALIGNED(new_seg) || !new_seg); + /* +M<S>rsbcst <ratio> */ + if (shrink_sz < opt->abs_shrink_th + && 100*shrink_sz < opt->rel_shrink_th*old_size) { + new_size = old_size; } else { -#if HAVE_MSEG_RECREATE -#if !CAN_PARTLY_DESTROY - do_recreate: -#endif - new_seg = mseg_recreate(ma, mk, (void *) seg, old_size, new_size); - /* ASSERT(MAP_IS_ALIGNED(new_seg) || !new_seg); - * will not always be aligned and it ok for now - */ - - if (erts_mtrace_enabled) - erts_mtrace_crr_realloc(new_seg, atype, SEGTYPE, seg, new_size); + new_seg = mseg_recreate(ma, flags, mk, (void *) seg, old_size, &new_size); if (!new_seg) new_size = old_size; -#else - new_seg = mseg_alloc(ma, atype, &new_size, flags, opt); - - ASSERT(MAP_IS_ALIGNED(new_seg) || !new_seg); - - if (!new_seg) - new_size = old_size; - else { - sys_memcpy(((char *) new_seg), ((char *) seg), MIN(new_size, old_size)); - mseg_dealloc(ma, atype, seg, old_size, flags, opt); - } -#endif } } + if (erts_mtrace_enabled) + erts_mtrace_crr_realloc(new_seg, atype, SEGTYPE, seg, new_size); + INC_CC(ma, realloc); ASSERT(!MSEG_FLG_IS_2POW(flags) || IS_2POW(new_size)); @@ -1106,9 +941,7 @@ static struct { Eterm mseg_create; Eterm mseg_create_resize; Eterm mseg_destroy; -#if HAVE_MSEG_RECREATE Eterm mseg_recreate; -#endif Eterm mseg_clear_cache; Eterm mseg_check_cache; @@ -1129,8 +962,6 @@ init_atoms(ErtsMsegAllctr_t *ma) #ifdef DEBUG Eterm *atom; #endif - - ERTS_MSEG_UNLOCK(ma); erts_mtx_lock(&init_atoms_mutex); if (!atoms_initialized) { @@ -1163,9 +994,7 @@ init_atoms(ErtsMsegAllctr_t *ma) AM_INIT(mseg_create); AM_INIT(mseg_create_resize); AM_INIT(mseg_destroy); -#if HAVE_MSEG_RECREATE AM_INIT(mseg_recreate); -#endif AM_INIT(mseg_clear_cache); AM_INIT(mseg_check_cache); @@ -1176,7 +1005,6 @@ init_atoms(ErtsMsegAllctr_t *ma) #endif } - ERTS_MSEG_LOCK(ma); atoms_initialized = 1; erts_mtx_unlock(&init_atoms_mutex); } @@ -1239,7 +1067,9 @@ info_options(ErtsMsegAllctr_t *ma, Uint **hpp, Uint *szp) { - Eterm res = THE_NON_VALUE; + Eterm res; + + res = erts_mmap_info_options(prefix, print_to_p, print_to_arg, hpp, szp); if (print_to_p) { int to = *print_to_p; @@ -1254,7 +1084,6 @@ info_options(ErtsMsegAllctr_t *ma, if (!atoms_initialized) init_atoms(ma); - res = NIL; add_2tup(hpp, szp, &res, am.mcs, bld_uint(hpp, szp, ma->max_cache_size)); @@ -1293,9 +1122,7 @@ info_calls(ErtsMsegAllctr_t *ma, int *print_to_p, void *print_to_arg, Uint **hpp PRINT_CC(to, arg, create); PRINT_CC(to, arg, create_resize); PRINT_CC(to, arg, destroy); -#if HAVE_MSEG_RECREATE PRINT_CC(to, arg, recreate); -#endif PRINT_CC(to, arg, clear_cache); PRINT_CC(to, arg, check_cache); @@ -1316,12 +1143,10 @@ info_calls(ErtsMsegAllctr_t *ma, int *print_to_p, void *print_to_arg, Uint **hpp bld_unstable_uint(hpp, szp, ma->calls.clear_cache.giga_no), bld_unstable_uint(hpp, szp, ma->calls.clear_cache.no)); -#if HAVE_MSEG_RECREATE add_3tup(hpp, szp, &res, am.mseg_recreate, bld_unstable_uint(hpp, szp, ma->calls.recreate.giga_no), bld_unstable_uint(hpp, szp, ma->calls.recreate.no)); -#endif add_3tup(hpp, szp, &res, am.mseg_destroy, bld_unstable_uint(hpp, szp, ma->calls.destroy.giga_no), @@ -1465,14 +1290,8 @@ erts_mseg_info_options(int ix, ErtsMsegAllctr_t *ma = ERTS_MSEG_ALLCTR_IX(ix); Eterm res; - ERTS_MSEG_LOCK(ma); - - ERTS_DBG_MA_CHK_THR_ACCESS(ma); - res = info_options(ma, "option ", print_to_p, print_to_arg, hpp, szp); - ERTS_MSEG_UNLOCK(ma); - return res; } @@ -1490,10 +1309,6 @@ erts_mseg_info(int ix, Eterm values[4]; Uint n = 0; - ERTS_MSEG_LOCK(ma); - - ERTS_DBG_MA_CHK_THR_ACCESS(ma); - if (hpp || szp) { if (!atoms_initialized) @@ -1506,6 +1321,10 @@ erts_mseg_info(int ix, } values[n++] = info_version(ma, print_to_p, print_to_arg, hpp, szp); values[n++] = info_options(ma, "option ", print_to_p, print_to_arg, hpp, szp); + + ERTS_MSEG_LOCK(ma); + ERTS_DBG_MA_CHK_THR_ACCESS(ma); + #if HALFWORD_HEAP values[n++] = info_memkind(ma, &ma->low_mem, print_to_p, print_to_arg, begin_max_per, hpp, szp); values[n++] = info_memkind(ma, &ma->hi_mem, print_to_p, print_to_arg, begin_max_per, hpp, szp); @@ -1521,7 +1340,7 @@ erts_mseg_info(int ix, } void * -erts_mseg_alloc_opt(ErtsAlcType_t atype, Uint *size_p, Uint flags, const ErtsMsegOpt_t *opt) +erts_mseg_alloc_opt(ErtsAlcType_t atype, UWord *size_p, Uint flags, const ErtsMsegOpt_t *opt) { ErtsMsegAllctr_t *ma = ERTS_MSEG_ALLCTR_OPT(opt); void *seg; @@ -1529,20 +1348,23 @@ erts_mseg_alloc_opt(ErtsAlcType_t atype, Uint *size_p, Uint flags, const ErtsMse ERTS_DBG_MA_CHK_THR_ACCESS(ma); seg = mseg_alloc(ma, atype, size_p, flags, opt); ERTS_MSEG_UNLOCK(ma); + HARD_DBG_INSERT_MSEG(seg, *size_p); return seg; } void * -erts_mseg_alloc(ErtsAlcType_t atype, Uint *size_p, Uint flags) +erts_mseg_alloc(ErtsAlcType_t atype, UWord *size_p, Uint flags) { return erts_mseg_alloc_opt(atype, size_p, flags, &erts_mseg_default_opt); } void erts_mseg_dealloc_opt(ErtsAlcType_t atype, void *seg, - Uint size, Uint flags, const ErtsMsegOpt_t *opt) + UWord size, Uint flags, const ErtsMsegOpt_t *opt) { ErtsMsegAllctr_t *ma = ERTS_MSEG_ALLCTR_OPT(opt); + + HARD_DBG_REMOVE_MSEG(seg, size); ERTS_MSEG_LOCK(ma); ERTS_DBG_MA_CHK_THR_ACCESS(ma); mseg_dealloc(ma, atype, seg, size, flags, opt); @@ -1550,29 +1372,32 @@ erts_mseg_dealloc_opt(ErtsAlcType_t atype, void *seg, } void -erts_mseg_dealloc(ErtsAlcType_t atype, void *seg, Uint size, Uint flags) +erts_mseg_dealloc(ErtsAlcType_t atype, void *seg, UWord size, Uint flags) { erts_mseg_dealloc_opt(atype, seg, size, flags, &erts_mseg_default_opt); } void * erts_mseg_realloc_opt(ErtsAlcType_t atype, void *seg, - Uint old_size, Uint *new_size_p, + UWord old_size, UWord *new_size_p, Uint flags, const ErtsMsegOpt_t *opt) { ErtsMsegAllctr_t *ma = ERTS_MSEG_ALLCTR_OPT(opt); void *new_seg; + + HARD_DBG_REMOVE_MSEG(seg, old_size); ERTS_MSEG_LOCK(ma); ERTS_DBG_MA_CHK_THR_ACCESS(ma); new_seg = mseg_realloc(ma, atype, seg, old_size, new_size_p, flags, opt); ERTS_MSEG_UNLOCK(ma); + HARD_DBG_INSERT_MSEG(new_seg, *new_size_p); return new_seg; } void * erts_mseg_realloc(ErtsAlcType_t atype, void *seg, - Uint old_size, Uint *new_size_p, Uint flags) + UWord old_size, UWord *new_size_p, Uint flags) { return erts_mseg_realloc_opt(atype, seg, old_size, new_size_p, flags, &erts_mseg_default_opt); @@ -1662,16 +1487,17 @@ erts_mseg_init(ErtsMsegInit_t *init) erts_mtx_init(&init_atoms_mutex, "mseg_init_atoms"); -#if HAVE_MMAP && !defined(MAP_ANON) - mmap_fd = open("/dev/zero", O_RDWR); - if (mmap_fd < 0) - erl_exit(ERTS_ABORT_EXIT, "erts_mseg: unable to open /dev/zero\n"); -#endif +#if HALFWORD_HEAP + if (sizeof(void *) != 8) + erl_exit(-1,"Halfword emulator cannot be run in 32bit mode"); -#if HAVE_MMAP && HALFWORD_HEAP - initialize_pmmap(); + init->mmap.virtual_range.start = (char *) sbrk(0); + init->mmap.virtual_range.end = (char *) 0x100000000UL; + init->mmap.sco = 0; #endif + erts_mmap_init(&init->mmap); + if (!IS_2POW(GET_PAGE_SIZE)) erl_exit(ERTS_ABORT_EXIT, "erts_mseg: Unexpected page_size %beu\n", GET_PAGE_SIZE); @@ -1712,10 +1538,6 @@ erts_mseg_init(ErtsMsegInit_t *init) #endif sys_memzero((void *) &ma->calls, sizeof(ErtsMsegCalls)); - -#if CAN_PARTLY_DESTROY - ma->min_seg_size = ~((Uint) 0); -#endif } } @@ -1757,7 +1579,7 @@ erts_mseg_test(UWord op, UWord a1, UWord a2, UWord a3) case 0x400: /* Have erts_mseg */ return (UWord) 1; case 0x401: - return (UWord) erts_mseg_alloc(ERTS_ALC_A_INVALID, (Uint *) a1, (Uint) 0); + return (UWord) erts_mseg_alloc(ERTS_ALC_A_INVALID, (UWord *) a1, (Uint) 0); case 0x402: erts_mseg_dealloc(ERTS_ALC_A_INVALID, (void *) a1, (Uint) a2, (Uint) 0); return (UWord) 0; @@ -1765,7 +1587,7 @@ erts_mseg_test(UWord op, UWord a1, UWord a2, UWord a3) return (UWord) erts_mseg_realloc(ERTS_ALC_A_INVALID, (void *) a1, (Uint) a2, - (Uint *) a3, + (UWord *) a3, (Uint) 0); case 0x404: erts_mseg_clear_cache(); @@ -1788,405 +1610,3 @@ erts_mseg_test(UWord op, UWord a1, UWord a2, UWord a3) } } - - -#if HALFWORD_HEAP -/* - * Very simple page oriented mmap replacer. Works in the lower - * 32 bit address range of a 64bit program. - * Implements anonymous mmap mremap and munmap with address order first fit. - * The free list is expected to be very short... - * To be used for compressed pointers in Erlang halfword emulator - * implementation. The MacOS X version is more of a toy, it's not really - * for production as the halfword erlang VM relies on Linux specific memory - * mapping tricks. - */ - -/* #define HARDDEBUG 1 */ - -#ifdef HARDDEBUG -static void dump_freelist(void) -{ - FreeBlock *p = first; - - while (p) { - fprintf(stderr, "p = %p\r\np->num = %ld\r\np->next = %p\r\n\r\n", - (void *) p, (unsigned long) p->num, (void *) p->next); - p = p->next; - } -} - -#define HARDDEBUG_HW_INCOMPLETE_ALIGNMENT(PTR, SZ) \ - fprintf(stderr,"Mapping of address %p with size %ld " \ - "does not map complete pages (%s:%d)\r\n", \ - (void *) (PTR), (unsigned long) (SZ),__FILE__, __LINE__) - -#define HARDDEBUG_HW_UNALIGNED_ALIGNMENT(PTR, SZ) \ - fprintf(stderr,"Mapping of address %p with size %ld " \ - "is not page aligned (%s:%d)\r\n", \ - (void *) (PTR), (unsigned long) (SZ),__FILE__, __LINE__) - -#define HARDDEBUG_MAP_FAILED(PTR, SZ) \ - fprintf(stderr, "Could not actually map memory " \ - "at address %p with size %ld (%s:%d) ..\r\n", \ - (void *) (PTR), (unsigned long) (SZ),__FILE__, __LINE__) -#else -#define HARDDEBUG_HW_INCOMPLETE_ALIGNMENT(PTR, SZ) do{}while(0) -#define HARDDEBUG_HW_UNALIGNED_ALIGNMENT(PTR, SZ) do{}while(0) -#define HARDDEBUG_MAP_FAILED(PTR, SZ) do{}while(0) -#endif - - -#ifdef __APPLE__ -#define MAP_ANONYMOUS MAP_ANON -#endif - -#define INIT_LOCK() do {erts_mtx_init(&pmmap_mutex, "pmmap");} while(0) - -#define TAKE_LOCK() do {erts_mtx_lock(&pmmap_mutex);} while(0) - -#define RELEASE_LOCK() do {erts_mtx_unlock(&pmmap_mutex);} while(0) - -static erts_mtx_t pmmap_mutex; /* Also needed when !USE_THREADS */ - -typedef struct _free_block { - unsigned long num; /*pages*/ - struct _free_block *next; -} FreeBlock; - -/* Protect with lock */ -static FreeBlock *first; - -static void *do_map(void *ptr, size_t sz) -{ - void *res; - - if (ALIGNED_CEILING(sz) != sz) { - HARDDEBUG_HW_INCOMPLETE_ALIGNMENT(ptr, sz); - return NULL; - } - - if (((unsigned long) ptr) % MSEG_ALIGNED_SIZE) { - HARDDEBUG_HW_UNALIGNED_ALIGNMENT(ptr, sz); - return NULL; - } - -#if HAVE_MMAP - res = mmap(ptr, sz, - PROT_READ | PROT_WRITE, MAP_PRIVATE | - MAP_ANONYMOUS | MAP_FIXED, - -1 , 0); -#else -# error "Missing mmap support" -#endif - - if (res == MAP_FAILED) { - HARDDEBUG_MAP_FAILED(ptr, sz); - return NULL; - } - - return res; -} - -static int do_unmap(void *ptr, size_t sz) -{ - void *res; - - if (ALIGNED_CEILING(sz) != sz) { - HARDDEBUG_HW_INCOMPLETE_ALIGNMENT(ptr, sz); - return 1; - } - - if (((unsigned long) ptr) % MSEG_ALIGNED_SIZE) { - HARDDEBUG_HW_UNALIGNED_ALIGNMENT(ptr, sz); - return 1; - } - - res = mmap(ptr, sz, - PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE | MAP_FIXED, - -1 , 0); - - if (res == MAP_FAILED) { - HARDDEBUG_MAP_FAILED(ptr, sz); - return 1; - } - - return 0; -} - -#ifdef __APPLE__ -/* - * The first 4 gig's are protected on Macos X for 64bit processes :( - * The range 0x1000000000 - 0x10FFFFFFFF is selected as an arbitrary - * value of a normally unused range... Real MMAP's will avoid - * it and all 32bit compressed pointers can be in that range... - * More expensive than on Linux where expansion of compressed - * poiters involves no masking (as they are in the first 4 gig's). - * It's also very uncertain if the MAP_NORESERVE flag really has - * any effect in MacOS X. Swap space may always be allocated... - */ -#define SET_RANGE_MIN() /* nothing */ -#define RANGE_MIN 0x1000000000UL -#define RANGE_MAX 0x1100000000UL -#define RANGE_MASK (RANGE_MIN) -#define EXTRA_MAP_FLAGS (MAP_FIXED) -#else -static size_t range_min; -#define SET_RANGE_MIN() do { range_min = (size_t) sbrk(0); } while (0) -#define RANGE_MIN range_min -#define RANGE_MAX 0x100000000UL -#define RANGE_MASK 0UL -#define EXTRA_MAP_FLAGS (0) -#endif - -static int initialize_pmmap(void) -{ - char *p,*q,*rptr; - size_t rsz; - FreeBlock *initial; - - SET_RANGE_MIN(); - if (sizeof(void *) != 8) { - erl_exit(1,"Halfword emulator cannot be run in 32bit mode"); - } - - p = (char *) RANGE_MIN; - q = (char *) RANGE_MAX; - - rsz = ALIGNED_FLOOR(q - p); - - rptr = mmap_align(NULL, (void *) p, rsz, - PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS | - MAP_NORESERVE | EXTRA_MAP_FLAGS, - -1 , 0); -#ifdef HARDDEBUG - printf("p=%p, rsz = %ld, pages = %ld, got range = %p -> %p\r\n", - p, (unsigned long) rsz, (unsigned long) (rsz / MSEG_ALIGNED_SIZE), - (void *) rptr, (void*)(rptr + rsz)); -#endif - if ((UWord)(rptr + rsz) > RANGE_MAX) { - size_t rsz_trunc = RANGE_MAX - (UWord)rptr; -#ifdef HARDDEBUG - printf("Reducing mmap'ed memory from %lu to %lu Mb, reduced range = %p -> %p\r\n", - rsz/(1024*1024), rsz_trunc/(1024*1024), rptr, rptr+rsz_trunc); -#endif - munmap((void*)RANGE_MAX, rsz - rsz_trunc); - rsz = rsz_trunc; - } - if (!do_map(rptr, MSEG_ALIGNED_SIZE)) { - erl_exit(1,"Could not actually mmap first page for halfword emulator...\n"); - } - initial = (FreeBlock *) rptr; - initial->num = (rsz / MSEG_ALIGNED_SIZE); - initial->next = NULL; - first = initial; - INIT_LOCK(); - return 0; -} - -static void *pmmap(size_t size) -{ - size_t real_size = ALIGNED_CEILING(size); - size_t num_pages = real_size / MSEG_ALIGNED_SIZE; - FreeBlock **block; - FreeBlock *tail; - FreeBlock *res; - - TAKE_LOCK(); - - for (block = &first; - *block != NULL && (*block)->num < num_pages; - block = &((*block)->next)) - ; - if (!(*block)) { - RELEASE_LOCK(); - return NULL; - } - if ((*block)->num == num_pages) { - /* nice, perfect fit */ - res = *block; - *block = (*block)->next; - } else { - tail = (FreeBlock *) (((char *) ((void *) (*block))) + real_size); - if (!do_map(tail, MSEG_ALIGNED_SIZE)) { - HARDDEBUG_MAP_FAILED(tail, MSEG_ALIGNED_SIZE); - RELEASE_LOCK(); - return NULL; - } - tail->num = (*block)->num - num_pages; - tail->next = (*block)->next; - res = *block; - *block = tail; - } - - RELEASE_LOCK(); - - if (!do_map(res, real_size)) { - HARDDEBUG_MAP_FAILED(res, real_size); - return NULL; - } - - return (void *) res; -} - -static int pmunmap(void *p, size_t size) -{ - size_t real_size = ALIGNED_CEILING(size); - size_t num_pages = real_size / MSEG_ALIGNED_SIZE; - - FreeBlock *block; - FreeBlock *last; - FreeBlock *nb = (FreeBlock *) p; - - ASSERT(((unsigned long)p & CHECK_POINTER_MASK)==0); - - if (real_size > MSEG_ALIGNED_SIZE) { - if (do_unmap(((char *) p) + MSEG_ALIGNED_SIZE, real_size - MSEG_ALIGNED_SIZE)) { - return 1; - } - } - - TAKE_LOCK(); - - last = NULL; - block = first; - while(block != NULL && ((void *) block) < p) { - last = block; - block = block->next; - } - - if (block != NULL && - ((void *) block) == ((void *) (((char *) p) + real_size))) { - /* Merge new free block with following */ - nb->num = block->num + num_pages; - nb->next = block->next; - if (do_unmap(block, MSEG_ALIGNED_SIZE)) { - RELEASE_LOCK(); - return 1; - } - } else { - /* just link in */ - nb->num = num_pages; - nb->next = block; - } - if (last != NULL) { - if (p == ((void *) (((char *) last) + (last->num * MSEG_ALIGNED_SIZE)))) { - /* Merge with previous */ - last->num += nb->num; - last->next = nb->next; - if (do_unmap(nb, MSEG_ALIGNED_SIZE)) { - RELEASE_LOCK(); - return 1; - } - } else { - last->next = nb; - } - } else { - first = nb; - } - RELEASE_LOCK(); - return 0; -} - -static void *pmremap(void *old_address, size_t old_size, - size_t new_size) -{ - size_t new_real_size = ALIGNED_CEILING(new_size); - size_t new_num_pages = new_real_size / MSEG_ALIGNED_SIZE; - size_t old_real_size = ALIGNED_CEILING(old_size); - size_t old_num_pages = old_real_size / MSEG_ALIGNED_SIZE; - if (new_num_pages == old_num_pages) { - return old_address; - } else if (new_num_pages < old_num_pages) { /* Shrink */ - size_t nfb_pages = old_num_pages - new_num_pages; - size_t nfb_real_size = old_real_size - new_real_size; - void *vnfb = (void *) (((char *)old_address) + new_real_size); - FreeBlock *nfb = (FreeBlock *) vnfb; - FreeBlock **block; - TAKE_LOCK(); - for (block = &first; - *block != NULL && (*block) < nfb; - block = &((*block)->next)) - ; - if (!(*block) || - (*block) > ((FreeBlock *)(((char *) vnfb) + nfb_real_size))) { - /* Normal link in */ - if (nfb_pages > 1) { - if (do_unmap((void *)(((char *) vnfb) + MSEG_ALIGNED_SIZE), - (nfb_pages - 1)*MSEG_ALIGNED_SIZE)) { - return NULL; - } - } - nfb->next = (*block); - nfb->num = nfb_pages; - (*block) = nfb; - } else { /* block merge */ - nfb->next = (*block)->next; - nfb->num = nfb_pages + (*block)->num; - /* unmap also the first page of the next freeblock */ - (*block) = nfb; - if (do_unmap((void *)(((char *) vnfb) + MSEG_ALIGNED_SIZE), - nfb_pages*MSEG_ALIGNED_SIZE)) { - return NULL; - } - } - RELEASE_LOCK(); - return old_address; - } else { /* Enlarge */ - FreeBlock **block; - void *old_end = (void *) (((char *)old_address) + old_real_size); - TAKE_LOCK(); - for (block = &first; - *block != NULL && (*block) < (FreeBlock *) old_address; - block = &((*block)->next)) - ; - if ((*block) == NULL || old_end > ((void *) RANGE_MAX) || - (*block) != old_end || - (*block)->num < (new_num_pages - old_num_pages)) { - /* cannot extend */ - void *result; - RELEASE_LOCK(); - result = pmmap(new_size); - if (result == NULL) { - return NULL; - } - memcpy(result,old_address,old_size); - if (pmunmap(old_address,old_size)) { - /* Oups... */ - pmunmap(result,new_size); - return NULL; - } - return result; - } else { /* extend */ - size_t remaining_pages = (*block)->num - - (new_num_pages - old_num_pages); - if (!remaining_pages) { - void *p = (void *) (((char *) (*block)) + MSEG_ALIGNED_SIZE); - void *n = (*block)->next; - size_t x = ((*block)->num - 1) * MSEG_ALIGNED_SIZE; - if (x > 0) { - if (do_map(p,x) == NULL) { - RELEASE_LOCK(); - return NULL; - } - } - (*block) = n; - } else { - FreeBlock *nfb = (FreeBlock *) ((void *) - (((char *) old_address) + - new_real_size)); - void *p = (void *) (((char *) (*block)) + MSEG_ALIGNED_SIZE); - if (do_map(p,new_real_size - old_real_size) == NULL) { - RELEASE_LOCK(); - return NULL; - } - nfb->num = remaining_pages; - nfb->next = (*block)->next; - (*block) = nfb; - } - RELEASE_LOCK(); - return old_address; - } - } -} -#endif /* HALFWORD_HEAP */ diff --git a/erts/emulator/sys/common/erl_mseg.h b/erts/emulator/sys/common/erl_mseg.h index a4f250ceab..2284b3f8f1 100644 --- a/erts/emulator/sys/common/erl_mseg.h +++ b/erts/emulator/sys/common/erl_mseg.h @@ -22,25 +22,25 @@ #include "sys.h" #include "erl_alloc_types.h" +#include "erl_mmap.h" -#ifndef HAVE_MMAP -# define HAVE_MMAP 0 -#endif -#ifndef HAVE_MREMAP -# define HAVE_MREMAP 0 -#endif - -#if HAVE_MMAP +/* + * We currently only enable mseg_alloc if we got + * a genuine mmap()/munmap() primitive. It is possible + * to utilize erts_mmap() withiout a mmap support but + * alloc_util needs to be prepared before we can do + * that. + */ +#ifdef ERTS_HAVE_GENUINE_OS_MMAP # define HAVE_ERTS_MSEG 1 -# define HAVE_SUPER_ALIGNED_MB_CARRIERS 1 +# define ERTS_HAVE_MSEG_SUPER_ALIGNED 1 #else # define HAVE_ERTS_MSEG 0 -# define HAVE_SUPER_ALIGNED_MB_CARRIERS 0 +# define ERTS_HAVE_MSEG_SUPER_ALIGNED 0 #endif -#if HAVE_SUPER_ALIGNED_MB_CARRIERS -# define MSEG_ALIGN_BITS (18) - /* Affects hard limits for sbct and lmbcs documented in erts_alloc.xml */ +#if ERTS_HAVE_MSEG_SUPER_ALIGNED +# define MSEG_ALIGN_BITS ERTS_MMAP_SUPERALIGNED_BITS #else /* If we don't use super aligned multiblock carriers * we will mmap with page size alignment (and thus use corresponding @@ -68,6 +68,7 @@ typedef struct { Uint rmcbf; Uint mcs; Uint nos; + ErtsMMapInit mmap; } ErtsMsegInit_t; #define ERTS_MSEG_INIT_DEFAULT_INITIALIZER \ @@ -75,7 +76,8 @@ typedef struct { 4*1024*1024, /* amcbf: Absolute max cache bad fit */ \ 20, /* rmcbf: Relative max cache bad fit */ \ 10, /* mcs: Max cache size */ \ - 1000 /* cci: Cache check interval */ \ + 1000, /* cci: Cache check interval */ \ + ERTS_MMAP_INIT_DEFAULT_INITER \ } typedef struct { @@ -91,12 +93,12 @@ typedef struct { extern const ErtsMsegOpt_t erts_mseg_default_opt; -void *erts_mseg_alloc(ErtsAlcType_t, Uint *, Uint); -void *erts_mseg_alloc_opt(ErtsAlcType_t, Uint *, Uint, const ErtsMsegOpt_t *); -void erts_mseg_dealloc(ErtsAlcType_t, void *, Uint, Uint); -void erts_mseg_dealloc_opt(ErtsAlcType_t, void *, Uint, Uint, const ErtsMsegOpt_t *); -void *erts_mseg_realloc(ErtsAlcType_t, void *, Uint, Uint *, Uint); -void *erts_mseg_realloc_opt(ErtsAlcType_t, void *, Uint, Uint *, Uint, const ErtsMsegOpt_t *); +void *erts_mseg_alloc(ErtsAlcType_t, UWord *, Uint); +void *erts_mseg_alloc_opt(ErtsAlcType_t, UWord *, Uint, const ErtsMsegOpt_t *); +void erts_mseg_dealloc(ErtsAlcType_t, void *, UWord, Uint); +void erts_mseg_dealloc_opt(ErtsAlcType_t, void *, UWord, Uint, const ErtsMsegOpt_t *); +void *erts_mseg_realloc(ErtsAlcType_t, void *, UWord, UWord *, Uint); +void *erts_mseg_realloc_opt(ErtsAlcType_t, void *, UWord, UWord *, Uint, const ErtsMsegOpt_t *); void erts_mseg_clear_cache(void); void erts_mseg_cache_check(void); Uint erts_mseg_no( const ErtsMsegOpt_t *); diff --git a/erts/emulator/sys/common/erl_poll.c b/erts/emulator/sys/common/erl_poll.c index 5861b30315..7676d8872a 100644 --- a/erts/emulator/sys/common/erl_poll.c +++ b/erts/emulator/sys/common/erl_poll.c @@ -123,8 +123,8 @@ static ERTS_INLINE int ERTS_SELECT(int nfds, ERTS_fd_set *readfds, ERTS_fd_set *writefds, ERTS_fd_set *exceptfds, struct timeval *timeout) { - ASSERT(!readfds || readfds->sz >= nfds); - ASSERT(!writefds || writefds->sz >= nfds); + ASSERT(!readfds || readfds->sz >= ERTS_FD_SIZE(nfds)); + ASSERT(!writefds || writefds->sz >= ERTS_FD_SIZE(nfds)); ASSERT(!exceptfds); return select(nfds, (readfds ? readfds->ptr : NULL ), diff --git a/erts/emulator/sys/unix/erl_unix_sys.h b/erts/emulator/sys/unix/erl_unix_sys.h index c8fcec8547..2c47aa06c2 100644 --- a/erts/emulator/sys/unix/erl_unix_sys.h +++ b/erts/emulator/sys/unix/erl_unix_sys.h @@ -107,6 +107,10 @@ #endif #include <netdb.h> +#ifdef HAVE_POSIX_MEMALIGN +# define ERTS_HAVE_ERTS_SYS_ALIGNED_ALLOC 1 +#endif + /* * Make sure that MAXPATHLEN is defined. */ diff --git a/erts/emulator/sys/unix/sys.c b/erts/emulator/sys/unix/sys.c index a7ea4b2490..401b37b9d2 100644 --- a/erts/emulator/sys/unix/sys.c +++ b/erts/emulator/sys/unix/sys.c @@ -2524,6 +2524,52 @@ void erts_sys_alloc_init(void) { } +#if ERTS_HAVE_ERTS_SYS_ALIGNED_ALLOC +void *erts_sys_aligned_alloc(UWord alignment, UWord size) +{ +#ifdef HAVE_POSIX_MEMALIGN + void *ptr = NULL; + int error; + ASSERT(alignment && (alignment & ~alignment) == 0); /* power of 2 */ + error = posix_memalign(&ptr, (size_t) alignment, (size_t) size); +#if HAVE_ERTS_MSEG + if (error || !ptr) { + erts_mseg_clear_cache(); + error = posix_memalign(&ptr, (size_t) alignment, (size_t) size); + } +#endif + if (error) { + errno = error; + return NULL; + } + if (!ptr) + errno = ENOMEM; + ASSERT(!ptr || (((UWord) ptr) & (alignment - 1)) == 0); + return ptr; +#else +# error "Missing erts_sys_aligned_alloc() implementation" +#endif +} + +void erts_sys_aligned_free(UWord alignment, void *ptr) +{ + ASSERT(alignment && (alignment & ~alignment) == 0); /* power of 2 */ + free(ptr); +} + +void *erts_sys_aligned_realloc(UWord alignment, void *ptr, UWord size, UWord old_size) +{ + void *new_ptr = erts_sys_aligned_alloc(alignment, size); + if (new_ptr) { + UWord copy_size = old_size < size ? old_size : size; + sys_memcpy(new_ptr, ptr, (size_t) copy_size); + erts_sys_aligned_free(alignment, ptr); + } + return new_ptr; +} + +#endif + void *erts_sys_alloc(ErtsAlcType_t t, void *x, Uint sz) { void *res = malloc((size_t) sz); @@ -2592,15 +2638,13 @@ int fd; } -#ifdef DEBUG - extern int erts_initialized; void -erl_assert_error(char* expr, char* file, int line) +erl_assert_error(const char* expr, const char* func, const char* file, int line) { fflush(stdout); - fprintf(stderr, "Assertion failed: %s in %s, line %d\n", - expr, file, line); + fprintf(stderr, "%s:%d:%s() Assertion failed: %s\n", + file, line, func, expr); fflush(stderr); #if !defined(ERTS_SMP) && 0 /* Writing a crashdump from a failed assertion when smp support @@ -2615,6 +2659,8 @@ erl_assert_error(char* expr, char* file, int line) abort(); } +#ifdef DEBUG + void erl_debug(char* fmt, ...) { diff --git a/erts/emulator/sys/win32/erl_win_sys.h b/erts/emulator/sys/win32/erl_win_sys.h index 5ce1a61303..0deb097b1a 100644 --- a/erts/emulator/sys/win32/erl_win_sys.h +++ b/erts/emulator/sys/win32/erl_win_sys.h @@ -82,7 +82,6 @@ #define NO_ERF #define NO_ERFC -#define NO_SYSLOG #define NO_SYSCONF #define NO_DAEMON #define NO_PWD @@ -95,6 +94,8 @@ # define ERTS_I64_LITERAL(X) X##i64 #endif +#define ERTS_HAVE_ERTS_SYS_ALIGNED_ALLOC 1 + /* * Practial Windows specific macros. */ diff --git a/erts/emulator/sys/win32/sys.c b/erts/emulator/sys/win32/sys.c index 93bbae7dee..5ea4703a7a 100755 --- a/erts/emulator/sys/win32/sys.c +++ b/erts/emulator/sys/win32/sys.c @@ -32,7 +32,7 @@ #include "erl_threads.h" #include "../../drivers/win32/win_con.h" #include "erl_cpu_topology.h" - +#include <malloc.h> void erts_sys_init_float(void); @@ -2754,6 +2754,30 @@ void erts_sys_free(ErtsAlcType_t t, void *x, void *p) free(p); } +void *erts_sys_aligned_alloc(UWord alignment, UWord size) +{ + void *ptr; + ASSERT(alignment && (alignment & ~alignment) == 0); /* power of 2 */ + ptr = _aligned_malloc((size_t) size, (size_t) alignment); + ASSERT(!ptr || (((UWord) ptr) & (alignment - 1)) == 0); + return ptr; +} + +void erts_sys_aligned_free(UWord alignment, void *ptr) +{ + ASSERT(alignment && (alignment & ~alignment) == 0); /* power of 2 */ + _aligned_free(ptr); +} + +void *erts_sys_aligned_realloc(UWord alignment, void *ptr, UWord size, UWord old_size) +{ + void *new_ptr; + ASSERT(alignment && (alignment & ~alignment) == 0); /* power of 2 */ + new_ptr = _aligned_realloc(ptr, (size_t) size, (size_t) alignment); + ASSERT(!new_ptr || (((UWord) new_ptr) & (alignment - 1)) == 0); + return new_ptr; +} + static Preload* preloaded = NULL; static unsigned* res_name = NULL; static int num_preloaded = 0; @@ -3042,7 +3066,7 @@ erl_bin_write(buf, sz, max) } void -erl_assert_error(char* expr, char* file, int line) +erl_assert_error(const char* expr, const char* func, const char* file, int line) { char message[1024]; diff --git a/erts/emulator/test/alloc_SUITE.erl b/erts/emulator/test/alloc_SUITE.erl index 801ed0f85a..f6ff6bb813 100644 --- a/erts/emulator/test/alloc_SUITE.erl +++ b/erts/emulator/test/alloc_SUITE.erl @@ -29,6 +29,7 @@ bucket_mask/1, rbtree/1, mseg_clear_cache/1, + erts_mmap/1, cpool/1]). -export([init_per_testcase/2, end_per_testcase/2]). @@ -41,7 +42,7 @@ suite() -> [{ct_hooks,[ts_install_cth]}]. all() -> [basic, coalesce, threads, realloc_copy, bucket_index, - bucket_mask, rbtree, mseg_clear_cache, cpool]. + bucket_mask, rbtree, mseg_clear_cache, erts_mmap, cpool]. groups() -> []. @@ -110,6 +111,59 @@ cpool(suite) -> []; cpool(doc) -> []; cpool(Cfg) -> ?line drv_case(Cfg). +erts_mmap(Config) when is_list(Config) -> + case {?t:os_type(), is_halfword_vm()} of + {{unix, _}, false} -> + [erts_mmap_do(Config, SCO, SCRPM, SCMGC) + || SCO <-[true,false], SCMGC <-[1234,0], SCRPM <- [true,false]]; + + {_,true} -> + {skipped, "No supercarrier support on halfword vm"}; + {SkipOs,_} -> + ?line {skipped, + lists:flatten(["Not run on " + | io_lib:format("~p",[SkipOs])])} + end. + + +erts_mmap_do(Config, SCO, SCRPM, SCMGC) -> + SCS = 100, % Mb + O1 = "+MMscs" ++ integer_to_list(SCS) + ++ " +MMsco" ++ atom_to_list(SCO) + ++ " +MMscrpm" ++ atom_to_list(SCRPM), + Opts = case SCMGC of + 0 -> O1; + _ -> O1 ++ " +MMscmgc"++integer_to_list(SCMGC) + end, + {ok, Node} = start_node(Config, Opts), + Self = self(), + Ref = make_ref(), + F = fun () -> + SI = erlang:system_info({allocator,mseg_alloc}), + {erts_mmap,EM} = lists:keyfind(erts_mmap, 1, SI), + {supercarrier,SC} = lists:keyfind(supercarrier, 1, EM), + {sizes,Sizes} = lists:keyfind(sizes, 1, SC), + {free_segs,Segs} = lists:keyfind(free_segs,1,SC), + {total,Total} = lists:keyfind(total,1,Sizes), + Total = SCS*1024*1024, + + {reserved,Reserved} = lists:keyfind(reserved,1,Segs), + true = (Reserved >= SCMGC), + + case {SCO,lists:keyfind(os,1,EM)} of + {true, false} -> ok; + {false, {os,_}} -> ok + end, + + Self ! {Ref, ok} + end, + + spawn_link(Node, F), + Result = receive {Ref, Rslt} -> Rslt end, + stop_node(Node), + Result. + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% %% %% Internal functions %% @@ -179,7 +233,9 @@ receive_drv_result(Port, CaseName) -> ?line {comment, Comment} end. -start_node(Config) when is_list(Config) -> +start_node(Config) -> + start_node(Config, []). +start_node(Config, Opts) when is_list(Config), is_list(Opts) -> ?line Pa = filename:dirname(code:which(?MODULE)), ?line {A, B, C} = now(), ?line Name = list_to_atom(atom_to_list(?MODULE) @@ -191,7 +247,14 @@ start_node(Config) when is_list(Config) -> ++ integer_to_list(B) ++ "-" ++ integer_to_list(C)), - ?line ?t:start_node(Name, slave, [{args, "-pa "++Pa}]). + ?line ?t:start_node(Name, slave, [{args, Opts++" -pa "++Pa}]). stop_node(Node) -> ?t:stop_node(Node). + +is_halfword_vm() -> + case {erlang:system_info({wordsize, internal}), + erlang:system_info({wordsize, external})} of + {4, 8} -> true; + {WS, WS} -> false + end. diff --git a/erts/emulator/test/big_SUITE_data/eq_big.dat b/erts/emulator/test/big_SUITE_data/eq_big.dat index 5511d1bf10..4ccb33d182 100644 --- a/erts/emulator/test/big_SUITE_data/eq_big.dat +++ b/erts/emulator/test/big_SUITE_data/eq_big.dat @@ -13001,4 +13001,5 @@ 0 = 7153697524993 bsr 475833444444444444444444444444444444444444444444. -1 = -83987348 bsr 475833444444444444444444444444444444444444444444. +0 = 1183140560213014108063589658350 bsr 146783911423364576743092537299333564210980159306769991919205685720763064069663027716481187399048043939495935. diff --git a/erts/emulator/test/call_trace_SUITE.erl b/erts/emulator/test/call_trace_SUITE.erl index eaecd32f95..ef1f2aa04c 100644 --- a/erts/emulator/test/call_trace_SUITE.erl +++ b/erts/emulator/test/call_trace_SUITE.erl @@ -1193,7 +1193,7 @@ bs_sum_b(Acc, <<>>) -> Acc. - + %%% Help functions. expect() -> diff --git a/erts/emulator/test/driver_SUITE.erl b/erts/emulator/test/driver_SUITE.erl index 104bdf8aec..7087542899 100644 --- a/erts/emulator/test/driver_SUITE.erl +++ b/erts/emulator/test/driver_SUITE.erl @@ -367,7 +367,7 @@ compare(Got, Expected) -> ?t:fail(got_bad_data) end. - + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Driver timer test suites %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -515,7 +515,7 @@ try_change_timer(Port, Timeout) -> ?line test_server:fail("driver failed to timeout") end. - + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Queue test suites %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -719,7 +719,7 @@ deq(Port, Size) -> read_head(Port, Size) -> erlang:port_control(Port, ?READ_HEAD, <<Size:32>>). - + driver_unloaded(doc) -> []; driver_unloaded(suite) -> diff --git a/erts/emulator/test/num_bif_SUITE.erl b/erts/emulator/test/num_bif_SUITE.erl index b92a0e2059..ff8d18eef8 100644 --- a/erts/emulator/test/num_bif_SUITE.erl +++ b/erts/emulator/test/num_bif_SUITE.erl @@ -350,12 +350,34 @@ t_integer_to_string(Config) when is_list(Config) -> (catch erlang:integer_to_list(Value)) end,[atom,1.2,0.0,[$1,[$2]]]), + %% Base-2 integers + test_its("0", 0, 2), + test_its("1", 1, 2), + test_its("110110", 54, 2), + test_its("-1000000", -64, 2), + %% Base-16 integers + test_its("0", 0, 16), + test_its("A", 10, 16), + test_its("D4BE", 54462, 16), + test_its("-D4BE", -54462, 16), + + lists:foreach(fun(Value) -> + {'EXIT', {badarg, _}} = + (catch erlang:integer_to_binary(Value, 8)), + {'EXIT', {badarg, _}} = + (catch erlang:integer_to_list(Value, 8)) + end,[atom,1.2,0.0,[$1,[$2]]]), + ok. test_its(List,Int) -> Int = list_to_integer(List), Int = binary_to_integer(list_to_binary(List)). +test_its(List,Int,Base) -> + Int = list_to_integer(List, Base), + Int = binary_to_integer(list_to_binary(List), Base). + %% Tests binary_to_integer/1. t_string_to_integer(Config) when is_list(Config) -> diff --git a/erts/emulator/test/scheduler_SUITE.erl b/erts/emulator/test/scheduler_SUITE.erl index 8931562828..81539faa09 100644 --- a/erts/emulator/test/scheduler_SUITE.erl +++ b/erts/emulator/test/scheduler_SUITE.erl @@ -52,6 +52,7 @@ update_cpu_info/1, sct_cmd/1, sbt_cmd/1, + scheduler_threads/1, scheduler_suspend/1, reader_groups/1]). @@ -66,7 +67,7 @@ all() -> equal_with_part_time_max, equal_and_high_with_part_time_max, equal_with_high, equal_with_high_max, bound_process, - {group, scheduler_bind}, scheduler_suspend, + {group, scheduler_bind}, scheduler_threads, scheduler_suspend, reader_groups]. groups() -> @@ -1039,7 +1040,66 @@ sbt_test(Config, CpuTCmd, ClBt, Bt, LP) -> tuple_to_list(SB)), ?line stop_node(Node), ?line ok. - + +scheduler_threads(Config) when is_list(Config) -> + SmpSupport = erlang:system_info(smp_support), + {Sched, SchedOnln, _} = get_sstate(Config, ""), + %% Configure half the number of both the scheduler threads and + %% the scheduler threads online. + {HalfSched, HalfSchedOnln} = case SmpSupport of + false -> {1,1}; + true -> + {Sched div 2, + SchedOnln div 2} + end, + {HalfSched, HalfSchedOnln, _} = get_sstate(Config, "+SP 50:50"), + %% Use +S to configure 4x the number of scheduler threads and + %% 4x the number of scheduler threads online, but alter that + %% setting using +SP to 50% scheduler threads and 25% scheduler + %% threads online. The result should be 2x scheduler threads and + %% 1x scheduler threads online. + TwiceSched = case SmpSupport of + false -> 1; + true -> Sched*2 + end, + FourSched = integer_to_list(Sched*4), + FourSchedOnln = integer_to_list(SchedOnln*4), + CombinedCmd1 = "+S "++FourSched++":"++FourSchedOnln++" +SP50:25", + {TwiceSched, SchedOnln, _} = get_sstate(Config, CombinedCmd1), + %% Now do the same test but with the +S and +SP options in the + %% opposite order, since order shouldn't matter. + CombinedCmd2 = "+SP50:25 +S "++FourSched++":"++FourSchedOnln, + {TwiceSched, SchedOnln, _} = get_sstate(Config, CombinedCmd2), + %% Apply two +SP options to make sure the second overrides the first + TwoCmd = "+SP 25:25 +SP 100:100", + {Sched, SchedOnln, _} = get_sstate(Config, TwoCmd), + %% Configure 50% of scheduler threads online only + {Sched, HalfSchedOnln, _} = get_sstate(Config, "+SP:50"), + %% Configure 2x scheduler threads only + {TwiceSched, SchedOnln, _} = get_sstate(Config, "+SP 200"), + %% Test resetting the scheduler counts + ResetCmd = "+S "++FourSched++":"++FourSchedOnln++" +S 0:0", + {Sched, SchedOnln, _} = get_sstate(Config, ResetCmd), + %% Test negative +S settings, but only for SMP-enabled emulators + case SmpSupport of + false -> ok; + true -> + SchedMinus1 = Sched-1, + SchedOnlnMinus1 = SchedOnln-1, + {SchedMinus1, SchedOnlnMinus1, _} = get_sstate(Config, "+S -1"), + {Sched, SchedOnlnMinus1, _} = get_sstate(Config, "+S :-1"), + {SchedMinus1, SchedOnlnMinus1, _} = get_sstate(Config, "+S -1:-1") + end, + ok. + +get_sstate(Config, Cmd) -> + {ok, Node} = start_node(Config, Cmd), + [SState] = mcall(Node, [fun () -> + erlang:system_info(schedulers_state) + end]), + stop_node(Node), + SState. + scheduler_suspend(Config) when is_list(Config) -> ?line Dog = ?t:timetrap(?t:minutes(5)), ?line lists:foreach(fun (S) -> scheduler_suspend_test(Config, S) end, diff --git a/erts/emulator/test/statistics_SUITE.erl b/erts/emulator/test/statistics_SUITE.erl index a93dd309c1..c428be6c5a 100644 --- a/erts/emulator/test/statistics_SUITE.erl +++ b/erts/emulator/test/statistics_SUITE.erl @@ -75,7 +75,7 @@ end_per_group(_GroupName, Config) -> Config. - + %%% Testing statistics(wall_clock). @@ -121,7 +121,7 @@ wall_clock_update1(N) when N > 0 -> wall_clock_update1(0) -> ok. - + %%% Test statistics(runtime). @@ -199,7 +199,7 @@ do_much(N) -> _ = 4784728478274827 * 72874284728472, do_much(N-1). - + reductions(doc) -> "Test that statistics(reductions) is callable, and that " "Total_Reductions and Reductions_Since_Last_Call make sense. " @@ -246,7 +246,7 @@ reductions_big_loop() -> reductions_big_loop() end. - + %%% Tests of statistics(run_queue). @@ -295,7 +295,7 @@ hog_iter(N, Mon) when N > 0 -> end; hog_iter(0, Mon) -> ?line hog_iter(10000, Mon). - + %%% Tests of statistics(scheduler_wall_time). scheduler_wall_time(doc) -> @@ -363,7 +363,7 @@ load_percentage([{Id, WN, TN}|Ss], [{Id, WP, TP}|Ps]) -> [100*(WN-WP) div (TN-TP)|load_percentage(Ss, Ps)]; load_percentage([], []) -> []. - + garbage_collection(doc) -> "Tests that statistics(garbage_collection) is callable. " "It is not clear how to test anything more."; diff --git a/erts/emulator/test/system_info_SUITE.erl b/erts/emulator/test/system_info_SUITE.erl index 0350eb671d..ceb4afb5cf 100644 --- a/erts/emulator/test/system_info_SUITE.erl +++ b/erts/emulator/test/system_info_SUITE.erl @@ -37,7 +37,8 @@ init_per_group/2,end_per_group/2, init_per_testcase/2, end_per_testcase/2]). --export([process_count/1, system_version/1, misc_smoke_tests/1, heap_size/1, wordsize/1, memory/1]). +-export([process_count/1, system_version/1, misc_smoke_tests/1, heap_size/1, wordsize/1, memory/1, + ets_limit/1]). -define(DEFAULT_TIMEOUT, ?t:minutes(2)). @@ -45,7 +46,7 @@ suite() -> [{ct_hooks,[ts_install_cth]}]. all() -> [process_count, system_version, misc_smoke_tests, - heap_size, wordsize, memory]. + heap_size, wordsize, memory, ets_limit]. groups() -> []. @@ -496,3 +497,52 @@ mapn(_Fun, 0) -> []; mapn(Fun, N) -> [Fun(N) | mapn(Fun, N-1)]. + +ets_limit(doc) -> + "Verify system_info(ets_limit) reflects max ETS table settings."; +ets_limit(suite) -> []; +ets_limit(Config0) when is_list(Config0) -> + Config = [{testcase,ets_limit}|Config0], + true = is_integer(get_ets_limit(Config)), + 12345 = get_ets_limit(Config, 12345), + ok. + +get_ets_limit(Config) -> + get_ets_limit(Config, 0). +get_ets_limit(Config, EtsMax) -> + Envs = case EtsMax of + 0 -> []; + _ -> [{"ERL_MAX_ETS_TABLES", integer_to_list(EtsMax)}] + end, + {ok, Node} = start_node(Config, Envs), + Me = self(), + Ref = make_ref(), + spawn_link(Node, + fun() -> + Res = erlang:system_info(ets_limit), + unlink(Me), + Me ! {Ref, Res} + end), + receive + {Ref, Res} -> + Res + end, + stop_node(Node), + Res. + +start_node(Config, Envs) when is_list(Config) -> + Pa = filename:dirname(code:which(?MODULE)), + {A, B, C} = now(), + Name = list_to_atom(atom_to_list(?MODULE) + ++ "-" + ++ atom_to_list(?config(testcase, Config)) + ++ "-" + ++ integer_to_list(A) + ++ "-" + ++ integer_to_list(B) + ++ "-" + ++ integer_to_list(C)), + ?t:start_node(Name, peer, [{args, "-pa "++Pa}, {env, Envs}]). + +stop_node(Node) -> + ?t:stop_node(Node). diff --git a/erts/emulator/test/time_SUITE.erl b/erts/emulator/test/time_SUITE.erl index 4d12e3449c..a0a8a9c42c 100644 --- a/erts/emulator/test/time_SUITE.erl +++ b/erts/emulator/test/time_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1997-2011. All Rights Reserved. +%% Copyright Ericsson AB 1997-2013. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -241,14 +241,26 @@ compare(Utc0, Local) -> %% Two linear times can be subtracted to give their difference %% in seconds. %% -%% XXX Limitations: The length of months and leap years are not -%% taken into account; thus a comparision of dates is only -%% valid if they are in the SAME month. +%% XXX Limitations: Simplified leap year calc will fail for 2100 :-) linear_time({{Year, Mon, Day}, {Hour, Min, Sec}}) -> - 86400*(366*Year + 31*(Mon-1) + (Day-1)) + + 86400*(year_to_days(Year) + month_to_days(Year,Mon) + (Day-1)) + 3600*Hour + 60*Min + Sec. +year_to_days(Year) -> + Year * 365 + (Year-1) div 4. + +month_to_days(Year, Mon) -> + DoM = [31,days_in_february(Year),31,30,31,30,31,31,30,31,30,31], + {PastMonths,_} = lists:split(Mon-1, DoM), + lists:sum(PastMonths). + +days_in_february(Year) -> + case (Year rem 4) of + 0 -> 29; + _ -> 28 + end. + %% This functions returns either the normal timezone or the %% the DST timezone, depending on the given UTC time. %% diff --git a/erts/emulator/test/trace_SUITE.erl b/erts/emulator/test/trace_SUITE.erl index 0f513f0dcb..2251575e5a 100644 --- a/erts/emulator/test/trace_SUITE.erl +++ b/erts/emulator/test/trace_SUITE.erl @@ -1427,7 +1427,7 @@ receive_nothing() -> ok end. - + %%% Models for various kinds of processes. process(Dest) -> diff --git a/erts/emulator/test/trace_port_SUITE.erl b/erts/emulator/test/trace_port_SUITE.erl index cc2eadafbc..99df8da107 100644 --- a/erts/emulator/test/trace_port_SUITE.erl +++ b/erts/emulator/test/trace_port_SUITE.erl @@ -648,7 +648,7 @@ fun_spawn(Fun, Opts) -> % [] % end. - + %%% Models for various kinds of processes. %% Sends messages when ordered to. diff --git a/erts/epmd/src/epmd.c b/erts/epmd/src/epmd.c index 94bb74c876..2d55b37ff3 100644 --- a/erts/epmd/src/epmd.c +++ b/erts/epmd/src/epmd.c @@ -286,7 +286,7 @@ static void run_daemon(EpmdVars *g) /* fork to make sure first child is not a process group leader */ if (( child_pid = fork()) < 0) { -#ifndef NO_SYSLOG +#ifdef HAVE_SYSLOG_H syslog(LOG_ERR,"erlang mapper daemon cant fork %m"); #endif epmd_cleanup_exit(g,1); @@ -312,7 +312,7 @@ static void run_daemon(EpmdVars *g) if ((child_pid = fork()) < 0) { -#ifndef NO_SYSLOG +#ifdef HAVE_SYSLOG_H syslog(LOG_ERR,"erlang mapper daemon cant fork 2'nd time %m"); #endif epmd_cleanup_exit(g,1); @@ -483,7 +483,7 @@ static void dbg_gen_printf(int onsyslog,int perr,int from_level, if (g->is_daemon) { -#ifndef NO_SYSLOG +#ifdef HAVE_SYSLOG_H if (onsyslog) { erts_vsnprintf(buf, DEBUG_BUFFER_SIZE, format, args); diff --git a/erts/epmd/src/epmd_int.h b/erts/epmd/src/epmd_int.h index ac354dcc78..656dbd1f45 100644 --- a/erts/epmd/src/epmd_int.h +++ b/erts/epmd/src/epmd_int.h @@ -25,13 +25,11 @@ definitions ourselves */ #ifdef __WIN32__ -#define NO_SYSLOG #define NO_SYSCONF #define NO_DAEMON #endif #ifdef VXWORKS -#define NO_SYSLOG #define NO_SYSCONF #define NO_DAEMON #define NO_FCNTL @@ -98,7 +96,7 @@ #include <errno.h> -#ifndef NO_SYSLOG +#ifdef HAVE_SYSLOG_H # include <syslog.h> #endif diff --git a/erts/etc/common/erlc.c b/erts/etc/common/erlc.c index add65b87ca..055064abc4 100644 --- a/erts/etc/common/erlc.c +++ b/erts/etc/common/erlc.c @@ -60,7 +60,6 @@ static int eargc; /* Number of arguments in eargv. */ #define PUSH2(s, t) PUSH(s); PUSH(t) #define PUSH3(s, t, u) PUSH2(s, t); PUSH(u) -static char* output_type = NULL; /* Type of output file. */ #ifdef __WIN32__ static int pause_after_execution = 0; #endif @@ -71,7 +70,6 @@ static int pause_after_execution = 0; static char* process_opt(int* pArgc, char*** pArgv, int offset); static void error(char* format, ...); -static void usage(void); static char* emalloc(size_t size); static char* strsave(char* string); static void push_words(char* src); @@ -218,6 +216,7 @@ int main(int argc, char** argv) PUSH2("-mode", "minimal"); PUSH2("-boot", "start_clean"); PUSH3("-s", "erl_compile", "compile_cmdline"); + PUSH("-extra"); /* * Push standard arguments to Erlang. @@ -227,154 +226,31 @@ int main(int argc, char** argv) * Parse all command line switches. */ - while (argc > 1 && (argv[1][0] == '-' || argv[1][0] == '+')) { + while (argc > 1) { /* * Options starting with '+' are passed on to Erlang. */ - if (argv[1][0] == '+') { - PUSH2("@option", argv[1]+1); - } else { - /* - * Interpret options starting with '-'. - */ - + switch (argv[1][0]) { + case '+': + PUSH(argv[1]); + break; + case '-': switch (argv[1][1]) { - case 'b': - output_type = process_opt(&argc, &argv, 0); - PUSH2("@output_type", output_type); - break; - case 'c': /* Allowed for compatibility with 'erl'. */ - if (strcmp(argv[1], "-compile") != 0) - goto error; - break; case 'd': - debug = 1; - break; - case 'D': - { - char* def = process_opt(&argc, &argv, 0); - char* equals; - - def = strsave(def); /* Do not clobber original. */ - if ((equals = strchr(def, '=')) == NULL) { - PUSH2("@d", def); - } else { - *equals = '\0'; - equals++; - PUSH3("@dv", def, equals); - } - } - break; - case 'I': - PUSH2("@i", process_opt(&argc, &argv, 0)); - break; - case 'M': - { - char *buf, *key, *val; - size_t buf_len; - - if (argv[1][2] == '\0') { /* -M */ - /* Push the following options: - * o 'makedep' - * o {makedep_output, standard_io} - */ - buf = strsave("makedep"); - PUSH2("@option", buf); - - key = "makedep_output"; - val = "standard_io"; - buf_len = 1 + strlen(key) + 1 + strlen(val) + 1 + 1; - buf = emalloc(buf_len); - snprintf(buf, buf_len, "{%s,%s}", key, val); - PUSH2("@option", buf); - } else if (argv[1][3] == '\0') { - switch(argv[1][2]) { - case 'D': /* -MD */ - /* Push the following options: - * o 'makedep' - */ - buf = strsave("makedep"); - PUSH2("@option", buf); - break; - case 'F': /* -MF <file> */ - /* Push the following options: - * o 'makedep' - * o {makedep_output, <file>} - */ - buf = strsave("makedep"); - PUSH2("@option", buf); - - key = "makedep_output"; - val = process_opt(&argc, &argv, 1); - buf_len = 1 + strlen(key) + 2 + strlen(val) + 2 + 1; - buf = emalloc(buf_len); - snprintf(buf, buf_len, "{%s,\"%s\"}", key, val); - PUSH2("@option", buf); - break; - case 'T': /* -MT <target> */ - /* Push the following options: - * o {makedep_target, <target>} - */ - key = "makedep_target"; - val = process_opt(&argc, &argv, 1); - buf_len = 1 + strlen(key) + 2 + strlen(val) + 2 + 1; - buf = emalloc(buf_len); - snprintf(buf, buf_len, "{%s,\"%s\"}", key, val); - PUSH2("@option", buf); - break; - case 'Q': /* -MQ <target> */ - /* Push the following options: - * o {makedep_target, <target>} - * o makedep_quote_target - */ - key = "makedep_target"; - val = process_opt(&argc, &argv, 1); - buf_len = 1 + strlen(key) + 2 + strlen(val) + 2 + 1; - buf = emalloc(buf_len); - snprintf(buf, buf_len, "{%s,\"%s\"}", key, val); - PUSH2("@option", buf); - - buf = strsave("makedep_quote_target"); - PUSH2("@option", buf); - break; - case 'G': /* -MG */ - /* Push the following options: - * o makedep_add_missing - */ - buf = strsave("makedep_add_missing"); - PUSH2("@option", buf); - break; - case 'P': /* -MP */ - /* Push the following options: - * o makedep_phony - */ - buf = strsave("makedep_phony"); - PUSH2("@option", buf); - break; - default: - goto error; - } - } + if (argv[1][2] == '\0') { + debug = 1; + } else { + PUSH(argv[1]); } break; - case 'o': - PUSH2("@outdir", process_opt(&argc, &argv, 0)); - break; - case 'O': - PUSH("@optimize"); - if (argv[1][2] == '\0') - PUSH("1"); - else - PUSH(argv[1]+2); - break; case 'p': { int c = argv[1][2]; if (c != 'a' && c != 'z') { - goto error; + PUSH(argv[1]); #ifdef __WIN32__ } else if (strcmp(argv[1], "-pause") == 0) { pause_after_execution = 1; @@ -395,81 +271,21 @@ int main(int argc, char** argv) if (strcmp(argv[1], "-smp") == 0) { UNSHIFT(argv[1]); } else { - goto error; - } - break; - case 'v': /* Verbose. */ - PUSH2("@verbose", "true"); - break; - case 'V': - /** XXX Version perhaps, but of what? **/ - break; - case 'W': /* Enable warnings. */ - if (strcmp(argv[1]+2, "all") == 0) { - PUSH2("@warn", "999"); - } else if (strcmp(argv[1]+2, "error") == 0) { - PUSH2("@option", "warnings_as_errors"); - } else if (isdigit((int)argv[1][2])) { - PUSH2("@warn", argv[1]+2); - } else { - PUSH2("@warn", "1"); - } - break; - case 'E': - case 'S': - case 'P': - { - char* buf; - - /* - * From the given upper-case letter, construct - * a quoted atom. This is a convenience for the - * Erlang compiler, to avoid fighting with the shell's - * quoting. - */ - - buf = emalloc(4); - buf[0] = '\''; - buf[1] = argv[1][1]; - buf[2] = '\''; - buf[3] = '\0'; - - PUSH2("@option", buf); + PUSH(argv[1]); } break; - - case '-': - goto no_more_options; - default: - error: - usage(); + PUSH(argv[1]); break; } + break; + default: + PUSH(argv[1]); + break; } argc--, argv++; } - no_more_options: - - if (argc <= 1) { - /* - * To avoid starting an Erlang system unless absolutely needed - * exit if no files were specified on the command line. - */ - exit(0); - } - - /* - * The rest of the command line must be filenames. Simply push them. - */ - - PUSH("@files"); - while (argc > 1) { - PUSH(argv[1]); - argc--, argv++; - } - /* * Move up the commands for invoking the emulator and adjust eargv * accordingly. @@ -649,53 +465,6 @@ run_erlang(char* progname, char** argv) } static void -usage(void) -{ - static struct { - char* name; - char* desc; - } options[] = { - {"-b type", "type of output file (e.g. jam or beam)"}, - {"-d", "turn on debugging of erlc itself"}, - {"-Dname", "define name"}, - {"-Dname=value", "define name to have value"}, - {"-help", "shows this help text"}, - {"-I path", "where to search for include files"}, - {"-M", "generate a rule for make(1) describing the dependencies"}, - {"-MF file", "write the dependencies to 'file'"}, - {"-MT target", "change the target of the rule emitted by dependency " - "generation"}, - {"-MQ target", "same as -MT but quote characters special to make(1)"}, - {"-MG", "consider missing headers as generated files and add them to " - "the dependencies"}, - {"-MP", "add a phony target for each dependency"}, - {"-MD", "same as -M -MT file (with default 'file')"}, - {"-o name", "name output directory or file"}, - {"-pa path", "add path to the front of Erlang's code path"}, - {"-pz path", "add path to the end of Erlang's code path"}, - {"-smp", "compile using SMP emulator"}, - {"-v", "verbose compiler output"}, - {"-Werror", "make all warnings into errors"}, - {"-W0", "disable warnings"}, - {"-Wnumber", "set warning level to number"}, - {"-Wall", "enable all warnings"}, - {"-W", "enable warnings (default; same as -W1)"}, - {"-E", "generate listing of expanded code (Erlang compiler)"}, - {"-S", "generate assembly listing (Erlang compiler)"}, - {"-P", "generate listing of preprocessed code (Erlang compiler)"}, - {"+term", "pass the Erlang term unchanged to the compiler"}, - }; - int i; - - fprintf(stderr, "Usage:\terlc [options] file.ext ...\n"); - fprintf(stderr, "Options:\n"); - for (i = 0; i < sizeof(options)/sizeof(options[0]); i++) { - fprintf(stderr, "%-14s %s\n", options[i].name, options[i].desc); - } - exit(1); -} - -static void error(char* format, ...) { char sbuf[1024]; diff --git a/erts/etc/common/erlexec.c b/erts/etc/common/erlexec.c index f61d6cdbd3..f212502bb0 100644 --- a/erts/etc/common/erlexec.c +++ b/erts/etc/common/erlexec.c @@ -109,6 +109,10 @@ static char *plusM_other_switches[] = { "Mamcbf", "Mrmcbf", "Mmcs", + "Mscs", + "Mscmgc", + "Msco", + "Mscrpm", "Ye", "Ym", "Ytp", @@ -799,11 +803,11 @@ int main(int argc, char **argv) case 'a': case 'A': case 'b': + case 'e': case 'i': case 'n': case 'P': case 'Q': - case 'S': case 't': case 'T': case 'R': @@ -818,6 +822,19 @@ int main(int argc, char **argv) add_Eargs(argv[i+1]); i++; break; + case 'S': + if (argv[i][2] == 'P') { + if (argv[i][3] != '\0') + goto the_default; + } else if (argv[i][2] != '\0') + goto the_default; + if (i+1 >= argc) + usage(argv[i]); + argv[i][0] = '-'; + add_Eargs(argv[i]); + add_Eargs(argv[i+1]); + i++; + break; case 'B': argv[i][0] = '-'; if (argv[i][2] != '\0') { @@ -1119,7 +1136,9 @@ usage_aux(void) "[+l] [+M<SUBSWITCH> <ARGUMENT>] [+P MAX_PROCS] [+Q MAX_PORTS] " "[+R COMPAT_REL] " "[+r] [+rg READER_GROUPS_LIMIT] [+s SCHEDULER_OPTION] " - "[+S NO_SCHEDULERS:NO_SCHEDULERS_ONLINE] [+T LEVEL] [+V] [+v] " + "[+S NO_SCHEDULERS:NO_SCHEDULERS_ONLINE] " + "[+SP PERCENTAGE_SCHEDULERS:PERCENTAGE_SCHEDULERS_ONLINE] " + "[+T LEVEL] [+V] [+v] " "[+W<i|w>] [+z MISC_OPTION] [args ...]\n"); exit(1); } diff --git a/erts/etc/unix/Makefile b/erts/etc/unix/Makefile index e85d2fab0c..c137a31ec2 100644 --- a/erts/etc/unix/Makefile +++ b/erts/etc/unix/Makefile @@ -29,7 +29,7 @@ opt debug: etc etc: etp-commands etp-commands: etp-commands.in - sed 's:@ERL_TOP@:${ERL_TOP}:g' etp-commands.in > etp-commands + $(gen_verbose)sed 's:@ERL_TOP@:${ERL_TOP}:g' etp-commands.in > etp-commands .PHONY: docs docs: diff --git a/erts/etc/unix/cerl.src b/erts/etc/unix/cerl.src index 0d45917e4b..41baa323ed 100644 --- a/erts/etc/unix/cerl.src +++ b/erts/etc/unix/cerl.src @@ -283,6 +283,19 @@ if [ "x$GDB" = "x" ]; then else valgrind_misc_flags="$VALGRIND_MISC_FLAGS" fi + if which taskset > /dev/null && test -e /proc/cpuinfo; then + # We only let valgrind utilize one core with "taskset 1" as it can be very slow + # on multiple cores (especially with async threads). Valgrind only run one pthread + # at a time anyway so there is no point letting it utilize more than one core. + # Use $sched_arg to force all schedulers online to emulate multicore. + taskset1="taskset 1" + ncpu=`cat /proc/cpuinfo | grep -w processor | wc -l` + sched_arg="-S$ncpu:$ncpu" + else + taskset1= + sched_arg= + fi + beam_args=`$EXEC -emu_args_exit ${1+"$@"}` # Time for some argument passing voodoo: @@ -293,7 +306,7 @@ if [ "x$GDB" = "x" ]; then ' set -- $beam_args IFS="$SAVE_IFS" - exec valgrind $valgrind_xml $valgrind_log $valgrind_misc_flags $BINDIR/$EMU_NAME $emu_xargs "$@" -pz $PRELOADED + exec $taskset1 valgrind $valgrind_xml $valgrind_log $valgrind_misc_flags $BINDIR/$EMU_NAME $sched_arg $emu_xargs "$@" -pz $PRELOADED else exec $EXEC $eeargs $xargs ${1+"$@"} fi diff --git a/erts/etc/unix/run_erl.c b/erts/etc/unix/run_erl.c index b69e31f784..2018bc007c 100644 --- a/erts/etc/unix/run_erl.c +++ b/erts/etc/unix/run_erl.c @@ -60,7 +60,7 @@ #include <dirent.h> #include <termios.h> #include <time.h> -#ifndef NO_SYSLOG +#ifdef HAVE_SYSLOG_H # include <syslog.h> #endif #ifdef HAVE_PTY_H @@ -197,8 +197,9 @@ static char* outbuf_in; #endif -#ifdef NO_SYSLOG +#ifndef HAVE_SYSLOG_H # define OPEN_SYSLOG() ((void) 0) +# define LOG_ERR NULL #else # define OPEN_SYSLOG() openlog(simple_basename(program_name), \ LOG_PID|LOG_CONS|LOG_NOWAIT,LOG_USER) @@ -415,7 +416,7 @@ int main(int argc, char **argv) } #endif -#ifndef NO_SYSLOG +#ifdef HAVE_SYSLOG_H /* Before fiddling with file descriptors we make sure syslog is turned off or "closed". In the single case where we might want it again, we will open it again instead. Would not want syslog to @@ -1163,7 +1164,7 @@ static void error_logf(int priority, int line, const char *format, ...) va_list args; va_start(args, format); -#ifndef NO_SYSLOG +#ifdef HAVE_SYSLOG_H if (run_daemon) { vsyslog(priority,format,args); } diff --git a/erts/preloaded/ebin/erlang.beam b/erts/preloaded/ebin/erlang.beam Binary files differindex db41a9d2e1..425effe7cd 100644 --- a/erts/preloaded/ebin/erlang.beam +++ b/erts/preloaded/ebin/erlang.beam diff --git a/erts/preloaded/ebin/prim_inet.beam b/erts/preloaded/ebin/prim_inet.beam Binary files differindex fb8321733a..deed86816e 100644 --- a/erts/preloaded/ebin/prim_inet.beam +++ b/erts/preloaded/ebin/prim_inet.beam diff --git a/erts/preloaded/ebin/zlib.beam b/erts/preloaded/ebin/zlib.beam Binary files differindex feb3c5979e..690b90adb5 100644 --- a/erts/preloaded/ebin/zlib.beam +++ b/erts/preloaded/ebin/zlib.beam diff --git a/erts/preloaded/src/erlang.erl b/erts/preloaded/src/erlang.erl index 833f0440ea..aae7048fce 100644 --- a/erts/preloaded/src/erlang.erl +++ b/erts/preloaded/src/erlang.erl @@ -2099,13 +2099,14 @@ tuple_to_list(_Tuple) -> (creation) -> integer(); (debug_compiled) -> boolean(); (dist) -> binary(); + (dist_buf_busy_limit) -> non_neg_integer(); (dist_ctrl) -> {Node :: node(), ControllingEntity :: port() | pid()}; (driver_version) -> string(); (dynamic_trace) -> none | dtrace | systemtap; (dynamic_trace_probes) -> boolean(); (elib_malloc) -> false; - (dist_buf_busy_limit) -> non_neg_integer(); + (ets_limit) -> pos_integer(); (fullsweep_after) -> {fullsweep_after, non_neg_integer()}; (garbage_collection) -> [{atom(), integer()}]; (heap_sizes) -> [non_neg_integer()]; @@ -2891,22 +2892,23 @@ integer_to_binary(I, Base) when erlang:is_integer(I), erlang:is_integer(Base), Base >= 2, Base =< 1+$Z-$A+10 -> if I < 0 -> - <<"$-",(integer_to_binary(-I, Base, []))/binary>>; + <<$-,(integer_to_binary(-I, Base, <<>>))/binary>>; true -> integer_to_binary(I, Base, <<>>) end; integer_to_binary(I, Base) -> erlang:error(badarg, [I, Base]). -integer_to_binary(0, _Base, R0) -> - R0; integer_to_binary(I0, Base, R0) -> D = I0 rem Base, I1 = I0 div Base, - if D >= 10 -> - integer_to_binary(I1,Base,<<(D-10+$A),R0/binary>>); - true -> - integer_to_binary(I1,Base,<<(D+$0),R0/binary>>) + R1 = if + D >= 10 -> <<(D-10+$A),R0/binary>>; + true -> <<(D+$0),R0/binary>> + end, + if + I1 =:= 0 -> R1; + true -> integer_to_binary(I1, Base, R1) end. %% erlang:flush_monitor_message/2 is for internal use only! @@ -3497,6 +3499,8 @@ mk_res_list([]) -> mk_res_list([Alloc | Rest]) -> [{Alloc, []} | mk_res_list(Rest)]. +insert_instance(I, N, Rest) when erlang:is_atom(N) -> + [{N, I} | Rest]; insert_instance(I, N, []) -> [{instance, N, I}]; insert_instance(I, N, [{instance, M, _}|_] = Rest) when N < M -> diff --git a/erts/preloaded/src/prim_inet.erl b/erts/preloaded/src/prim_inet.erl index fb1269cf91..69eed716ff 100644 --- a/erts/preloaded/src/prim_inet.erl +++ b/erts/preloaded/src/prim_inet.erl @@ -25,7 +25,7 @@ %% Primitive inet_drv interface --export([open/3, fdopen/4, close/1]). +-export([open/3, open/4, fdopen/4, close/1]). -export([bind/3, listen/1, listen/2, peeloff/2]). -export([connect/3, connect/4, async_connect/4]). -export([accept/1, accept/2, async_accept/2]). @@ -64,22 +64,31 @@ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% open(Protocol, Family, Type) -> - open(Protocol, Family, Type, ?INET_REQ_OPEN, []). + open(Protocol, Family, Type, [], ?INET_REQ_OPEN, []). + +open(Protocol, Family, Type, Opts) -> + open(Protocol, Family, Type, Opts, ?INET_REQ_OPEN, []). fdopen(Protocol, Family, Type, Fd) when is_integer(Fd) -> - open(Protocol, Family, Type, ?INET_REQ_FDOPEN, ?int32(Fd)). + open(Protocol, Family, Type, [], ?INET_REQ_FDOPEN, ?int32(Fd)). -open(Protocol, Family, Type, Req, Data) -> +open(Protocol, Family, Type, Opts, Req, Data) -> Drv = protocol2drv(Protocol), AF = enc_family(Family), T = enc_type(Type), try erlang:open_port({spawn_driver,Drv}, [binary]) of S -> - case ctl_cmd(S, Req, [AF,T,Data]) of - {ok,_} -> {ok,S}; - {error,_}=Error -> + case setopts(S, Opts) of + ok -> + case ctl_cmd(S, Req, [AF,T,Data]) of + {ok,_} -> {ok,S}; + {error,_}=E1 -> + close(S), + E1 + end; + {error,_}=E2 -> close(S), - Error + E2 end catch %% The only (?) way to get here is to try to open @@ -1108,6 +1117,7 @@ enc_opt(send_timeout_close) -> ?INET_LOPT_TCP_SEND_TIMEOUT_CLOSE; enc_opt(delay_send) -> ?INET_LOPT_TCP_DELAY_SEND; enc_opt(packet_size) -> ?INET_LOPT_PACKET_SIZE; enc_opt(read_packets) -> ?INET_LOPT_READ_PACKETS; +enc_opt(netns) -> ?INET_LOPT_NETNS; enc_opt(raw) -> ?INET_OPT_RAW; % Names of SCTP opts: enc_opt(sctp_rtoinfo) -> ?SCTP_OPT_RTOINFO; @@ -1164,6 +1174,7 @@ dec_opt(?INET_LOPT_TCP_SEND_TIMEOUT_CLOSE) -> send_timeout_close; dec_opt(?INET_LOPT_TCP_DELAY_SEND) -> delay_send; dec_opt(?INET_LOPT_PACKET_SIZE) -> packet_size; dec_opt(?INET_LOPT_READ_PACKETS) -> read_packets; +dec_opt(?INET_LOPT_NETNS) -> netns; dec_opt(?INET_OPT_RAW) -> raw; dec_opt(I) when is_integer(I) -> undefined. @@ -1226,7 +1237,8 @@ type_opt_1(buffer) -> int; type_opt_1(active) -> {enum,[{false, ?INET_PASSIVE}, {true, ?INET_ACTIVE}, - {once, ?INET_ONCE}]}; + {once, ?INET_ONCE}, + {multi, ?INET_MULTI}]}; type_opt_1(packet) -> {enum,[{0, ?TCP_PB_RAW}, {1, ?TCP_PB_1}, @@ -1261,6 +1273,7 @@ type_opt_1(send_timeout_close) -> bool; type_opt_1(delay_send) -> bool; type_opt_1(packet_size) -> uint; type_opt_1(read_packets) -> uint; +type_opt_1(netns) -> binary; %% %% SCTP options (to be set). If the type is a record type, the corresponding %% record signature is returned, otherwise, an "elementary" type tag @@ -1487,9 +1500,12 @@ type_value_2({bitenumlist,List,_}, EnumList) -> Ls when is_list(Ls) -> true; false -> false end; -type_value_2(binary,Bin) when is_binary(Bin) -> true; -type_value_2(binary_or_uint,Bin) when is_binary(Bin) -> true; -type_value_2(binary_or_uint,Int) when is_integer(Int), Int >= 0 -> true; +type_value_2(binary,Bin) + when is_binary(Bin), byte_size(Bin) < (1 bsl 32) -> true; +type_value_2(binary_or_uint,Bin) + when is_binary(Bin), byte_size(Bin) < (1 bsl 32) -> true; +type_value_2(binary_or_uint,Int) + when is_integer(Int), Int >= 0 -> true; %% Type-checking of SCTP options type_value_2(sctp_assoc_id, X) when X band 16#ffffffff =:= X -> true; @@ -1701,11 +1717,14 @@ encode_opt_val(Opts) -> Reason -> {error,Reason} end. +%% {active, once} and {active, N} are specially optimized because they will +%% be used for every packet or every N packets, not only once when +%% initializing the socket. Measurements show that this optimization is +%% worthwhile. enc_opt_val([{active,once}|Opts], Acc) -> - %% Specially optimized because {active,once} will be used for - %% every packet, not only once when initializing the socket. - %% Measurements show that this optimization is worthwhile. enc_opt_val(Opts, [<<?INET_LOPT_ACTIVE:8,?INET_ONCE:32>>|Acc]); +enc_opt_val([{active,N}|Opts], Acc) when is_integer(N), N < 32768, N >= -32768 -> + enc_opt_val(Opts, [<<?INET_LOPT_ACTIVE:8,?INET_MULTI:32,N:16>>|Acc]); enc_opt_val([{raw,P,O,B}|Opts], Acc) -> enc_opt_val(Opts, Acc, raw, {P,O,B}); enc_opt_val([{Opt,Val}|Opts], Acc) -> @@ -1795,6 +1814,14 @@ dec_opt_val([]) -> []. dec_opt_val(Buf, raw, Type) -> {{P,O,B},T} = dec_value(Type, Buf), [{raw,P,O,B}|dec_opt_val(T)]; +dec_opt_val(Buf, active, Type) -> + case dec_value(Type, Buf) of + {multi,[M0,M1|T]} -> + <<N:16>> = list_to_binary([M0,M1]), + [{active,N}|dec_opt_val(T)]; + {Val,T} -> + [{active,Val}|dec_opt_val(T)] + end; dec_opt_val(Buf, Opt, Type) -> {Val,T} = dec_value(Type, Buf), [{Opt,Val}|dec_opt_val(T)]. diff --git a/erts/preloaded/src/zlib.erl b/erts/preloaded/src/zlib.erl index 2c9d55f50c..3d85533b80 100644 --- a/erts/preloaded/src/zlib.erl +++ b/erts/preloaded/src/zlib.erl @@ -30,6 +30,8 @@ compress/1,uncompress/1,zip/1,unzip/1, gzip/1,gunzip/1]). +-export_type([zstream/0]). + %% flush argument encoding -define(Z_NO_FLUSH, 0). -define(Z_SYNC_FLUSH, 2). diff --git a/lib/Makefile b/lib/Makefile index 432d98e854..ec26a01dc6 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -19,20 +19,32 @@ include $(ERL_TOP)/make/target.mk include $(ERL_TOP)/make/$(TARGET)/otp.mk -ERTS_SUB_DIRECTORIES = stdlib sasl kernel compiler -OTHER_SUB_DIRECTORIES = tools test_server common_test runtime_tools \ + +# These have to be built first +ERTS_APPLICATIONS = stdlib sasl kernel compiler + +# Then these have to be build +ERLANG_APPLICATIONS = tools test_server common_test runtime_tools \ inets xmerl edoc erl_docgen + +# These are only build if -a is given to otp_build or make is used directly +ALL_ERLANG_APPLICATIONS = snmp otp_mibs appmon erl_interface asn1 jinterface \ + wx debugger reltool gs \ + ic mnesia crypto orber os_mon parsetools syntax_tools \ + pman public_key ssl toolbar tv observer odbc diameter \ + cosTransactions cosEvent cosTime cosNotification \ + cosProperty cosFileTransfer cosEventDomain et megaco webtool \ + eunit ssh typer percept eldap dialyzer hipe + ifdef BUILD_ALL - OTHER_SUB_DIRECTORIES += \ - snmp otp_mibs appmon erl_interface asn1 jinterface \ - wx debugger reltool gs \ - ic mnesia crypto orber os_mon parsetools syntax_tools \ - pman public_key ssl toolbar tv observer odbc diameter \ - cosTransactions cosEvent cosTime cosNotification \ - cosProperty cosFileTransfer cosEventDomain et megaco webtool \ - eunit ssh typer percept eldap dialyzer hipe - EXTRA_FILE := $(wildcard EXTRA-APPLICATIONS) - EXTRA_APPLICATIONS := $(if $(EXTRA_FILE),$(shell cat $(EXTRA_FILE))) + ERLANG_APPLICATIONS += $(ALL_ERLANG_APPLICATIONS) + +# We use whildcard */ to figure out if there are any other applications +# in here. + EXPECTED_APPLICATIONS := $(ERTS_APPLICATIONS) $(ERLANG_APPLICATIONS) \ + autom4te.cache + EXTRA_APPLICATIONS += $(filter-out $(EXPECTED_APPLICATIONS),\ + $(subst /,,$(wildcard */))) endif ifdef BUILD_STATIC_LIBS @@ -48,13 +60,18 @@ else ifdef TERTIARY_BOOTSTRAP SUB_DIRECTORIES = snmp sasl jinterface ic syntax_tools wx else # Not bootstrap build - SUB_DIRECTORIES = $(ERTS_SUB_DIRECTORIES) \ - $(OTHER_SUB_DIRECTORIES) \ + SUB_DIRECTORIES = $(ERTS_APPLICATIONS) \ + $(ERLANG_APPLICATIONS) \ $(EXTRA_APPLICATIONS) endif endif endif endif +# Any applications listed in SKIP-APPLICATIONS should be skipped +SKIP_FILE := $(wildcard SKIP-APPLICATIONS) +SKIP_APPLICATIONS := $(if $(SKIP_FILE),$(shell cat $(SKIP_FILE))) +SUB_DIRECTORIES := $(filter-out $(SKIP_APPLICATIONS),$(SUB_DIRECTORIES)) + # ---------------------------------------------------------------------- include $(ERL_TOP)/make/otp_subdir.mk diff --git a/lib/asn1/doc/src/asn1ct.xml b/lib/asn1/doc/src/asn1ct.xml index b020643149..ada2aace87 100644 --- a/lib/asn1/doc/src/asn1ct.xml +++ b/lib/asn1/doc/src/asn1ct.xml @@ -66,7 +66,7 @@ <v>Option = ber | per | uper | der | compact_bit_string | legacy_bit_string | noobj | {n2n, EnumTypeName} |{outdir, Dir} | {i, IncludeDir} | - asn1config | undec_rest | + asn1config | undec_rest | no_ok_wrapper | {macro_name_prefix, Prefix} | {record_name_prefix, Prefix} | verbose | warnings_as_errors</v> <v>OldOption = ber | per</v> <v>Reason = term()</v> @@ -238,6 +238,13 @@ File3.asn </pre> list or a binary. Earlier versions of the compiler ignored those following bytes.</p> </item> + <tag><c>no_ok_wrapper</c></tag> + <item> + <p>If this option is given, the generated <c>encode/2</c> + and <c>decode/2</c> functions will not wrap a successful + return value in an <c>{ok,...}</c> tuple. If any error + occurs, there will be an exception.</p> + </item> <tag><c>{macro_name_prefix, Prefix}</c></tag> <item> <p>All macro names generated by the compiler are prefixed with @@ -356,11 +363,11 @@ File3.asn </pre> </item> </list> - <p>Schematically the following happens for each type in the module: + <p>Schematically the following happens for each type in the module:</p> <code type="none"> {ok, Value} = asn1ct:value(Module, Type), {ok, Bytes} = asn1ct:encode(Module, Type, Value), -{ok, Value} = asn1ct:decode(Module, Type, Bytes).</code></p> +{ok, Value} = asn1ct:decode(Module, Type, Bytes).</code> <p>The <c>test</c> functions utilizes the <c>*.asn1db</c> files for all included modules. If they are located in a different diff --git a/lib/asn1/doc/src/notes.xml b/lib/asn1/doc/src/notes.xml index f3c1ef862c..69e97019df 100644 --- a/lib/asn1/doc/src/notes.xml +++ b/lib/asn1/doc/src/notes.xml @@ -31,6 +31,44 @@ <p>This document describes the changes made to the asn1 application.</p> +<section><title>Asn1 2.0.3</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Open types greater than 16383 bytes will now be correctly + encoded and decoded.</p> + <p> + Own Id: OTP-11262 Aux Id: seq12386, OTP-11223 </p> + </item> + </list> + </section> + + + <section><title>Improvements and New Features</title> + <list> + <item> + <p>For the PER and UPER formats, code generation + especially for encoding has been improved.</p> + <p>When encoding BIT STRINGs, values longer than the + maximum size for the BIT STRING type would be truncated + silently - they now cause an exception.</p> + <p>Open types greater than 16383 bytes will now be + correctly encoded and decoded.</p> + <p>IMPORTANT NOTE: For ASN.1 specifications that depend + on each other, such as the S1AP-* specifications, it is + important to recompile all specifications (compiling some + with this version of the compiler and some with an older + version will not work).</p> + <p> + Own Id: OTP-11300</p> + </item> + </list> + </section> + +</section> + <section><title>Asn1 2.0.2</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/asn1/src/Makefile b/lib/asn1/src/Makefile index 33cd3cc4c3..3f24e15c04 100644 --- a/lib/asn1/src/Makefile +++ b/lib/asn1/src/Makefile @@ -43,9 +43,7 @@ RELSYSDIR = $(RELEASE_PATH)/lib/asn1-$(VSN) EBIN = ../ebin -EVAL_CT_MODULES = asn1ct_eval_ext \ - asn1ct_eval_per \ - asn1ct_eval_uper +EVAL_CT_MODULES = asn1ct_eval_ext CT_MODULES= \ asn1ct \ @@ -55,7 +53,6 @@ CT_MODULES= \ asn1ct_func \ asn1ct_gen \ asn1ct_gen_per \ - asn1ct_gen_per_rt2ct \ asn1ct_name \ asn1ct_constructed_per \ asn1ct_constructed_ber_bin_v2 \ diff --git a/lib/asn1/src/asn1_db.erl b/lib/asn1/src/asn1_db.erl index 869b36ddbd..48d9dd16d7 100644 --- a/lib/asn1/src/asn1_db.erl +++ b/lib/asn1/src/asn1_db.erl @@ -19,25 +19,37 @@ %% -module(asn1_db). --export([dbstart/1,dbnew/1,dbsave/2,dbput/3,dbget/2]). +-export([dbstart/1,dbnew/2,dbload/1,dbload/3,dbsave/2,dbput/3,dbget/2]). -export([dbstop/0]). -record(state, {parent, monitor, includes, table}). %% Interface -dbstart(Includes) -> +dbstart(Includes0) -> + Includes = case Includes0 of + [] -> ["."]; + [_|_] -> Includes0 + end, Parent = self(), undefined = get(?MODULE), %Assertion. put(?MODULE, spawn_link(fun() -> init(Parent, Includes) end)), ok. -dbnew(Module) -> req({new, Module}). +dbload(Module, Erule, Mtime) -> + req({load, Module, Erule, Mtime}). + +dbload(Module) -> + req({load, Module, any, {{0,0,0},{0,0,0}}}). + +dbnew(Module, Erule) -> req({new, Module, Erule}). dbsave(OutFile, Module) -> cast({save, OutFile, Module}). dbput(Module, K, V) -> cast({set, Module, K, V}). dbget(Module, K) -> req({get, Module, K}). dbstop() -> Resp = req(stop), erase(?MODULE), Resp. %% Internal functions +-define(MAGIC_KEY, '__version_and_erule__'). + req(Request) -> DbPid = get(?MODULE), Ref = erlang:monitor(process,DbPid), @@ -71,47 +83,57 @@ loop(#state{parent = Parent, monitor = MRef, table = Table, ets:insert(Modtab, {K2, V}), loop(State); {From, {get, Mod, K2}} -> - Result = case ets:lookup(Table, Mod) of - [] -> opentab(Table, Mod, Includes); - [{_, Modtab}] -> {ok, Modtab} - end, - case Result of - {ok, Newtab} -> reply(From, lookup(Newtab, K2)); - _Error -> reply(From, undefined) + %% XXX If there is no information for Mod, get_table/3 + %% will attempt to load information from an .asn1db + %% file, without comparing its timestamp against the + %% source file. This is known to happen when check_* + %% functions for DER are generated, but it could possibly + %% happen in other circumstances. Ideally, this issue should + %% be rectified in some way, perhaps by ensuring that + %% the module has been loaded (using dbload/4) prior + %% to calling dbget/2. + case get_table(Table, Mod, Includes) of + {ok,Tab} -> reply(From, lookup(Tab, K2)); + error -> reply(From, undefined) end, loop(State); {save, OutFile, Mod} -> [{_,Mtab}] = ets:lookup(Table, Mod), ok = ets:tab2file(Mtab, OutFile), loop(State); - {From, {new, Mod}} -> + {From, {new, Mod, Erule}} -> [] = ets:lookup(Table, Mod), %Assertion. ModTableId = ets:new(list_to_atom(lists:concat(["asn1_",Mod])), []), ets:insert(Table, {Mod, ModTableId}), + ets:insert(ModTableId, {?MAGIC_KEY, info(Erule)}), reply(From, ok), loop(State); + {From, {load, Mod, Erule, Mtime}} -> + case ets:member(Table, Mod) of + true -> + reply(From, ok); + false -> + case load_table(Mod, Erule, Mtime, Includes) of + {ok, ModTableId} -> + ets:insert(Table, {Mod, ModTableId}), + reply(From, ok); + error -> + reply(From, error) + end + end, + loop(State); {From, stop} -> reply(From, stopped); %% Nothing to store {'DOWN', MRef, process, Parent, Reason} -> exit(Reason) end. -opentab(Tab, Mod, []) -> - opentab(Tab, Mod, ["."]); -opentab(Tab, Mod, Includes) -> - Base = lists:concat([Mod, ".asn1db"]), - opentab2(Tab, Base, Mod, Includes, ok). - -opentab2(_Tab, _Base, _Mod, [], Error) -> - Error; -opentab2(Tab, Base, Mod, [Ih|It], _Error) -> - File = filename:join(Ih, Base), - case ets:file2tab(File) of - {ok, Modtab} -> - ets:insert(Tab, {Mod, Modtab}), - {ok, Modtab}; - NewErr -> - opentab2(Tab, Base, Mod, It, NewErr) +get_table(Table, Mod, Includes) -> + case ets:lookup(Table, Mod) of + [{Mod,Tab}] -> + {ok,Tab}; + [] -> + load_table(Mod, any, {{0,0,0},{0,0,0}}, Includes) end. lookup(Tab, K) -> @@ -119,3 +141,43 @@ lookup(Tab, K) -> [] -> undefined; [{K,V}] -> V end. + +info(Erule) -> + {asn1ct:vsn(),Erule}. + +load_table(Mod, Erule, Mtime, Includes) -> + Base = lists:concat([Mod, ".asn1db"]), + case path_find(Includes, Mtime, Base) of + error -> + error; + {ok,ModTab} when Erule =:= any -> + {ok,ModTab}; + {ok,ModTab} -> + Vsn = asn1ct:vsn(), + case ets:lookup(ModTab, ?MAGIC_KEY) of + [{_,{Vsn,Erule}}] -> + %% Correct version and encoding rule. + {ok,ModTab}; + _ -> + %% Missing key or wrong version/encoding rule. + ets:delete(ModTab), + error + end + end. + +path_find([H|T], Mtime, Base) -> + File = filename:join(H, Base), + case filelib:last_modified(File) of + 0 -> + path_find(T, Mtime, Base); + DbMtime when DbMtime >= Mtime -> + case ets:file2tab(File) of + {ok,_}=Ret -> + Ret; + _ -> + path_find(T, Mtime, Base) + end; + _ -> + path_find(T, Mtime, Base) + end; +path_find([], _, _) -> error. diff --git a/lib/asn1/src/asn1ct.erl b/lib/asn1/src/asn1ct.erl index 8e71a5697c..f2ccf5f212 100644 --- a/lib/asn1/src/asn1ct.erl +++ b/lib/asn1/src/asn1ct.erl @@ -893,17 +893,23 @@ parse_and_save(Module,S) -> Options = S#state.options, SourceDir = S#state.sourcedir, Includes = [I || {i,I} <- Options], + Erule = S#state.erule, case get_input_file(Module, [SourceDir|Includes]) of %% search for asn1 source {file,SuffixedASN1source} -> - case dbfile_uptodate(SuffixedASN1source,Options) of - false -> - parse_and_save1(S, SuffixedASN1source, Options); - _ -> ok + Mtime = filelib:last_modified(SuffixedASN1source), + case asn1_db:dbload(Module, Erule, Mtime) of + ok -> ok; + error -> parse_and_save1(S, SuffixedASN1source, Options) end; Err -> - warning("could not do a consistency check of the ~p file: no asn1 source file was found.~n", - [lists:concat([Module,".asn1db"])],Options), + case asn1_db:dbload(Module) of + ok -> + warning("could not do a consistency check of the ~p file: no asn1 source file was found.~n", + [lists:concat([Module,".asn1db"])],Options); + error -> + ok + end, {error,{asn1,input_file_error,Err}} end. @@ -929,48 +935,6 @@ get_input_file(Module,[I|Includes]) -> get_input_file(Module,Includes) end. -dbfile_uptodate(File,Options) -> - EncodingRule = get_rule(Options), - Ext = filename:extension(File), - Base = filename:basename(File,Ext), - DbFile = outfile(Base,"asn1db",Options), - case file:read_file_info(DbFile) of - {error,enoent} -> - false; - {ok,FileInfoDb} -> - %% file exists, check date and finally encodingrule - {ok,FileInfoAsn} = file:read_file_info(File), - case FileInfoDb#file_info.mtime < FileInfoAsn#file_info.mtime of - true -> - %% date of asn1 spec newer than db file - false; - _ -> - %% date ok,check that same erule was used - Obase = case lists:keysearch(outdir, 1, Options) of - {value, {outdir, Odir}} -> - Odir; - _NotFound -> "" - end, - BeamFileName = outfile(Base,"beam",Options), - case file:read_file_info(BeamFileName) of - {ok,_} -> - code:add_path(Obase), - BeamFile = list_to_atom(Base), - BeamInfo = (catch BeamFile:info()), - case catch lists:keysearch(options,1,BeamInfo) of - {value,{options,OldOptions}} -> - case get_rule(OldOptions) of - EncodingRule -> true; - _ -> false - end; - _ -> false - end; - _ -> false - end - end - end. - - input_file_type(Name,I) -> case input_file_type(Name) of {error,_} -> input_file_type2(filename:basename(Name),I); @@ -1374,10 +1338,11 @@ get_value(Module, Type) -> end. check(Module, Includes) -> - case asn1_db:dbget(Module,'MODULE') of - undefined -> - {error, {file_not_found, lists:concat([Module, ".asn1db"])}}; - M -> + case asn1_db:dbload(Module) of + error -> + {error,asn1db_missing_or_out_of_date}; + ok -> + M = asn1_db:dbget(Module, 'MODULE'), TypeOrVal = M#module.typeorval, State = #state{mname = M#module.name, module = M#module{typeorval=[]}, diff --git a/lib/asn1/src/asn1ct_check.erl b/lib/asn1/src/asn1ct_check.erl index f94550b0a4..eddcda0018 100644 --- a/lib/asn1/src/asn1ct_check.erl +++ b/lib/asn1/src/asn1ct_check.erl @@ -1557,21 +1557,32 @@ check_objectdefn(S,Def,CDef) when is_record(CDef,classdef) -> exit({error,{objectdefn,Other}}) end. -check_defaultfields(S,Fields,ClassFields) -> - check_defaultfields(S,Fields,ClassFields,[]). +check_defaultfields(S, Fields, ClassFields) -> + Present = ordsets:from_list([F || {F,_} <- Fields]), + Mandatory0 = get_mandatory_class_fields(ClassFields), + Mandatory = ordsets:from_list(Mandatory0), + All = ordsets:from_list([element(2, F) || F <- ClassFields]), + #state{type=T,tname=Obj} = S, + case ordsets:subtract(Present, All) of + [] -> + ok; + [_|_]=Invalid -> + throw(asn1_error(S, T, {invalid_fields,Invalid,Obj})) + end, + case ordsets:subtract(Mandatory, Present) of + [] -> + check_defaultfields_1(S, Fields, ClassFields, []); + [_|_]=Missing -> + throw(asn1_error(S, T, {missing_mandatory_fields,Missing,Obj})) + end. -check_defaultfields(_S,[],_ClassFields,Acc) -> +check_defaultfields_1(_S, [], _ClassFields, Acc) -> {object,defaultsyntax,lists:reverse(Acc)}; -check_defaultfields(S,[{FName,Spec}|Fields],ClassFields,Acc) -> - case lists:keysearch(FName,2,ClassFields) of - {value,CField} -> - {NewField,RestFields} = - convert_to_defaultfield(S,FName,[Spec|Fields],CField), - check_defaultfields(S,RestFields,ClassFields,[NewField|Acc]); - _ -> - throw({error,{asn1,{'unvalid field in object',FName}}}) - end. -%% {object,defaultsyntax,Fields}. +check_defaultfields_1(S, [{FName,Spec}|Fields], ClassFields, Acc) -> + CField = lists:keyfind(FName, 2, ClassFields), + {NewField,RestFields} = + convert_to_defaultfield(S, FName, [Spec|Fields], CField), + check_defaultfields_1(S, RestFields, ClassFields, [NewField|Acc]). convert_definedsyntax(_S,[],[],_ClassFields,Acc) -> lists:reverse(Acc); @@ -1587,6 +1598,23 @@ convert_definedsyntax(S,Fields,WithSyntax,ClassFields,Acc) -> [MatchedField|Acc]) end. +get_mandatory_class_fields([{fixedtypevaluefield,Name,_,_,'MANDATORY'}|T]) -> + [Name|get_mandatory_class_fields(T)]; +get_mandatory_class_fields([{objectfield,Name,_,_,'MANDATORY'}|T]) -> + [Name|get_mandatory_class_fields(T)]; +get_mandatory_class_fields([{objectsetfield,Name,_,'MANDATORY'}|T]) -> + [Name|get_mandatory_class_fields(T)]; +get_mandatory_class_fields([{typefield,Name,'MANDATORY'}|T]) -> + [Name|get_mandatory_class_fields(T)]; +get_mandatory_class_fields([{variabletypevaluefield,Name,_,'MANDATORY'}|T]) -> + [Name|get_mandatory_class_fields(T)]; +get_mandatory_class_fields([{variabletypevaluesetfield, + Name,_,'MANDATORY'}|T]) -> + [Name|get_mandatory_class_fields(T)]; +get_mandatory_class_fields([_|T]) -> + get_mandatory_class_fields(T); +get_mandatory_class_fields([]) -> []. + match_field(S,Fields,WithSyntax,ClassFields) -> match_field(S,Fields,WithSyntax,ClassFields,[]). @@ -6798,7 +6826,7 @@ merge_tags2([], Acc) -> storeindb(S,M) when is_record(M,module) -> TVlist = M#module.typeorval, NewM = M#module{typeorval=findtypes_and_values(TVlist)}, - asn1_db:dbnew(NewM#module.name), + asn1_db:dbnew(NewM#module.name, S#state.erule), asn1_db:dbput(NewM#module.name,'MODULE', NewM), Res = storeindb(#state{mname=NewM#module.name}, TVlist, []), include_default_class(S,NewM#module.name), @@ -6867,11 +6895,22 @@ asn1_error(#state{mname=Where}, Item, Error) -> format_error({already_defined,Name,PrevLine}) -> io_lib:format("the name ~p has already been defined at line ~p", [Name,PrevLine]); +format_error({invalid_fields,Fields,Obj}) -> + io_lib:format("invalid ~s in ~p", [format_fields(Fields),Obj]); +format_error({missing_mandatory_fields,Fields,Obj}) -> + io_lib:format("missing mandatory ~s in ~p", + [format_fields(Fields),Obj]); format_error({undefined,Name}) -> io_lib:format("'~s' is referenced, but is not defined", [Name]); format_error(Other) -> io_lib:format("~p", [Other]). +format_fields([F]) -> + io_lib:format("field &~s", [F]); +format_fields([H|T]) -> + [io_lib:format("fields &~s", [H])| + [io_lib:format(", &~s", [F]) || F <- T]]. + error({_,{structured_error,_,_,_}=SE,_}) -> SE; error({export,Msg,#state{mname=Mname,type=Ref,tname=Typename}}) -> diff --git a/lib/asn1/src/asn1ct_constructed_ber_bin_v2.erl b/lib/asn1/src/asn1ct_constructed_ber_bin_v2.erl index 761faa53c5..8359b81b33 100644 --- a/lib/asn1/src/asn1ct_constructed_ber_bin_v2.erl +++ b/lib/asn1/src/asn1ct_constructed_ber_bin_v2.erl @@ -122,8 +122,8 @@ gen_encode_sequence(Erules,Typename,D) when is_record(D,type) -> asn1ct_gen:un_hyphen_var(lists:concat(['Obj', AttrN])), emit([ObjectEncode," = ",nl, - " ",{asis,ObjSetMod},":'getenc_",ObjSetName, - "'(",{asis,UniqueFieldName},", ",nl]), + " ",{asis,ObjSetMod},":'getenc_",ObjSetName, + "'("]), ValueMatch = value_match(ValueIndex, lists:concat(["Cindex",N])), emit([indent(35),ValueMatch,"),",nl]), @@ -198,7 +198,7 @@ gen_decode_sequence(Erules,Typename,D) when is_record(D,type) -> asn1ct_name:new(tlv), asn1ct_name:new(v), - {DecObjInf,UniqueFName,ValueIndex} = + {DecObjInf,ValueIndex} = case TableConsInfo of #simpletableattributes{objectsetname=ObjectSetRef, c_name=AttrN, @@ -217,12 +217,12 @@ gen_decode_sequence(Erules,Typename,D) when is_record(D,type) -> %% relation from a component to another components %% subtype component {{AttrN,{deep,ObjectSetRef,UniqueFieldName,ValIndex}}, - UniqueFieldName,ValIndex}; + ValIndex}; false -> - {{AttrN,ObjectSetRef},UniqueFieldName,ValIndex} + {{AttrN,ObjectSetRef},ValIndex} end; _ -> - {false,false,false} + {false,false} end, RecordName = lists:concat([get_record_name_prefix(), asn1ct_gen:list2rname(Typename)]), @@ -246,7 +246,7 @@ gen_decode_sequence(Erules,Typename,D) when is_record(D,type) -> {ObjSetMod,ObjSetName} = ObjSetRef, emit([DecObj," =",nl, " ",{asis,ObjSetMod},":'getdec_",ObjSetName,"'(", - {asis,UniqueFName},", ",ValueMatch,"),",nl]), + ValueMatch,"),",nl]), gen_dec_postponed_decs(DecObj,PostponedDecArgs) end, demit(["Result = "]), %dbg @@ -357,7 +357,7 @@ gen_decode_set(Erules,Typename,D) when is_record(D,type) -> asn1ct_name:new(v), - {DecObjInf,UniqueFName,ValueIndex} = + {DecObjInf,ValueIndex} = case TableConsInfo of %% {ObjectSetRef,AttrN,_N,UniqueFieldName} ->%% N is index of attribute that determines constraint #simpletableattributes{objectsetname=ObjectSetRef, @@ -378,12 +378,12 @@ gen_decode_set(Erules,Typename,D) when is_record(D,type) -> %% relation from a component to another components %% subtype component {{AttrN,{deep,ObjectSetRef,UniqueFieldName,ValIndex}}, - UniqueFieldName,ValIndex}; + ValIndex}; false -> - {{AttrN,ObjectSetRef},UniqueFieldName,ValIndex} + {{AttrN,ObjectSetRef},ValIndex} end; _ -> - {false,false,false} + {false,false} end, case CompList of @@ -425,7 +425,7 @@ gen_decode_set(Erules,Typename,D) when is_record(D,type) -> {ObjSetMod,ObjSetName} = ObjSetRef, emit([DecObj," =",nl, " ",{asis,ObjSetMod},":'getdec_",ObjSetName,"'(", - {asis,UniqueFName},", ",ValueMatch,"),",nl]), + ValueMatch,"),",nl]), gen_dec_postponed_decs(DecObj,PostponedDecArgs) end, demit(["Result = "]), %dbg @@ -577,6 +577,8 @@ gen_decode_choice(Erules,Typename,D) when is_record(D,type) -> gen_enc_sequence_call(Erules,TopType,[#'ComponentType'{name=Cname,typespec=Type,prop=Prop,textual_order=Order}|Rest],Pos,Ext,EncObj) -> asn1ct_name:new(encBytes), asn1ct_name:new(encLen), + asn1ct_name:new(tmpBytes), + asn1ct_name:new(tmpLen), CindexPos = case Order of undefined -> @@ -706,8 +708,6 @@ emit_term_tlv('OPTIONAL',InnerType,DecObjInf) -> emit_term_tlv(opt_or_def,InnerType,DecObjInf); emit_term_tlv(Prop,{typefield,_},DecObjInf) -> emit_term_tlv(Prop,type_or_object_field,DecObjInf); -emit_term_tlv(Prop,{objectfield,_,_},DecObjInf) -> - emit_term_tlv(Prop,type_or_object_field,DecObjInf); emit_term_tlv(opt_or_def,type_or_object_field,NotFalse) when NotFalse /= false -> asn1ct_name:new(tmpterm), @@ -789,6 +789,7 @@ gen_enc_choice2(Erules,TopType,[H1|T]) when is_record(H1,'ComponentType') -> componentrelation)} of {#'ObjectClassFieldType'{},{componentrelation,_,_}} -> asn1ct_name:new(tmpBytes), + asn1ct_name:new(tmpLen), asn1ct_name:new(encBytes), asn1ct_name:new(encLen), Emit = ["{",{curr,tmpBytes},", _} = "], @@ -929,7 +930,6 @@ gen_enc_line(Erules,TopType,Cname, when is_list(Element) -> case asn1ct_gen:get_constraint(C,componentrelation) of {componentrelation,_,_} -> - asn1ct_name:new(tmpBytes), gen_enc_line(Erules,TopType,Cname,Type,Element,Indent,OptOrMand, ["{",{curr,tmpBytes},",_} = "],EncObj); _ -> @@ -991,12 +991,8 @@ gen_enc_line(Erules,TopType,Cname,Type,Element,Indent,OptOrMand,Assign,EncObj) {call,ber,encode_open_type, [{curr,tmpBytes},{asis,Tag}]},nl]); _ -> - emit(["{",{next,tmpBytes},",",{curr,tmpLen}, - "} = ", - {call,ber,encode_open_type, - [{curr,tmpBytes},{asis,Tag}]},com,nl]), - emit(IndDeep), - emit(["{",{next,tmpBytes},", ",{curr,tmpLen},"}"]) + emit([{call,ber,encode_open_type, + [{curr,tmpBytes},{asis,Tag}]}]) end; Err -> throw({asn1,{'internal error',Err}}) @@ -1213,22 +1209,18 @@ gen_dec_call({typefield,_},_,_,Cname,Type,BytesVar,Tag,_,_,_DecObjInf,OptOrMandC (Type#type.def)#'ObjectClassFieldType'.fieldname, [{Cname,RefedFieldName,asn1ct_gen:mk_var(asn1ct_name:curr(term)), asn1ct_gen:mk_var(asn1ct_name:curr(tmpterm)),Tag,OptOrMandComp}]; -gen_dec_call({objectfield,PrimFieldName,PFNList},_,_,Cname,_,BytesVar,Tag,_,_,_,OptOrMandComp) -> - call(decode_open_type, [BytesVar,{asis,Tag}]), - [{Cname,{PrimFieldName,PFNList},asn1ct_gen:mk_var(asn1ct_name:curr(term)), - asn1ct_gen:mk_var(asn1ct_name:curr(tmpterm)),Tag,OptOrMandComp}]; gen_dec_call(InnerType,Erules,TopType,Cname,Type,BytesVar,Tag,PrimOptOrMand, OptOrMand,DecObjInf,_) -> WhatKind = asn1ct_gen:type(InnerType), gen_dec_call1(WhatKind,InnerType,Erules,TopType,Cname,Type,BytesVar,Tag, PrimOptOrMand,OptOrMand), case DecObjInf of - {Cname,{_,OSet,UniqueFName,ValIndex}} -> + {Cname,{_,OSet,_UniqueFName,ValIndex}} -> Term = asn1ct_gen:mk_var(asn1ct_name:curr(term)), ValueMatch = value_match(ValIndex,Term), {ObjSetMod,ObjSetName} = OSet, emit([",",nl,"ObjFun = ",{asis,ObjSetMod},":'getdec_",ObjSetName, - "'(",{asis,UniqueFName},", ",ValueMatch,")"]); + "'(",ValueMatch,")"]); _ -> ok end, diff --git a/lib/asn1/src/asn1ct_constructed_per.erl b/lib/asn1/src/asn1ct_constructed_per.erl index d279e9697f..8d4afc0a0b 100644 --- a/lib/asn1/src/asn1ct_constructed_per.erl +++ b/lib/asn1/src/asn1ct_constructed_per.erl @@ -43,10 +43,13 @@ gen_encode_set(Erules,TypeName,D) -> gen_encode_sequence(Erules,TypeName,D) -> gen_encode_constructed(Erules,TypeName,D). -gen_encode_constructed(Erule,Typename,D) when is_record(D,type) -> +gen_encode_constructed(Erule, Typename, #type{}=D) -> asn1ct_name:start(), - asn1ct_name:new(term), - asn1ct_name:new(bytes), + Imm = gen_encode_constructed_imm(Erule, Typename, D), + asn1ct_imm:enc_cg(Imm, is_aligned(Erule)), + emit([".",nl]). + +gen_encode_constructed_imm(Erule, Typename, #type{}=D) -> {ExtAddGroup,TmpCompList,TableConsInfo} = case D#type.def of #'SEQUENCE'{tablecinf=TCI,components=CL,extaddgroup=ExtAddGroup0} -> @@ -65,74 +68,36 @@ gen_encode_constructed(Erule,Typename,D) when is_record(D,type) -> [Comp#'ComponentType'{textual_order=undefined}|| Comp<-TmpCompList] end, - case Typename of - ['EXTERNAL'] -> - emit([{next,val}," = ", - {call,ext,transform_to_EXTERNAL1990, - [{curr,val}]},com,nl]), - asn1ct_name:new(val); - _ -> - ok - end, - case {Optionals = optionals(to_textual_order(CompList)),CompList, - is_optimized(Erule)} of - {[],EmptyCL,_} when EmptyCL == {[],[],[]};EmptyCL == {[],[]};EmptyCL == [] -> - ok; - {[],_,_} -> - emit([{next,val}," = ",{curr,val},",",nl]); - {_,_,true} -> - gen_fixoptionals(Optionals), - FixOpts = param_map(fun(Var) -> - {var,Var} - end,asn1ct_name:all(fixopt)), - emit({"{",{next,val},",Opt} = {",{curr,val},",[",FixOpts,"]},",nl}); - {_,_,false} -> - asn1ct_func:need({Erule,fixoptionals,3}), - Fixoptcall = ",Opt} = fixoptionals(", - emit({"{",{next,val},Fixoptcall, - {asis,Optionals},",",length(Optionals), - ",",{curr,val},"),",nl}) - end, - asn1ct_name:new(val), + ExternalImm = + case Typename of + ['EXTERNAL'] -> + Next = asn1ct_gen:mk_var(asn1ct_name:next(val)), + Curr = asn1ct_gen:mk_var(asn1ct_name:curr(val)), + asn1ct_name:new(val), + [{call,ext,transform_to_EXTERNAL1990,[{var,Curr}],{var,Next}}]; + _ -> + [] + end, + Aligned = is_aligned(Erule), + Value0 = asn1ct_gen:mk_var(asn1ct_name:curr(val)), + Optionals = optionals(to_textual_order(CompList)), + ImmOptionals = [asn1ct_imm:per_enc_optional(Value0, Opt, Aligned) || + Opt <- Optionals], Ext = extensible_enc(CompList), - case Ext of - {ext,_,NumExt} when NumExt > 0 -> - case extgroup_pos_and_length(CompList) of - {extgrouppos,[]} -> % no extenstionAdditionGroup - ok; - {extgrouppos,ExtGroupPosLenList} -> - ExtGroupFun = - fun({ExtActualGroupPos,ExtGroupVirtualPos,ExtGroupLen}) -> - Elements = - make_elements(ExtGroupVirtualPos+1, - "Val1", - lists:seq(1,ExtGroupLen)), - emit([ - {next,val}," = case [X || X <- [",Elements, - "],X =/= asn1_NOVALUE] of",nl, - "[] -> setelement(", - {asis,ExtActualGroupPos+1},",", - {curr,val},",", - "asn1_NOVALUE);",nl, - "_ -> setelement(",{asis,ExtActualGroupPos+1},",", - {curr,val},",", - "{extaddgroup,", Elements,"})",nl, - "end,",nl]), - asn1ct_name:new(val) - end, - lists:foreach(ExtGroupFun,ExtGroupPosLenList) - end, - asn1ct_name:new(tmpval), - emit(["Extensions = ", - {call,Erule,fixextensions,[{asis,Ext},{curr,val}]}, - com,nl]); - _ -> true - end, - EncObj = + ExtImm = case Ext of + {ext,ExtPos,NumExt} when NumExt > 0 -> + gen_encode_extaddgroup(CompList), + Value = asn1ct_gen:mk_var(asn1ct_name:curr(val)), + asn1ct_imm:per_enc_extensions(Value, ExtPos, + NumExt, Aligned); + _ -> + [] + end, + {EncObj,ObjSetImm} = case TableConsInfo of #simpletableattributes{usedclassfield=Used, uniqueclassfield=Unique} when Used /= Unique -> - false; + {false,[]}; %% ObjectSet, name of the object set in constraints %% %%{ObjectSet,AttrN,N,UniqueFieldName} -> %% N is index of attribute that determines constraint @@ -152,13 +117,10 @@ gen_encode_constructed(Erule,Typename,D) when is_record(D,type) -> asn1ct_gen:un_hyphen_var(lists:concat(['Obj',AttrN])), El = make_element(N+1, asn1ct_gen:mk_var(asn1ct_name:curr(val))), ValueMatch = value_match(ValueIndex, El), - emit([ObjectEncode," =",nl, - " ",{asis,Module},":'getenc_",ObjSetName,"'(", - {asis,UniqueFieldName},", ",nl, - " ",ValueMatch,"),",nl]), - {AttrN,ObjectEncode}; + ObjSetImm0 = [{assign,{var,ObjectEncode},ValueMatch}], + {{AttrN,ObjectEncode},ObjSetImm0}; false -> - false + {false,[]} end; _ -> case D#type.tablecinf of @@ -166,34 +128,52 @@ gen_encode_constructed(Erule,Typename,D) when is_record(D,type) -> %% when the simpletableattributes was at an outer %% level and the objfun has been passed through the %% function call - {"got objfun through args","ObjFun"}; + {{"got objfun through args","ObjFun"},[]}; _ -> - false + {false,[]} end end, - emit({"[",nl}), - MaybeComma1 = + ImmSetExt = case Ext of - {ext,_Pos,NumExt2} when NumExt2 > 0 -> - call(Erule, setext, ["Extensions =/= []"]), - ", "; - {ext,_Pos,_} -> - call(Erule, setext, ["false"]), - ", "; - _ -> - "" - end, - MaybeComma2 = - case optionals(CompList) of - [] -> MaybeComma1; - _ -> - emit(MaybeComma1), - emit("Opt"), - {",",nl} + {ext,_Pos,NumExt2} when NumExt2 > 0 -> + asn1ct_imm:per_enc_extension_bit('Extensions', Aligned); + {ext,_Pos,_} -> + asn1ct_imm:per_enc_extension_bit([], Aligned); + _ -> + [] end, - gen_enc_components_call(Erule,Typename,CompList,MaybeComma2,EncObj,Ext), - emit({"].",nl}). + ImmBody = gen_enc_components_call(Erule, Typename, CompList, EncObj, Ext), + ExternalImm ++ ExtImm ++ ObjSetImm ++ + asn1ct_imm:enc_append([ImmSetExt] ++ ImmOptionals ++ ImmBody). + +gen_encode_extaddgroup(CompList) -> + case extgroup_pos_and_length(CompList) of + {extgrouppos,[]} -> + ok; + {extgrouppos,ExtGroupPosLenList} -> + _ = [do_gen_encode_extaddgroup(G) || G <- ExtGroupPosLenList], + ok + end. +do_gen_encode_extaddgroup({ActualGroupPos,GroupVirtualPos,GroupLen}) -> + Val = asn1ct_gen:mk_var(asn1ct_name:curr(val)), + Elements = make_elements(GroupVirtualPos+1, + Val, + lists:seq(1, GroupLen)), + Expr = any_non_value(GroupVirtualPos+1, Val, GroupLen, ""), + emit([{next,val}," = case ",Expr," of",nl, + "false -> setelement(",{asis,ActualGroupPos+1},", ", + {curr,val},", asn1_NOVALUE);",nl, + "true -> setelement(",{asis,ActualGroupPos+1},", ", + {curr,val},", {extaddgroup,", Elements,"})",nl, + "end,",nl]), + asn1ct_name:new(val). + +any_non_value(_, _, 0, _) -> + []; +any_non_value(Pos, Val, N, Sep) -> + Sep ++ [make_element(Pos, Val)," =/= asn1_NOVALUE"] ++ + any_non_value(Pos+1, Val, N-1, [" orelse",nl]). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% generate decode function for SEQUENCE and SET @@ -328,28 +308,29 @@ gen_dec_constructed_imm(Erule, Typename, #type{}=D) -> EmitComp = gen_dec_components_call(Erule, Typename, CompList, DecObjInf, Ext, length(Optionals)), EmitRest = fun({AccTerm,AccBytes}) -> - gen_dec_constructed_imm_2(Typename, CompList, + gen_dec_constructed_imm_2(Erule, Typename, + CompList, ObjSetInfo, AccTerm, AccBytes) end, [EmitExt,EmitOpt|EmitComp++[{safe,EmitRest}]]. -gen_dec_constructed_imm_2(Typename, CompList, +gen_dec_constructed_imm_2(Erule, Typename, CompList, ObjSetInfo, AccTerm, AccBytes) -> - {_,UniqueFName,ValueIndex} = ObjSetInfo, + {_,_UniqueFName,ValueIndex} = ObjSetInfo, case {AccTerm,AccBytes} of {[],[]} -> ok; {_,[]} -> ok; {[{ObjSet,LeadingAttr,Term}],ListOfOpenTypes} -> - DecObj = asn1ct_gen:un_hyphen_var(lists:concat(['DecObj',LeadingAttr,Term])), - ValueMatch = value_match(ValueIndex,Term), - {ObjSetMod,ObjSetName} = ObjSet, - emit([DecObj," =",nl, - " ",{asis,ObjSetMod},":'getdec_",ObjSetName,"'(", - {asis,UniqueFName},", ",ValueMatch,"),",nl]), - gen_dec_listofopentypes(DecObj,ListOfOpenTypes,false) + ValueMatch = value_match(ValueIndex, Term), + _ = [begin + gen_dec_open_type(Erule, ValueMatch, ObjSet, + LeadingAttr, T), + emit([com,nl]) + end || T <- ListOfOpenTypes], + ok end, %% we don't return named lists any more Cnames = mkcnamelist(CompList), demit({"Result = "}), %dbg @@ -423,67 +404,143 @@ to_textual_order(Cs) when is_list(Cs) -> to_textual_order(Cs) -> Cs. -gen_dec_listofopentypes(_,[],_) -> - emit(nl); -gen_dec_listofopentypes(DecObj,[{_Cname,{FirstPFN,PFNList},Term,TmpTerm,Prop}|Rest],_Update) -> - - asn1ct_name:new(tmpterm), - asn1ct_name:new(reason), - - emit([Term," = ",nl]), +gen_dec_open_type(Erule, Val, {Xmod,Xtype}, LeadingAttr, + {_,{Name,RestFieldNames},Term,TmpTerm,Prop}) -> + #typedef{typespec=ObjSet0} = asn1_db:dbget(Xmod, Xtype), + #'ObjectSet'{class=Class,set=ObjSet1} = ObjSet0, + #'Externaltypereference'{module=ClMod,type=ClType} = Class, + #classdef{typespec=ClassDef} = asn1_db:dbget(ClMod, ClType), + #objectclass{fields=ClassFields} = ClassDef, + Extensible = lists:member('EXTENSIONMARK', ObjSet1), + ObjSet2 = [{Key,fix_object_code(Name, Code, ClassFields)} || + {_,Key,Code} <- ObjSet1], + ObjSet = lists:sort([P || {_,B}=P <- ObjSet2, B =/= none]), + Key = erlang:md5(term_to_binary({decode,ObjSet,RestFieldNames, + Prop,Extensible})), + Typename = [Name,ClType], + Gen = fun(_Fd, N) -> + dec_objset_optional(N, Prop), + dec_objset(Erule, N, ObjSet, RestFieldNames, Typename), + dec_objset_default(N, Name, LeadingAttr, Extensible) + end, + Prefix = lists:concat(["dec_os_",Name]), + F = asn1ct_func:call_gen(Prefix, Key, Gen), + emit([Term," = ",{asis,F},"(",TmpTerm,", ",Val,")"]). + +dec_objset_optional(N, {'DEFAULT',Val}) -> + dec_objset_optional_1(N, Val), + dec_objset_optional_1(N, asn1_DEFAULT); +dec_objset_optional(N, 'OPTIONAL') -> + dec_objset_optional_1(N, asn1_NOVALUE); +dec_objset_optional(_N, mandatory) -> ok. + +dec_objset_optional_1(N, Val) -> + emit([{asis,N},"(",{asis,Val},", _Id) ->",nl, + {asis,Val},";",nl]). + +dec_objset(_Erule, _N, [], _, _) -> + ok; +dec_objset(Erule, N, [Obj|Objs], RestFields, Cl) -> + dec_objset_1(Erule, N, Obj, RestFields, Cl), + emit([";",nl]), + dec_objset(Erule, N, Objs, RestFields, Cl). + +dec_objset_default(N, C, LeadingAttr, false) -> + emit([{asis,N},"(Bytes, Id) ->",nl, + "exit({'Type not compatible with table constraint'," + "{{component,",{asis,C},"}," + "{value,Bytes}," + "{unique_name_and_value,",{asis,LeadingAttr},",Id}}}).",nl,nl]); +dec_objset_default(N, _, _, true) -> + emit([{asis,N},"(Bytes, Id) ->",nl, + "Bytes.",nl,nl]). + +dec_objset_1(Erule, N, {Id,Obj}, RestFields, Typename) -> + emit([{asis,N},"(Bytes, ",{asis,Id},") ->",nl]), + dec_objset_2(Erule, Obj, RestFields, Typename). + +dec_objset_2(Erule, Obj, RestFields0, Typename) -> + case Obj of + #typedef{name={primitive,bif},typespec=Type} -> + Imm = asn1ct_gen_per:gen_dec_imm(Erule, Type), + {Term,_} = asn1ct_imm:dec_slim_cg(Imm, 'Bytes'), + emit([com,nl,Term]); + #typedef{name={constructed,bif},typespec=Def} -> + InnerType = asn1ct_gen:get_inner(Def#type.def), + case InnerType of + 'CHOICE' -> + asn1ct_name:start(), + asn1ct_name:new(bytes), + {'CHOICE',CompList} = Def#type.def, + Ext = extensible_enc(CompList), + emit(["{Result,_} = begin",nl]), + gen_dec_choice(Erule, Typename, CompList, Ext), + emit([nl, + "end",com,nl, + "Result"]); + 'SET' -> + Imm0 = gen_dec_constructed_imm(Erule, Typename, Def), + Imm = opt_imm(Imm0), + asn1ct_name:start(), + emit(["{Result,_} = begin",nl]), + emit_gen_dec_imm(Imm), + emit([nl, + "end",com,nl, + "Result"]); + 'SET OF' -> + asn1ct_name:start(), + do_gen_decode_sof(Erule, Typename, 'SET OF', + Def, false); + 'SEQUENCE' -> + Imm0 = gen_dec_constructed_imm(Erule, Typename, Def), + Imm = opt_imm(Imm0), + asn1ct_name:start(), + emit(["{Result,_} = begin",nl]), + emit_gen_dec_imm(Imm), + emit([nl, + "end",com,nl, + "Result"]); + 'SEQUENCE OF' -> + asn1ct_name:start(), + do_gen_decode_sof(Erule, Typename, 'SEQUENCE OF', + Def, false) + end; + #typedef{name=Type} -> + emit(["{Result,_} = ",{asis,enc_func("dec_", Type)},"(Bytes),",nl, + "Result"]); + #'Externaltypereference'{module=Mod,type=Type} -> + emit("{Term,_} = "), + Func = enc_func("dec_", Type), + case get(currmod) of + Mod -> + emit([{asis,Func},"(Bytes)"]); + _ -> + emit([{asis,Mod},":",{asis,Func},"(Bytes)"]) + end, + emit([com,nl, + "Term"]); + #'Externalvaluereference'{module=Mod,value=Value} -> + case asn1_db:dbget(Mod, Value) of + #typedef{typespec=#'Object'{def=Def}} -> + {object,_,Fields} = Def, + [NextField|RestFields] = RestFields0, + {NextField,Typedef} = lists:keyfind(NextField, 1, Fields), + dec_objset_2(Erule, Typedef, RestFields, Typename) + end + end. - N = case Prop of - mandatory -> 0; - 'OPTIONAL' -> - emit_opt_or_mand_check(asn1_NOVALUE,TmpTerm), - 6; - {'DEFAULT',Val} -> - emit_opt_or_mand_check(Val,TmpTerm), - 6 - end, +gen_encode_choice(Erule, TopType, D) -> + asn1ct_name:start(), + Imm = gen_encode_choice_imm(Erule, TopType, D), + asn1ct_imm:enc_cg(Imm, is_aligned(Erule)), + emit([".",nl]). - emit([indent(N+3),"case (catch ",DecObj,"(", - {asis,FirstPFN},", ",TmpTerm,", telltype,",{asis,PFNList},")) of",nl]), - emit([indent(N+6),"{'EXIT', ",{curr,reason},"} ->",nl]), - emit([indent(N+9),"exit({'Type not compatible with table constraint',", - {curr,reason},"});",nl]), - emit([indent(N+6),"{",{curr,tmpterm},",_} ->",nl]), - emit([indent(N+9),{curr,tmpterm},nl]), - - case Prop of - mandatory -> - emit([indent(N+3),"end,",nl]); - _ -> - emit([indent(N+3),"end",nl, - indent(3),"end,",nl]) - end, - gen_dec_listofopentypes(DecObj,Rest,true). - - -emit_opt_or_mand_check(Val,Term) -> - emit([indent(3),"case ",Term," of",nl, - indent(6),{asis,Val}," ->",{asis,Val},";",nl, - indent(6),"_ ->",nl]). - -%% ENCODE GENERATOR FOR THE CHOICE TYPE ******* -%% assume Val = {Alternative,AltType} -%% generate -%%[ -%% ?RT_PER:set_choice(element(1,Val),Altnum,Altlist,ext), -%%case element(1,Val) of -%% alt1 -> -%% encode_alt1(element(2,Val)); -%% alt2 -> -%% encode_alt2(element(2,Val)) -%%end -%%]. - -gen_encode_choice(Erule,Typename,D) when is_record(D,type) -> - {'CHOICE',CompList} = D#type.def, - emit({"[",nl}), +gen_encode_choice_imm(Erule, TopType, #type{def={'CHOICE',CompList}}) -> Ext = extensible_enc(CompList), - gen_enc_choice(Erule,Typename,CompList,Ext), - emit({nl,"].",nl}). + Aligned = is_aligned(Erule), + Cs = gen_enc_choice(Erule, TopType, CompList, Ext), + [{assign,{expr,"{ChoiceTag,ChoiceVal}"},"Val"}| + asn1ct_imm:per_enc_choice('ChoiceTag', Cs, Aligned)]. gen_decode_choice(Erules,Typename,D) when is_record(D,type) -> asn1ct_name:start(), @@ -496,72 +553,48 @@ gen_decode_choice(Erules,Typename,D) when is_record(D,type) -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Encode generator for SEQUENCE OF type - -gen_encode_sof(Erule,Typename,SeqOrSetOf,D) when is_record(D,type) -> +gen_encode_sof(Erule, Typename, SeqOrSetOf, D) -> asn1ct_name:start(), - {_SeqOrSetOf,ComponentType} = D#type.def, - emit({"[",nl}), - SizeConstraint = asn1ct_imm:effective_constraint(bitstring, - D#type.constraint), - ObjFun = - case D#type.tablecinf of - [{objfun,_}|_R] -> - ", ObjFun"; - _-> - "" - end, - gen_encode_length(Erule, SizeConstraint), - emit({indent(3),"'enc_",asn1ct_gen:list2name(Typename), - "_components'(Val",ObjFun,", [])"}), - emit({nl,"].",nl}), - gen_encode_sof_components(Erule, Typename, SeqOrSetOf, ComponentType). - - -%% Logic copied from asn1_per_bin_rt2ct:encode_constrained_number -gen_encode_length(per, {Lb,Ub}) when Ub =< 65535, Lb >= 0 -> - Range = Ub - Lb + 1, - V2 = ["(length(Val) - ",Lb,")"], - Encode = if - Range == 1 -> - "[]"; - Range == 2 -> - {"[",V2,"]"}; - Range =< 4 -> - {"[10,2,",V2,"]"}; - Range =< 8 -> - {"[10,3,",V2,"]"}; - Range =< 16 -> - {"[10,4,",V2,"]"}; - Range =< 32 -> - {"[10,5,",V2,"]"}; - Range =< 64 -> - {"[10,6,",V2,"]"}; - Range =< 128 -> - {"[10,7,",V2,"]"}; - Range =< 255 -> - {"[10,8,",V2,"]"}; - Range =< 256 -> - {"[20,1,",V2,"]"}; - Range =< 65536 -> - {"[20,2,<<",V2,":16>>]"}; - true -> - {call,per,encode_length, - [{asis,{Lb,Ub}},"length(Val)"]} - end, - emit({nl,Encode,",",nl}); -gen_encode_length(Erules, SizeConstraint) -> - emit([nl,indent(3), - case SizeConstraint of - no -> - {call,Erules,encode_length,["length(Val)"]}; - _ -> - {call,Erules,encode_length, - [{asis,SizeConstraint},"length(Val)"]} - end, - com,nl]). + Imm = gen_encode_sof_imm(Erule, Typename, SeqOrSetOf, D), + asn1ct_imm:enc_cg(Imm, is_aligned(Erule)), + emit([".",nl,nl]). -gen_decode_sof(Erules,Typename,SeqOrSetOf,D) when is_record(D,type) -> +gen_encode_sof_imm(Erule, Typename, SeqOrSetOf, #type{}=D) -> + {_SeqOrSetOf,ComponentType} = D#type.def, + Aligned = is_aligned(Erule), + Constructed_Suffix = + asn1ct_gen:constructed_suffix(SeqOrSetOf, + ComponentType#type.def), + Conttype = asn1ct_gen:get_inner(ComponentType#type.def), + Currmod = get(currmod), + Imm0 = case asn1ct_gen:type(Conttype) of + {primitive,bif} -> + asn1ct_gen_per:gen_encode_prim_imm('Comp', ComponentType, Aligned); + {constructed,bif} -> + TypeName = [Constructed_Suffix|Typename], + Enc = enc_func(asn1ct_gen:list2name(TypeName)), + ObjArg = case D#type.tablecinf of + [{objfun,_}|_] -> [{var,"ObjFun"}]; + _ -> [] + end, + [{apply,Enc,[{var,"Comp"}|ObjArg]}]; + #'Externaltypereference'{module=Currmod,type=Ename} -> + [{apply,enc_func(Ename),[{var,"Comp"}]}]; + #'Externaltypereference'{module=EMod,type=Ename} -> + [{apply,{EMod,enc_func(Ename)},[{var,"Comp"}]}]; + 'ASN1_OPEN_TYPE' -> + asn1ct_gen_per:gen_encode_prim_imm('Comp', + #type{def='ASN1_OPEN_TYPE'}, + Aligned) + end, + asn1ct_imm:per_enc_sof('Val', D#type.constraint, 'Comp', Imm0, Aligned). + +gen_decode_sof(Erules, Typename, SeqOrSetOf, #type{}=D) -> asn1ct_name:start(), + do_gen_decode_sof(Erules, Typename, SeqOrSetOf, D, true), + emit([".",nl,nl]). + +do_gen_decode_sof(Erules, Typename, SeqOrSetOf, D, NeedRest) -> {_SeqOrSetOf,ComponentType} = D#type.def, SizeConstraint = asn1ct_imm:effective_constraint(bitstring, D#type.constraint), @@ -573,10 +606,16 @@ gen_decode_sof(Erules,Typename,SeqOrSetOf,D) when is_record(D,type) -> "" end, {Num,Buf} = gen_decode_length(SizeConstraint, Erules), + Key = erlang:md5(term_to_binary({Typename,SeqOrSetOf, + ComponentType,NeedRest})), + Gen = fun(_Fd, Name) -> + gen_decode_sof_components(Erules, Name, + Typename, SeqOrSetOf, + ComponentType, NeedRest) + end, + F = asn1ct_func:call_gen("dec_components", Key, Gen), emit([",",nl, - "'dec_",asn1ct_gen:list2name(Typename), - "_components'(",Num,", ",Buf,ObjFun,", []).",nl,nl]), - gen_decode_sof_components(Erules, Typename, SeqOrSetOf, ComponentType). + {asis,F},"(",Num,", ",Buf,ObjFun,", [])"]). is_aligned(per) -> true; is_aligned(uper) -> false. @@ -586,7 +625,7 @@ gen_decode_length(Constraint, Erule) -> Imm = asn1ct_imm:per_dec_length(Constraint, true, is_aligned(Erule)), asn1ct_imm:dec_slim_cg(Imm, "Bytes"). -gen_encode_sof_components(Erule,Typename,SeqOrSetOf,Cont) -> +gen_decode_sof_components(Erule, Name, Typename, SeqOrSetOf, Cont, NeedRest) -> {ObjFun,ObjFun_Var} = case Cont#type.tablecinf of [{objfun,_}|_R] -> @@ -594,76 +633,38 @@ gen_encode_sof_components(Erule,Typename,SeqOrSetOf,Cont) -> _ -> {"",""} end, - emit({"'enc_",asn1ct_gen:list2name(Typename),"_components'([]", - ObjFun_Var,", Acc) -> lists:reverse(Acc);",nl,nl}), - emit({"'enc_",asn1ct_gen:list2name(Typename),"_components'([H|T]", - ObjFun,", Acc) ->",nl}), - emit({"'enc_",asn1ct_gen:list2name(Typename),"_components'(T"}), - emit({ObjFun,", ["}), - %% the component encoder - Constructed_Suffix = asn1ct_gen:constructed_suffix(SeqOrSetOf, - Cont#type.def), - - Conttype = asn1ct_gen:get_inner(Cont#type.def), - Currmod = get(currmod), - case asn1ct_gen:type(Conttype) of - {primitive,bif} -> - asn1ct_gen_per:gen_encode_prim(Erule, Cont, "H"); - {constructed,bif} -> - NewTypename = [Constructed_Suffix|Typename], - emit({"'enc_",asn1ct_gen:list2name(NewTypename),"'(H", - ObjFun,")",nl,nl}); - #'Externaltypereference'{module=Currmod,type=Ename} -> - emit({"'enc_",Ename,"'(H)",nl,nl}); - #'Externaltypereference'{module=EMod,type=EType} -> - emit({"'",EMod,"':'enc_",EType,"'(H)",nl,nl}); - 'ASN1_OPEN_TYPE' -> - asn1ct_gen_per:gen_encode_prim(Erule, - #type{def='ASN1_OPEN_TYPE'}, - "H"); - _ -> - emit({"'enc_",Conttype,"'(H)",nl,nl}) + case NeedRest of + false -> + emit([{asis,Name},"(0, _Bytes",ObjFun_Var,", Acc) ->",nl, + "lists:reverse(Acc);",nl]); + true -> + emit([{asis,Name},"(0, Bytes",ObjFun_Var,", Acc) ->",nl, + "{lists:reverse(Acc),Bytes};",nl]) end, - emit({" | Acc]).",nl}). - -gen_decode_sof_components(Erule,Typename,SeqOrSetOf,Cont) -> - {ObjFun,ObjFun_Var} = - case Cont#type.tablecinf of - [{objfun,_}|_R] -> - {", ObjFun",", _"}; - _ -> - {"",""} - end, - emit({"'dec_",asn1ct_gen:list2name(Typename), - "_components'(0, Bytes",ObjFun_Var,", Acc) ->",nl, - indent(3),"{lists:reverse(Acc), Bytes};",nl}), - emit({"'dec_",asn1ct_gen:list2name(Typename), - "_components'(Num, Bytes",ObjFun,", Acc) ->",nl}), - emit({indent(3),"{Term,Remain} = "}), + emit([{asis,Name},"(Num, Bytes",ObjFun,", Acc) ->",nl, + "{Term,Remain} = "]), Constructed_Suffix = asn1ct_gen:constructed_suffix(SeqOrSetOf, Cont#type.def), Conttype = asn1ct_gen:get_inner(Cont#type.def), - Ctgenmod = asn1ct_gen:ct_gen_module(Erule), case asn1ct_gen:type(Conttype) of {primitive,bif} -> - Ctgenmod:gen_dec_prim(Erule,Cont,"Bytes"), + asn1ct_gen_per:gen_dec_prim(Erule, Cont, "Bytes"), emit({com,nl}); {constructed,bif} -> NewTypename = [Constructed_Suffix|Typename], emit({"'dec_",asn1ct_gen:list2name(NewTypename), - "'(Bytes, telltype",ObjFun,"),",nl}); + "'(Bytes",ObjFun,"),",nl}); #'Externaltypereference'{}=Etype -> asn1ct_gen_per:gen_dec_external(Etype, "Bytes"), emit([com,nl]); 'ASN1_OPEN_TYPE' -> - Ctgenmod:gen_dec_prim(Erule,#type{def='ASN1_OPEN_TYPE'}, - "Bytes"), + asn1ct_gen_per:gen_dec_prim(Erule, #type{def='ASN1_OPEN_TYPE'}, + "Bytes"), emit({com,nl}); _ -> - emit({"'dec_",Conttype,"'(Bytes,telltype),",nl}) + emit({"'dec_",Conttype,"'(Bytes),",nl}) end, - emit({indent(3),"'dec_",asn1ct_gen:list2name(Typename), - "_components'(Num-1, Remain",ObjFun,", [Term|Acc]).",nl}). + emit([{asis,Name},"(Num-1, Remain",ObjFun,", [Term|Acc]).",nl]). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -754,27 +755,6 @@ gen_dec_optionals(Optionals) -> end, {imm,Imm0,E}. -gen_fixoptionals([{Pos,Def}|R]) -> - asn1ct_name:new(fixopt), - emit({{curr,fixopt}," = case element(",{asis,Pos},",",{curr,val},") of",nl, - "asn1_DEFAULT -> 0;",nl, - {asis,Def}," -> 0;",nl, - "_ -> 1",nl, - "end,",nl}), - gen_fixoptionals(R); -gen_fixoptionals([Pos|R]) -> - gen_fixoptionals([{Pos,asn1_NOVALUE}|R]); -gen_fixoptionals([]) -> - ok. - - -param_map(Fun, [H]) -> - [Fun(H)]; -param_map(Fun, [H|T]) -> - [Fun(H),","|param_map(Fun,T)]. - - - %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Produce a list with positions (in the Value record) where %% there are optional components, start with 2 because first element @@ -788,15 +768,13 @@ optionals({L1,Ext,L2}) -> optionals({L,_Ext}) -> optionals(L,[],2); optionals(L) -> optionals(L,[],2). -optionals([{'EXTENSIONMARK',_,_}|Rest],Acc,Pos) -> - optionals(Rest,Acc,Pos); % optionals in extension are currently not handled -optionals([#'ComponentType'{prop='OPTIONAL'}|Rest],Acc,Pos) -> - optionals(Rest,[Pos|Acc],Pos+1); -optionals([#'ComponentType'{prop={'DEFAULT',Val}}|Rest],Acc,Pos) -> - optionals(Rest,[{Pos,Val}|Acc],Pos+1); -optionals([#'ComponentType'{}|Rest],Acc,Pos) -> - optionals(Rest,Acc,Pos+1); -optionals([],Acc,_) -> +optionals([#'ComponentType'{prop='OPTIONAL'}|Rest], Acc, Pos) -> + optionals(Rest, [Pos|Acc], Pos+1); +optionals([#'ComponentType'{prop={'DEFAULT',Val}}|Rest], Acc, Pos) -> + optionals(Rest, [{Pos,Val}|Acc], Pos+1); +optionals([#'ComponentType'{}|Rest], Acc, Pos) -> + optionals(Rest, Acc, Pos+1); +optionals([], Acc, _) -> lists:reverse(Acc). %%%%%%%%%%%%%%%%%%%%%% @@ -858,33 +836,32 @@ add_textual_order1(Cs,NumIn) -> end, NumIn,Cs). -gen_enc_components_call(Erule,TopType,{Root,ExtList},MaybeComma,DynamicEnc,Ext) -> - gen_enc_components_call(Erule,TopType,{Root,ExtList,[]},MaybeComma,DynamicEnc,Ext); -gen_enc_components_call(Erule,TopType,CL={Root,ExtList,Root2},MaybeComma,DynamicEnc,Ext) -> +gen_enc_components_call(Erule,TopType,{Root,ExtList}, DynamicEnc,Ext) -> + gen_enc_components_call(Erule,TopType,{Root,ExtList,[]}, DynamicEnc,Ext); +gen_enc_components_call(Erule,TopType,CL={Root,ExtList,Root2}, DynamicEnc,Ext) -> %% The type has extensionmarker - Rpos = gen_enc_components_call1(Erule,TopType,Root++Root2,1,MaybeComma,DynamicEnc,noext), - case Ext of - {ext,_,ExtNum} when ExtNum > 0 -> - emit([nl, - ",Extensions",nl]); - - _ -> true - end, + {Imm0,Rpos} = gen_enc_components_call1(Erule,TopType,Root++Root2,1, DynamicEnc,noext,[]), + ExtImm = case Ext of + {ext,_,ExtNum} when ExtNum > 0 -> + [{var,"Extensions"}]; + _ -> + [] + end, %handle extensions {extgrouppos,ExtGroupPosLen} = extgroup_pos_and_length(CL), NewExtList = wrap_extensionAdditionGroups(ExtList,ExtGroupPosLen), - gen_enc_components_call1(Erule,TopType,NewExtList,Rpos,MaybeComma,DynamicEnc,Ext); -gen_enc_components_call(Erule,TopType, CompList, MaybeComma, DynamicEnc, Ext) -> + {Imm1,_} = gen_enc_components_call1(Erule,TopType,NewExtList,Rpos,DynamicEnc,Ext,[]), + Imm0 ++ [ExtImm|Imm1]; +gen_enc_components_call(Erule,TopType, CompList, DynamicEnc, Ext) -> %% The type has no extensionmarker - gen_enc_components_call1(Erule,TopType,CompList,1,MaybeComma,DynamicEnc,Ext). + {Imm,_} = gen_enc_components_call1(Erule,TopType,CompList,1,DynamicEnc,Ext,[]), + Imm. gen_enc_components_call1(Erule,TopType, [C=#'ComponentType'{name=Cname,typespec=Type,prop=Prop}|Rest], Tpos, - MaybeComma, DynamicEnc, Ext) -> + DynamicEnc, Ext, Acc) -> - put(component_type,{true,C}), - %% information necessary in asn1ct_gen_per_rt2ct:gen_encode_prim TermNo = case C#'ComponentType'.textual_order of undefined -> @@ -892,90 +869,48 @@ gen_enc_components_call1(Erule,TopType, CanonicalNum -> CanonicalNum end, - emit(MaybeComma), - case Prop of - 'OPTIONAL' -> - gen_enc_component_optional(Erule,TopType,Cname,Type,TermNo,DynamicEnc,Ext); - {'DEFAULT',DefVal} -> - gen_enc_component_default(Erule,TopType,Cname,Type,TermNo,DynamicEnc,Ext,DefVal); + Element0 = make_element(TermNo+1, asn1ct_gen:mk_var(asn1ct_name:curr(val))), + {Imm0,Element} = asn1ct_imm:enc_bind_var(Element0), + Imm1 = gen_enc_line_imm(Erule, TopType, Cname, Type, Element, DynamicEnc, Ext), + Category = case {Prop,Ext} of + {'OPTIONAL',_} -> + optional; + {{'DEFAULT',DefVal},_} -> + {default,DefVal}; + {_,{ext,ExtPos,_}} when Tpos >= ExtPos -> + optional; + {_,_} -> + mandatory + end, + Imm2 = case Category of + mandatory -> + Imm1; + optional -> + asn1ct_imm:enc_absent(Element, [asn1_NOVALUE], Imm1); + {default,Def} -> + asn1ct_imm:enc_absent(Element, [asn1_DEFAULT,Def], Imm1) + end, + Imm = case Imm2 of + [] -> []; + _ -> Imm0 ++ Imm2 + end, + gen_enc_components_call1(Erule, TopType, Rest, Tpos+1, DynamicEnc, Ext, [Imm|Acc]); +gen_enc_components_call1(_Erule,_TopType,[],Pos,_,_, Acc) -> + ImmList = lists:reverse(Acc), + {ImmList,Pos}. + +gen_enc_line_imm(Erule, TopType, Cname, Type, Element, DynamicEnc, Ext) -> + Imm0 = gen_enc_line_imm_1(Erule, TopType, Cname, Type, + Element, DynamicEnc), + Aligned = is_aligned(Erule), + case Ext of + {ext,_Ep2,_} -> + asn1ct_imm:per_enc_open_type(Imm0, Aligned); _ -> - case Ext of - {ext,ExtPos,_} when Tpos >= ExtPos -> - gen_enc_component_optional(Erule,TopType,Cname,Type,TermNo,DynamicEnc,Ext); - _ -> - gen_enc_component_mandatory(Erule,TopType,Cname,Type,TermNo,DynamicEnc,Ext) - end - end, - - erase(component_type), + Imm0 + end. - case Rest of - [] -> - Tpos+1; - _ -> - emit({com,nl}), - gen_enc_components_call1(Erule,TopType,Rest,Tpos+1,"",DynamicEnc,Ext) - end; -gen_enc_components_call1(_Erule,_TopType,[],Pos,_,_,_) -> - Pos. - -gen_enc_component_default(Erule,TopType,Cname,Type,Pos,DynamicEnc,Ext,DefaultVal) -> - Element = make_element(Pos+1,asn1ct_gen:mk_var(asn1ct_name:curr(val))), - emit({"case ",Element," of",nl}), -% emit({"asn1_DEFAULT -> [];",nl}), - emit({"DFLT when DFLT == asn1_DEFAULT; DFLT == ",{asis,DefaultVal}," -> [];",nl}), - - asn1ct_name:new(tmpval), - emit({{curr,tmpval}," ->",nl}), - InnerType = asn1ct_gen:get_inner(Type#type.def), - emit({nl,"%% attribute number ",Pos," with type ", - InnerType,nl}), - NextElement = asn1ct_gen:mk_var(asn1ct_name:curr(tmpval)), - gen_enc_line(Erule,TopType,Cname,Type,NextElement, Pos,DynamicEnc,Ext), - emit({nl,"end"}). - -gen_enc_component_optional(Erule,TopType,Cname, - Type=#type{def=#'SEQUENCE'{ - extaddgroup=Number, - components=_ExtGroupCompList}}, - Pos,DynamicEnc,Ext) when is_integer(Number) -> - - Element = make_element(Pos+1,asn1ct_gen:mk_var(asn1ct_name:curr(val))), - emit({"case ",Element," of",nl}), - - emit({"asn1_NOVALUE -> [];",nl}), - asn1ct_name:new(tmpval), - emit({{curr,tmpval}," ->",nl}), - InnerType = asn1ct_gen:get_inner(Type#type.def), - emit({nl,"%% attribute number ",Pos," with type ", - InnerType,nl}), - NextElement = asn1ct_gen:mk_var(asn1ct_name:curr(tmpval)), - gen_enc_line(Erule,TopType,Cname,Type,NextElement, Pos,DynamicEnc,Ext), - emit({nl,"end"}); -gen_enc_component_optional(Erule,TopType,Cname,Type,Pos,DynamicEnc,Ext) -> - Element = make_element(Pos+1,asn1ct_gen:mk_var(asn1ct_name:curr(val))), - emit({"case ",Element," of",nl}), - - emit({"asn1_NOVALUE -> [];",nl}), - asn1ct_name:new(tmpval), - emit({{curr,tmpval}," ->",nl}), - InnerType = asn1ct_gen:get_inner(Type#type.def), - emit({nl,"%% attribute number ",Pos," with type ", - InnerType,nl}), - NextElement = asn1ct_gen:mk_var(asn1ct_name:curr(tmpval)), - gen_enc_line(Erule,TopType,Cname,Type,NextElement, Pos,DynamicEnc,Ext), - emit({nl,"end"}). - -gen_enc_component_mandatory(Erule,TopType,Cname,Type,Pos,DynamicEnc,Ext) -> - InnerType = asn1ct_gen:get_inner(Type#type.def), - emit({nl,"%% attribute number ",Pos," with type ", - InnerType,nl}), - gen_enc_line(Erule,TopType,Cname,Type,[],Pos,DynamicEnc,Ext). - -gen_enc_line(Erule,TopType, Cname, Type, [], Pos,DynamicEnc,Ext) -> - Element = make_element(Pos+1,asn1ct_gen:mk_var(asn1ct_name:curr(val))), - gen_enc_line(Erule,TopType,Cname,Type,Element, Pos,DynamicEnc,Ext); -gen_enc_line(Erule,TopType,Cname,Type,Element, _Pos,DynamicEnc,Ext) -> +gen_enc_line_imm_1(Erule, TopType, Cname, Type, Element, DynamicEnc) -> Atype = case Type of #type{def=#'ObjectClassFieldType'{type=InnerType}} -> @@ -983,81 +918,157 @@ gen_enc_line(Erule,TopType,Cname,Type,Element, _Pos,DynamicEnc,Ext) -> _ -> asn1ct_gen:get_inner(Type#type.def) end, - - case Ext of - {ext,_Ep1,_} -> - asn1ct_func:need({Erule,encode_open_type,1}), - asn1ct_func:need({Erule,complete,1}), - emit(["encode_open_type(complete("]); - _ -> true - end, - + Aligned = is_aligned(Erule), case Atype of {typefield,_} -> - case DynamicEnc of - {_LeadingAttrName,Fun} -> - case (Type#type.def)#'ObjectClassFieldType'.fieldname of - {Name,RestFieldNames} when is_atom(Name) -> - asn1ct_func:need({Erule,complete,1}), - asn1ct_func:need({Erule,encode_open_type,1}), - emit({"encode_open_type(complete(",nl}), - emit({" ",Fun,"(",{asis,Name},", ", - Element,", ",{asis,RestFieldNames},")))"}); - Other -> - throw({asn1,{'internal error',Other}}) - end - end; - {objectfield,PrimFieldName1,PFNList} -> - case DynamicEnc of - {_LeadingAttrName,Fun} -> - asn1ct_func:need({Erule,complete,1}), - asn1ct_func:need({Erule,encode_open_type,1}), - emit({"encode_open_type(" - "complete(",nl}), - emit({" ",Fun,"(",{asis,PrimFieldName1}, - ", ",Element,", ",{asis,PFNList},")))"}) + {_LeadingAttrName,Fun} = DynamicEnc, + case (Type#type.def)#'ObjectClassFieldType'.fieldname of + {Name,RestFieldNames} when is_atom(Name) -> + Imm = enc_var_type_call(Erule, Name, RestFieldNames, + Type, Fun, Element), + asn1ct_imm:per_enc_open_type(Imm, Aligned) end; _ -> CurrMod = get(currmod), case asn1ct_gen:type(Atype) of - #'Externaltypereference'{module=Mod,type=EType} when - (CurrMod==Mod) -> - emit({"'enc_",EType,"'(",Element,")"}); + #'Externaltypereference'{module=CurrMod,type=EType} -> + [{apply,enc_func(EType),[{expr,Element}]}]; #'Externaltypereference'{module=Mod,type=EType} -> - emit({"'",Mod,"':'enc_", - EType,"'(",Element,")"}); + [{apply,{Mod,enc_func(EType)},[{expr,Element}]}]; {primitive,bif} -> - asn1ct_gen_per:gen_encode_prim(Erule, Type, Element); + asn1ct_gen_per:gen_encode_prim_imm(Element, Type, Aligned); 'ASN1_OPEN_TYPE' -> case Type#type.def of #'ObjectClassFieldType'{type=OpenType} -> - asn1ct_gen_per:gen_encode_prim(Erule, - #type{def=OpenType}, - Element); + asn1ct_gen_per:gen_encode_prim_imm(Element, + #type{def=OpenType}, + Aligned); _ -> - asn1ct_gen_per:gen_encode_prim(Erule, Type, - Element) + asn1ct_gen_per:gen_encode_prim_imm(Element, + Type, + Aligned) end; {constructed,bif} -> NewTypename = [Cname|TopType], + Enc = enc_func(asn1ct_gen:list2name(NewTypename)), case {Type#type.tablecinf,DynamicEnc} of {[{objfun,_}|_R],{_,EncFun}} -> - emit({"'enc_", - asn1ct_gen:list2name(NewTypename), - "'(",Element,", ",EncFun,")"}); + [{apply,Enc,[{expr,Element},{var,EncFun}]}]; _ -> - emit({"'enc_", - asn1ct_gen:list2name(NewTypename), - "'(",Element,")"}) + [{apply,Enc,[{expr,Element}]}] end end - end, - case Ext of - {ext,_Ep2,_} -> - emit("))"); - _ -> true end. +enc_func(Type) -> + enc_func("enc_", Type). + +enc_func(Prefix, Name) -> + list_to_atom(lists:concat([Prefix,Name])). + +enc_var_type_call(Erule, Name, RestFieldNames, + #type{tablecinf=TCI}, Fun, Val) -> + [{objfun,#'Externaltypereference'{module=Xmod,type=Xtype}}] = TCI, + #typedef{typespec=ObjSet0} = asn1_db:dbget(Xmod, Xtype), + #'ObjectSet'{class=Class,set=ObjSet1} = ObjSet0, + #'Externaltypereference'{module=ClMod,type=ClType} = Class, + #classdef{typespec=ClassDef} = asn1_db:dbget(ClMod, ClType), + #objectclass{fields=ClassFields} = ClassDef, + Extensible = lists:member('EXTENSIONMARK', ObjSet1), + ObjSet2 = [{Key,fix_object_code(Name, Code, ClassFields)} || + {_,Key,Code} <- ObjSet1], + ObjSet = lists:sort([P || {_,B}=P <- ObjSet2, B =/= none]), + Key = erlang:md5(term_to_binary({encode,ObjSet,RestFieldNames,Extensible})), + Gen = fun(_Fd, N) -> + enc_objset(Erule, Name, N, ObjSet, + RestFieldNames, Extensible) + end, + Prefix = lists:concat(["enc_os_",Name]), + F = asn1ct_func:call_gen(Prefix, Key, Gen), + [{apply,F,[{var,atom_to_list(Val)},{var,Fun}]}]. + +fix_object_code(Name, [{Name,B}|_], _ClassFields) -> + B; +fix_object_code(Name, [_|T], ClassFields) -> + fix_object_code(Name, T, ClassFields); +fix_object_code(Name, [], ClassFields) -> + case lists:keyfind(Name, 2, ClassFields) of + {typefield,Name,'OPTIONAL'} -> + none; + {objectfield,Name,_,_,'OPTIONAL'} -> + none; + {typefield,Name,{'DEFAULT',#type{}=Type}} -> + InnerType = asn1ct_gen:get_inner(Type#type.def), + case asn1ct_gen:type(InnerType) of + {primitive,bif} -> + #typedef{name={primitive,bif},typespec=Type}; + {constructed,bif} -> + #typedef{name={constructed,bif},typespec=Type} + end + end. + + +enc_objset(Erule, Component, Name, ObjSet, RestFieldNames, Extensible) -> + asn1ct_name:start(), + Aligned = is_aligned(Erule), + E = {error, + fun() -> + emit(["exit({'Type not compatible with table constraint'," + "{component,",{asis,Component},"}," + "{value,Val}," + "{unique_name_and_value,'_'}})",nl]) + end}, + Imm = [{'cond', + [[{eq,{var,"Id"},Key}| + enc_obj(Erule, Obj, RestFieldNames, Aligned)] || + {Key,Obj} <- ObjSet] ++ + [['_',case Extensible of + false -> E; + true -> {put_bits,{var,"Val"},binary,[1]} + end]]}], + emit([{asis,Name},"(Val, Id) ->",nl]), + asn1ct_imm:enc_cg(Imm, Aligned), + emit([".",nl]). + +enc_obj(Erule, Obj, RestFieldNames0, Aligned) -> + case Obj of + #typedef{name={primitive,bif},typespec=Def} -> + asn1ct_gen_per:gen_encode_prim_imm('Val', Def, Aligned); + #typedef{name={constructed,bif},typespec=Def} -> + InnerType = asn1ct_gen:get_inner(Def#type.def), + case InnerType of + 'CHOICE' -> + gen_encode_choice_imm(Erule, name, Def); + 'SET' -> + gen_encode_constructed_imm(Erule, name, Def); + 'SET OF' -> + gen_encode_sof_imm(Erule, name, InnerType, Def); + 'SEQUENCE' -> + gen_encode_constructed_imm(Erule, name, Def); + 'SEQUENCE OF' -> + gen_encode_sof_imm(Erule, name, InnerType, Def) + end; + #typedef{name=Type} -> + [{apply,enc_func(Type),[{var,"Val"}]}]; + #'Externalvaluereference'{module=Mod,value=Value} -> + case asn1_db:dbget(Mod, Value) of + #typedef{typespec=#'Object'{def=Def}} -> + {object,_,Fields} = Def, + [NextField|RestFieldNames] = RestFieldNames0, + {NextField,Typedef} = lists:keyfind(NextField, 1, Fields), + enc_obj(Erule, Typedef, RestFieldNames, Aligned) + end; + #'Externaltypereference'{module=Mod,type=Type} -> + Func = enc_func(Type), + case get(currmod) of + Mod -> + [{apply,Func,[{var,"Val"}]}]; + _ -> + [{apply,{Mod,Func},[{var,"Val"}]}] + end + end. + + gen_dec_components_call(Erule, TopType, {Root,ExtList}, DecInfObj, Ext, NumberOfOptionals) -> gen_dec_components_call(Erule,TopType,{Root,ExtList,[]}, @@ -1163,14 +1174,6 @@ gen_dec_comp_call(Comp, Erule, TopType, Tpos, OptTable, DecInfObj, emit(["{",{curr,tmpterm},", ",{next,bytes},"} = "]), St end; - %%{objectfield,_,_} when Ext == noext, Prop == mandatory -> - {{objectfield,_,_},true} -> - fun(St) -> - asn1ct_name:new(term), - asn1ct_name:new(tmpterm), - emit(["{",{curr,tmpterm},", ",{next,bytes},"} = "]), - St - end; _ -> case Type of #type{def=#'SEQUENCE'{ @@ -1350,25 +1353,19 @@ gen_dec_line_special(Erule, {typefield,_}, _TopType, Comp, false -> % This is in a choice with typefield components {Name,RestFieldNames} = (Type#type.def)#'ObjectClassFieldType'.fieldname, - - asn1ct_name:new(reason), Imm = asn1ct_imm:per_dec_open_type(is_aligned(Erule)), BytesVar = asn1ct_gen:mk_var(asn1ct_name:curr(bytes)), {TmpTerm,TempBuf} = asn1ct_imm:dec_slim_cg(Imm, BytesVar), + emit([com,nl]), + #type{tablecinf=[{objfun, + #'Externaltypereference'{module=Xmod, + type=Xtype}}]} = + Type, + gen_dec_open_type(Erule, "ObjFun", {Xmod,Xtype}, + '_', {'_',{Name,RestFieldNames}, + 'Result',TmpTerm,mandatory}), emit([com,nl, - {next,bytes}," = ",TempBuf,com,nl, - indent(2),"case (catch ObjFun(", - {asis,Name},",",TmpTerm,",telltype,", - {asis,RestFieldNames},")) of", nl]), - emit([indent(4),"{'EXIT',",{curr,reason},"} ->",nl]), - emit([indent(6),"exit({'Type not ", - "compatible with table constraint', ", - {curr,reason},"});",nl]), - asn1ct_name:new(tmpterm), - emit([indent(4),"{",{curr,tmpterm},", _} ->",nl]), - emit([indent(6),"{",{asis,Cname},", {",{curr,tmpterm},", ", - {next,bytes},"}}",nl]), - emit([indent(2),"end"]), + "{",{asis,Cname},",{Result,",TempBuf,"}}"]), {[],PrevSt}; {"got objfun through args","ObjFun"} -> %% this is when the generated code gots the @@ -1388,27 +1385,22 @@ gen_dec_line_special(Erule, {typefield,_}, _TopType, Comp, BytesVar = asn1ct_gen:mk_var(asn1ct_name:curr(bytes)), asn1ct_imm:dec_code_gen(Imm, BytesVar), emit([com,nl]), + #type{tablecinf=[{objfun, + #'Externaltypereference'{module=Xmod, + type=Xtype}}]} = + Type, + Term = asn1ct_gen:mk_var(asn1ct_name:curr(term)), + TmpTerm = asn1ct_gen:mk_var(asn1ct_name:curr(tmpterm)), if Prop =:= mandatory -> - emit([{curr,term}," =",nl," "]); - true -> - emit([" {"]) - end, - emit(["case (catch ObjFun(",{asis,Name},",", - {curr,tmpterm},",telltype,", - {asis,RestFieldNames},")) of", nl]), - emit([" {'EXIT',",{curr,reason},"} ->",nl]), - emit([indent(6),"exit({'Type not ", - "compatible with table constraint', ", - {curr,reason},"});",nl]), - asn1ct_name:new(tmpterm), - emit([indent(4),"{",{curr,tmpterm},", _} ->",nl]), - emit([indent(6),{curr,tmpterm},nl]), - emit([indent(2),"end"]), - if - Prop =:= mandatory -> - ok; + gen_dec_open_type(Erule, "ObjFun", {Xmod,Xtype}, + '_', {'_',{Name,RestFieldNames}, + Term,TmpTerm,Prop}); true -> + emit([" {"]), + gen_dec_open_type(Erule, "ObjFun", {Xmod,Xtype}, + '_', {'_',{Name,RestFieldNames}, + '_',TmpTerm,Prop}), emit([",",nl,{curr,tmpbytes},"}"]) end, {[],PrevSt}; @@ -1425,19 +1417,6 @@ gen_dec_line_special(Erule, {typefield,_}, _TopType, Comp, Prop}],PrevSt} end end; -gen_dec_line_special(Erule, {objectfield,PrimFieldName1,PFNList}, _TopType, - Comp, _DecInfObj) -> - fun({_BytesVar,PrevSt}) -> - Imm = asn1ct_imm:per_dec_open_type(is_aligned(Erule)), - BytesVar = asn1ct_gen:mk_var(asn1ct_name:curr(bytes)), - asn1ct_imm:dec_code_gen(Imm, BytesVar), - #'ComponentType'{name=Cname,prop=Prop} = Comp, - SaveBytes = [{Cname,{PrimFieldName1,PFNList}, - asn1ct_gen:mk_var(asn1ct_name:curr(term)), - asn1ct_gen:mk_var(asn1ct_name:curr(tmpterm)), - Prop}], - {SaveBytes,PrevSt} - end; gen_dec_line_special(Erule, Atype, TopType, Comp, DecInfObj) -> case gen_dec_line_other(Erule, Atype, TopType, Comp) of Fun when is_function(Fun, 1) -> @@ -1458,14 +1437,11 @@ gen_dec_line_special(Erule, Atype, TopType, Comp, DecInfObj) -> gen_dec_line_dec_inf(Comp, DecInfObj) -> #'ComponentType'{name=Cname} = Comp, case DecInfObj of - {Cname,{_,OSet,UniqueFName,ValIndex}} -> + {Cname,{_,_OSet,_UniqueFName,ValIndex}} -> Term = asn1ct_gen:mk_var(asn1ct_name:curr(term)), ValueMatch = value_match(ValIndex,Term), - {ObjSetMod,ObjSetName} = OSet, emit([",",nl, - "ObjFun = ",{asis,ObjSetMod}, - ":'getdec_",ObjSetName,"'(", - {asis,UniqueFName},", ",ValueMatch,")"]); + "ObjFun = ",ValueMatch]); _ -> ok end. @@ -1492,63 +1468,35 @@ gen_dec_line_other(Erule, Atype, TopType, Comp) -> [{objfun,_}|_R] -> fun(BytesVar) -> emit({"'dec_",asn1ct_gen:list2name(NewTypename), - "'(",BytesVar,", telltype, ObjFun)"}) + "'(",BytesVar,", ObjFun)"}) end; _ -> fun(BytesVar) -> emit({"'dec_",asn1ct_gen:list2name(NewTypename), - "'(",BytesVar,", telltype)"}) + "'(",BytesVar,")"}) end end end. -gen_enc_choice(Erule,TopType,CompList,Ext) -> - gen_enc_choice_tag(Erule, CompList, [], Ext), - emit({com,nl}), - emit({"case element(1,Val) of",nl}), - gen_enc_choice2(Erule,TopType, CompList, Ext), - emit({nl,"end"}). - -gen_enc_choice_tag(Erule, {C1,C2}, _, _) -> - N1 = get_name_list(C1), - N2 = get_name_list(C2), - call(Erule,set_choice, - ["element(1, Val)", - {asis,{N1,N2}}, - {asis,{length(N1),length(N2)}}]); -gen_enc_choice_tag(Erule, {C1,C2,C3}, _, _) -> - N1 = get_name_list(C1), - N2 = get_name_list(C2), - N3 = get_name_list(C3), - Root = N1 ++ N3, - call(Erule,set_choice, - ["element(1, Val)", - {asis,{Root,N2}}, - {asis,{length(Root),length(N2)}}]); -gen_enc_choice_tag(Erule, C, _, _) -> - N = get_name_list(C), - call(Erule,set_choice, - ["element(1, Val)", - {asis,N},{asis,length(N)}]). - -get_name_list(L) -> - get_name_list(L,[]). - -get_name_list([#'ComponentType'{name=Name}|T], Acc) -> - get_name_list(T,[Name|Acc]); -get_name_list([], Acc) -> - lists:reverse(Acc). - - -gen_enc_choice2(Erule,TopType, {L1,L2}, Ext) -> - gen_enc_choice2(Erule, TopType, L1 ++ L2, 0, [], Ext); -gen_enc_choice2(Erule, TopType, {L1,L2,L3}, Ext) -> - gen_enc_choice2(Erule, TopType, L1 ++ L3 ++ L2, 0, [], Ext); -gen_enc_choice2(Erule,TopType, L, Ext) -> - gen_enc_choice2(Erule,TopType, L, 0, [], Ext). +gen_enc_choice(Erule, TopType, {Root,Exts}, Ext) -> + Constr = choice_constraint(Root), + gen_enc_choices(Root, Erule, TopType, 0, Constr, Ext) ++ + gen_enc_choices(Exts, Erule, TopType, 0, ext, Ext); +gen_enc_choice(Erule, TopType, {Root,Exts,[]}, Ext) -> + gen_enc_choice(Erule, TopType, {Root,Exts}, Ext); +gen_enc_choice(Erule, TopType, Root, Ext) when is_list(Root) -> + Constr = choice_constraint(Root), + gen_enc_choices(Root, Erule, TopType, 0, Constr, Ext). + +choice_constraint(L) -> + case length(L) of + 0 -> [{'SingleValue',0}]; + Len -> [{'ValueRange',{0,Len-1}}] + end. -gen_enc_choice2(Erule, TopType, [H|T], Pos, Sep0, Ext) -> +gen_enc_choices([H|T], Erule, TopType, Pos, Constr, Ext) -> #'ComponentType'{name=Cname,typespec=Type} = H, + Aligned = is_aligned(Erule), EncObj = case asn1ct_gen:get_constraint(Type#type.constraint, componentrelation) of @@ -1562,16 +1510,25 @@ gen_enc_choice2(Erule, TopType, [H|T], Pos, Sep0, Ext) -> _ -> {no_attr,"ObjFun"} end, - emit([Sep0,{asis,Cname}," ->",nl]), - DoExt = case Ext of - {ext,ExtPos,_} when Pos + 1 < ExtPos -> noext; - _ -> Ext + DoExt = case Constr of + ext -> Ext; + _ -> noext end, - gen_enc_line(Erule, TopType, Cname, Type, "element(2, Val)", - Pos+1, EncObj, DoExt), - Sep = [";",nl], - gen_enc_choice2(Erule, TopType, T, Pos+1, Sep, Ext); -gen_enc_choice2(_, _, [], _, _, _) -> ok. + Tag = case {Ext,Constr} of + {noext,_} -> + asn1ct_imm:per_enc_integer(Pos, Constr, Aligned); + {{ext,_,_},ext} -> + [{put_bits,1,1,[1]}| + asn1ct_imm:per_enc_small_number(Pos, Aligned)]; + {{ext,_,_},_} -> + [{put_bits,0,1,[1]}| + asn1ct_imm:per_enc_integer(Pos, Constr, Aligned)] + end, + Body = gen_enc_line_imm(Erule, TopType, Cname, Type, 'ChoiceVal', + EncObj, DoExt), + Imm = Tag ++ Body, + [{Cname,Imm}|gen_enc_choices(T, Erule, TopType, Pos+1, Constr, Ext)]; +gen_enc_choices([], _, _, _, _, _) -> []. %% Generate the code for CHOICE. If the CHOICE is extensible, %% the structure of the generated code is as follows: @@ -1704,9 +1661,6 @@ gen_dec_choice2(Erule, TopType, [H0|T], Pos, Sep0, Pre) -> gen_dec_choice2(Erule, TopType, T, Pos+1, Sep, Pre); gen_dec_choice2(_, _, [], _, _, _) -> ok. -indent(N) -> - lists:duplicate(N,32). % 32 = space - make_elements(I,Val,ExtCnames) -> make_elements(I,Val,ExtCnames,[]). @@ -1720,7 +1674,7 @@ make_elements(_I,_,[],Acc) -> lists:reverse(Acc). make_element(I, Val) -> - io_lib:format("element(~w,~s)", [I,Val]). + lists:flatten(io_lib:format("element(~w, ~s)", [I,Val])). emit_extaddgroupTerms(VarSeries,[_]) -> asn1ct_name:new(VarSeries), @@ -1787,6 +1741,3 @@ value_match1(Value,[],Acc,Depth) -> Acc ++ Value ++ lists:concat(lists:duplicate(Depth,")")); value_match1(Value,[{VI,_}|VIs],Acc,Depth) -> value_match1(Value,VIs,Acc++lists:concat(["element(",VI,","]),Depth+1). - -is_optimized(per) -> true; -is_optimized(uper) -> false. diff --git a/lib/asn1/src/asn1ct_eval_per.funcs b/lib/asn1/src/asn1ct_eval_per.funcs deleted file mode 100644 index a1ea5cd043..0000000000 --- a/lib/asn1/src/asn1ct_eval_per.funcs +++ /dev/null @@ -1,2 +0,0 @@ -{per,encode_constrained_number,2}. -{per,encode_small_number,1}. diff --git a/lib/asn1/src/asn1ct_eval_uper.funcs b/lib/asn1/src/asn1ct_eval_uper.funcs deleted file mode 100644 index 884a486f40..0000000000 --- a/lib/asn1/src/asn1ct_eval_uper.funcs +++ /dev/null @@ -1,2 +0,0 @@ -{uper,encode_constrained_number,2}. -{uper,encode_small_number,1}. diff --git a/lib/asn1/src/asn1ct_func.erl b/lib/asn1/src/asn1ct_func.erl index ab0dbcce8f..dbadedb683 100644 --- a/lib/asn1/src/asn1ct_func.erl +++ b/lib/asn1/src/asn1ct_func.erl @@ -19,7 +19,7 @@ %% -module(asn1ct_func). --export([start_link/0,need/1,call/3,generate/1]). +-export([start_link/0,need/1,call/3,call_gen/3,call_gen/4,generate/1]). -export([init/1,handle_call/3,handle_cast/2,terminate/2]). start_link() -> @@ -28,15 +28,33 @@ start_link() -> ok. call(M, F, Args) -> - MFA = {M,F,length(Args)}, + A = length(Args), + MFA = {M,F,A}, need(MFA), - asn1ct_gen:emit([F,"(",call_args(Args, ""),")"]). + case M of + binary -> + asn1ct_gen:emit(["binary:",F,"(",call_args(Args, ""),")"]); + _ -> + asn1ct_gen:emit([F,"(",call_args(Args, ""),")"]) + end. +need({binary,_,_}) -> + ok; +need({erlang,_,_}) -> + ok; need(MFA) -> asn1ct_rtt:assert_defined(MFA), cast({need,MFA}). +call_gen(Prefix, Key, Gen, Args) when is_function(Gen, 2) -> + F = req({gen_func,Prefix,Key,Gen}), + asn1ct_gen:emit([F,"(",call_args(Args, ""),")"]). + +call_gen(Prefix, Key, Gen) when is_function(Gen, 2) -> + req({gen_func,Prefix,Key,Gen}). + generate(Fd) -> + do_generate(Fd), Used0 = req(get_used), erase(?MODULE), Used = sofs:set(Used0, [mfa]), @@ -53,10 +71,13 @@ cast(Req) -> %%% Internal functions. --record(st, {used}). +-record(st, {used, %Used functions + gen, %Dynamically generated functions + gc=1 %Counter for generated functions + }). init([]) -> - St = #st{used=gb_sets:empty()}, + St = #st{used=gb_sets:empty(),gen=gb_trees:empty()}, {ok,St}. handle_cast({need,MFA}, #st{used=Used0}=St) -> @@ -69,7 +90,20 @@ handle_cast({need,MFA}, #st{used=Used0}=St) -> end. handle_call(get_used, _From, #st{used=Used}=St) -> - {stop,normal,gb_sets:to_list(Used),St}. + {stop,normal,gb_sets:to_list(Used),St}; +handle_call(get_gen, _From, #st{gen=G0}=St) -> + {L,G} = do_get_gen(gb_trees:to_list(G0), [], []), + {reply,L,St#st{gen=gb_trees:from_orddict(G)}}; +handle_call({gen_func,Prefix,Key,GenFun}, _From, #st{gen=G0,gc=Gc0}=St) -> + case gb_trees:lookup(Key, G0) of + none -> + Name = list_to_atom(Prefix ++ integer_to_list(Gc0)), + Gc = Gc0 + 1, + G = gb_trees:insert(Key, {Name,GenFun}, G0), + {reply,Name,St#st{gen=G,gc=Gc}}; + {value,{Name,_}} -> + {reply,Name,St} + end. terminate(_, _) -> ok. @@ -98,3 +132,22 @@ update_worklist([H|T], Used, Ws) -> update_worklist(T, Used, Ws) end; update_worklist([], _, Ws) -> Ws. + +do_get_gen([{_,{_,done}}=Keep|T], Gacc, Kacc) -> + do_get_gen(T, Gacc, [Keep|Kacc]); +do_get_gen([{K,{Name,_}=V}|T], Gacc, Kacc) -> + do_get_gen(T, [V|Gacc], [{K,{Name,done}}|Kacc]); +do_get_gen([], Gacc, Kacc) -> + {lists:sort(Gacc),lists:reverse(Kacc)}. + +do_generate(Fd) -> + case req(get_gen) of + [] -> + ok; + [_|_]=Gen -> + _ = [begin + ok = file:write(Fd, "\n"), + GenFun(Fd, Name) + end || {Name,GenFun} <- Gen], + do_generate(Fd) + end. diff --git a/lib/asn1/src/asn1ct_gen.erl b/lib/asn1/src/asn1ct_gen.erl index 9095e145a3..3452d29085 100644 --- a/lib/asn1/src/asn1ct_gen.erl +++ b/lib/asn1/src/asn1ct_gen.erl @@ -85,6 +85,8 @@ pgen_module(OutFile,Erules,Module, "%%%",nl]), asn1ct_func:generate(Fid), file:close(Fid), + _ = erase(gen_file_out), + _ = erase(outfile), asn1ct:verbose("--~p--~n",[{generated,ErlFile}],Options). @@ -798,7 +800,12 @@ pgen_exports(Erules,_Module,{Types,Values,_,_,Objects,ObjectSets}) -> gen_exports1(Types,"enc_",1) end, emit({"-export([",nl}), - gen_exports1(Types,"dec_",2) + case Erules of + ber -> + gen_exports1(Types, "dec_", 2); + _ -> + gen_exports1(Types, "dec_", 1) + end end, case [X || {n2n,X} <- get(encoding_options)] of [] -> ok; @@ -819,10 +826,7 @@ pgen_exports(Erules,_Module,{Types,Values,_,_,Objects,ObjectSets}) -> _ -> case erule(Erules) of per -> - emit({"-export([",nl}), - gen_exports1(Objects,"enc_",3), - emit({"-export([",nl}), - gen_exports1(Objects,"dec_",4); + ok; ber -> emit({"-export([",nl}), gen_exports1(Objects,"enc_",3), @@ -833,10 +837,15 @@ pgen_exports(Erules,_Module,{Types,Values,_,_,Objects,ObjectSets}) -> case ObjectSets of [] -> ok; _ -> - emit({"-export([",nl}), - gen_exports1(ObjectSets,"getenc_",2), - emit({"-export([",nl}), - gen_exports1(ObjectSets,"getdec_",2) + case erule(Erules) of + per -> + ok; + ber -> + emit({"-export([",nl}), + gen_exports1(ObjectSets, "getenc_",1), + emit({"-export([",nl}), + gen_exports1(ObjectSets, "getdec_",1) + end end, emit({"-export([info/0]).",nl}), gen_partial_inc_decode_exports(), @@ -900,41 +909,45 @@ pgen_dispatcher(Erules,_Module,{[],_Values,_,_,_Objects,_ObjectSets}) -> pgen_dispatcher(Erules,_Module,{Types,_Values,_,_,_Objects,_ObjectSets}) -> emit(["-export([encode/2,decode/2]).",nl,nl]), gen_info_functions(Erules), - NoFinalPadding = lists:member(no_final_padding,get(encoding_options)), - {Call,BytesAsBinary} = - case Erules of - per -> - asn1ct_func:need({Erules,complete,1}), - {["complete(encode_disp(Type, Data))"],"Bytes"}; - ber -> - {"encode_disp(Type,Data)","iolist_to_binary(Bytes)"}; - uper when NoFinalPadding == true -> - asn1ct_func:need({Erules,complete_NFP,1}), - {"complete_NFP(encode_disp(Type, Data))","Bytes"}; - uper -> - asn1ct_func:need({Erules,complete,1}), - {["complete(encode_disp(Type, Data))"],"Bytes"} - end, - emit(["encode(Type,Data) ->",nl, - "case catch ",Call," of",nl, - " {'EXIT',{error,Reason}} ->",nl, - " {error,Reason};",nl, - " {'EXIT',Reason} ->",nl, - " {error,{asn1,Reason}};",nl, - " {Bytes,_Len} ->",nl, - " {ok,",BytesAsBinary,"};",nl, - " Bytes ->",nl, - " {ok,",BytesAsBinary,"}",nl, - "end.",nl,nl]), - - Return_rest = lists:member(undec_rest,get(encoding_options)), + + Options = get(encoding_options), + NoFinalPadding = lists:member(no_final_padding, Options), + NoOkWrapper = proplists:get_bool(no_ok_wrapper, Options), + + Call = case Erules of + per -> + asn1ct_func:need({Erules,complete,1}), + "complete(encode_disp(Type, Data))"; + ber -> + "iolist_to_binary(element(1, encode_disp(Type, Data)))"; + uper when NoFinalPadding == true -> + asn1ct_func:need({Erules,complete_NFP,1}), + "complete_NFP(encode_disp(Type, Data))"; + uper -> + asn1ct_func:need({Erules,complete,1}), + "complete(encode_disp(Type, Data))" + end, + + emit(["encode(Type, Data) ->",nl]), + case NoOkWrapper of + true -> + emit([" ",Call,"."]); + false -> + emit(["try ",Call," of",nl, + " Bytes ->",nl, + " {ok,Bytes}",nl, + try_catch()]) + end, + emit([nl,nl]), + + Return_rest = proplists:get_bool(undec_rest, Options), Data = case {Erules,Return_rest} of {ber,true} -> "Data0"; _ -> "Data" end, emit(["decode(Type,",Data,") ->",nl]), - DecAnonymous = + DecWrap = case {Erules,Return_rest} of {ber,false} -> asn1ct_func:need({ber,ber_decode_nif,1}), @@ -946,49 +959,26 @@ pgen_dispatcher(Erules,_Module,{Types,_Values,_,_,_Objects,_ObjectSets}) -> _ -> "Data" end, - DecWrap = case Erules of - ber -> - DecAnonymous; - _ -> "Data" - end, - - emit(["case catch decode_disp(Type,",DecWrap,") of",nl, - " {'EXIT',{error,Reason}} ->",nl, - " {error,Reason};",nl, - " {'EXIT',Reason} ->",nl, - " {error,{asn1,Reason}};",nl]), - case {Erules,Return_rest} of - {ber,false} -> - emit([" Result ->",nl, - " {ok,Result}",nl]); - {ber,true} -> - emit([" Result ->",nl, - " {ok,Result,Rest}",nl]); - {_,false} -> - emit([" {X,_Rest} ->",nl, - " {ok,X};",nl, - " {X,_Rest,_Len} ->",nl, - " {ok,X}",nl]); - {per,true} -> - emit([" {X,{_,Rest}} ->",nl, - " {ok,X,Rest};",nl, - " {X,{_,Rest},_Len} ->",nl, - " {ok,X,Rest};",nl, - " {X,Rest} ->",nl, - " {ok,X,Rest};",nl, - " {X,Rest,_Len} ->",nl, - " {ok,X,Rest}",nl]); - {uper,true} -> - emit([" {X,{_,Rest}} ->",nl, - " {ok,X,Rest};",nl, - " {X,{_,Rest},_Len} ->",nl, - " {ok,X,Rest};",nl, - " {X,Rest} ->",nl, - " {ok,X,Rest};",nl, - " {X,Rest,_Len} ->",nl, - " {ok,X,Rest}",nl]) + emit([case NoOkWrapper of + false -> "try"; + true -> "case" + end, " decode_disp(Type, ",DecWrap,") of",nl]), + case erule(Erules) of + ber -> + emit([" Result ->",nl]); + per -> + emit([" {Result,Rest} ->",nl]) + end, + case Return_rest of + false -> result_line(NoOkWrapper, ["Result"]); + true -> result_line(NoOkWrapper, ["Result","Rest"]) + end, + case NoOkWrapper of + false -> + emit([nl,try_catch(),nl,nl]); + true -> + emit([nl,"end.",nl,nl]) end, - emit(["end.",nl,nl]), gen_decode_partial_incomplete(Erules), @@ -999,10 +989,32 @@ pgen_dispatcher(Erules,_Module,{Types,_Values,_,_,_Objects,_ObjectSets}) -> gen_partial_inc_dispatcher(); _PerOrPer_bin -> gen_dispatcher(Types,"encode_disp","enc_",""), - gen_dispatcher(Types,"decode_disp","dec_",",mandatory") + gen_dispatcher(Types,"decode_disp","dec_","") end, - emit([nl]), - emit({nl,nl}). + emit([nl,nl]). + +result_line(NoOkWrapper, Items) -> + S = [" "|case NoOkWrapper of + false -> result_line_1(["ok"|Items]); + true -> result_line_1(Items) + end], + emit(lists:flatten(S)). + +result_line_1([SingleItem]) -> + SingleItem; +result_line_1(Items) -> + ["{",string:join(Items, ","),"}"]. + +try_catch() -> + [" catch",nl, + " Class:Exception when Class =:= error; Class =:= exit ->",nl, + " case Exception of",nl, + " {error,Reason}=Error ->",nl, + " Error;",nl, + " Reason ->",nl, + " {error,{asn1,Reason}}",nl, + " end",nl, + "end."]. gen_info_functions(Erules) -> emit(["encoding_rule() -> ", diff --git a/lib/asn1/src/asn1ct_gen_ber_bin_v2.erl b/lib/asn1/src/asn1ct_gen_ber_bin_v2.erl index 8ab49aec2c..de81259fcb 100644 --- a/lib/asn1/src/asn1ct_gen_ber_bin_v2.erl +++ b/lib/asn1/src/asn1ct_gen_ber_bin_v2.erl @@ -196,8 +196,16 @@ gen_encode_prim(_Erules, #type{}=D, DoTag, Value) -> emit(["case ",Value," of",nl]), emit_enc_enumerated_cases(NamedNumberList,DoTag); 'REAL' -> - emit([{call,ber,encode_tags, - [DoTag,{call,real_common,ber_encode_real,[Value]}]}]); + asn1ct_name:new(realval), + asn1ct_name:new(realsize), + emit(["begin",nl, + {curr,realval}," = ", + {call,real_common,ber_encode_real,[Value]},com,nl, + {curr,realsize}," = ", + {call,erlang,byte_size,[{curr,realval}]},com,nl, + {call,ber,encode_tags, + [DoTag,{curr,realval},{curr,realsize}]},nl, + "end"]); {'BIT STRING',NamedNumberList} -> call(encode_bit_string, [{asis,BitStringConstraint},Value, @@ -637,9 +645,6 @@ gen_encode_objectfields(ClassName,[{typefield,Name,OptOrMand}|Rest], % ", Val, RestPrimFieldName) ->",nl]), MaybeConstr= case {get_object_field(Name,ObjectFields),OptOrMand} of - {false,'MANDATORY'} -> %% this case is illegal - exit({error,{asn1,{"missing mandatory field in object", - ObjName}}}); {false,'OPTIONAL'} -> EmitFuncClause("Val"), emit([" {Val,0}"]), @@ -672,9 +677,6 @@ gen_encode_objectfields(ClassName,[{objectfield,Name,_,_,OptOrMand}|Rest], % emit(["'enc_",ObjName,"'(",{asis,Name}, % ", Val,[H|T]) ->",nl]), case {get_object_field(Name,ObjectFields),OptOrMand} of - {false,'MANDATORY'} -> - exit({error,{asn1,{"missing mandatory field in object", - ObjName}}}); {false,'OPTIONAL'} -> EmitFuncClause("_,_"), emit([" exit({error,{'use of missing field in object', ",{asis,Name}, @@ -807,9 +809,6 @@ gen_decode_objectfields(ClassName,[{typefield,Name,OptOrMand}|Rest], % ", Bytes, RestPrimFieldName) ->",nl]), MaybeConstr= case {get_object_field(Name,ObjectFields),OptOrMand} of - {false,'MANDATORY'} -> %% this case is illegal - exit({error,{asn1,{"missing mandatory field in object", - ObjName}}}); {false,'OPTIONAL'} -> EmitFuncClause(" Bytes"), emit([" Bytes"]), @@ -844,9 +843,6 @@ gen_decode_objectfields(ClassName,[{objectfield,Name,_,_,OptOrMand}|Rest], % ", Bytes,[H|T]) ->",nl]), % emit_tlv_format("Bytes"), case {get_object_field(Name,ObjectFields),OptOrMand} of - {false,'MANDATORY'} -> - exit({error,{asn1,{"missing mandatory field in object", - ObjName}}}); {false,'OPTIONAL'} -> EmitFuncClause("_,_"), emit([" exit({error,{'illegal use of missing field in object', ",{asis,Name}, @@ -1072,8 +1068,7 @@ gen_objset_enc(_,_,{unique,undefined},_,_,_,_,_) -> gen_objset_enc(Erules, ObjSetName, UniqueName, [{ObjName,Val,Fields}|T], ClName, ClFields, NthObj,Acc)-> - emit(["'getenc_",ObjSetName,"'(",{asis,UniqueName},",",{asis,Val}, - ") ->",nl]), + emit(["'getenc_",ObjSetName,"'(",{asis,Val},") ->",nl]), CurrMod = get(currmod), {InternalFunc,NewNthObj}= case ObjName of @@ -1095,7 +1090,7 @@ gen_objset_enc(Erules, ObjSetName, UniqueName, %% See X.681 Annex E for the following case gen_objset_enc(_,ObjSetName,_UniqueName,['EXTENSIONMARK'],_ClName, _ClFields,_NthObj,Acc) -> - emit({"'getenc_",ObjSetName,"'(_, _) ->",nl}), + emit(["'getenc_",ObjSetName,"'(_) ->",nl]), emit({indent(3),"fun(_, Val, _RestPrimFieldName) ->",nl}), emit({indent(6),"Len = case Val of",nl,indent(9), "Bin when is_binary(Bin) -> byte_size(Bin);",nl,indent(9), @@ -1113,7 +1108,7 @@ emit_ext_fun(EncDec,ModuleName,Name) -> Name,"'(T,V,O) end"]). emit_default_getenc(ObjSetName,UniqueName) -> - emit(["'getenc_",ObjSetName,"'(",{asis,UniqueName},", ErrV) ->",nl]), + emit(["'getenc_",ObjSetName,"'(ErrV) ->",nl]), emit([indent(3),"fun(C,V,_) -> exit({'Type not compatible with table constraint',{component,C},{value,V}, {unique_name_and_value,",{asis,UniqueName},", ErrV}}) end"]). %% gen_inlined_enc_funs for each object iterates over all fields of a @@ -1240,8 +1235,7 @@ gen_objset_dec(_,_,{unique,undefined},_,_,_,_) -> ok; gen_objset_dec(Erules, ObjSName, UniqueName, [{ObjName,Val,Fields}|T], ClName, ClFields, NthObj)-> - emit(["'getdec_",ObjSName,"'(",{asis,UniqueName},",", - {asis,Val},") ->",nl]), + emit(["'getdec_",ObjSName,"'(",{asis,Val},") ->",nl]), CurrMod = get(currmod), NewNthObj= case ObjName of @@ -1262,7 +1256,7 @@ gen_objset_dec(Erules, ObjSName, UniqueName, [{ObjName,Val,Fields}|T], ClFields, NewNthObj); gen_objset_dec(_,ObjSetName,_UniqueName,['EXTENSIONMARK'],_ClName, _ClFields,_NthObj) -> - emit(["'getdec_",ObjSetName,"'(_, _) ->",nl]), + emit(["'getdec_",ObjSetName,"'(_) ->",nl]), emit([indent(2),"fun(_,Bytes, _RestPrimFieldName) ->",nl]), emit([indent(4),"case Bytes of",nl, @@ -1279,7 +1273,7 @@ gen_objset_dec(_, ObjSetName, UniqueName, [], _, _, _) -> ok. emit_default_getdec(ObjSetName,UniqueName) -> - emit(["'getdec_",ObjSetName,"'(",{asis,UniqueName},", ErrV) ->",nl]), + emit(["'getdec_",ObjSetName,"'(ErrV) ->",nl]), emit([indent(2), "fun(C,V,_) -> exit({{component,C},{value,V},{unique_name_and_value,",{asis,UniqueName},", ErrV}}) end"]). gen_inlined_dec_funs(Fields, ClFields, ObjSetName, NthObj) -> diff --git a/lib/asn1/src/asn1ct_gen_per.erl b/lib/asn1/src/asn1ct_gen_per.erl index 69d9d51bf1..8b999ddbf0 100644 --- a/lib/asn1/src/asn1ct_gen_per.erl +++ b/lib/asn1/src/asn1ct_gen_per.erl @@ -26,7 +26,7 @@ %-compile(export_all). -export([gen_dec_imm/2]). --export([gen_dec_prim/3,gen_encode_prim/3]). +-export([gen_dec_prim/3,gen_encode_prim_imm/3]). -export([gen_obj_code/3,gen_objectset_code/2]). -export([gen_decode/2, gen_decode/3]). -export([gen_encode/2, gen_encode/3]). @@ -102,832 +102,106 @@ gen_encode_prim(Erules, D) -> Value = asn1ct_gen:mk_var(asn1ct_name:curr(val)), gen_encode_prim(Erules, D, Value). -gen_encode_prim(Erules, #type{def={'ENUMERATED',{N1,N2}}}, Value) -> - NewList = [{0,X} || {X,_} <- N1] ++ ['EXT_MARK'] ++ - [{1,X} || {X,_} <- N2], - NewC = {0,length(N1)-1}, - emit(["case ",Value," of",nl]), - emit_enc_enumerated_cases(Erules, NewC, NewList, 0); -gen_encode_prim(Erules, #type{def={'ENUMERATED',NNL}}, Value) -> - NewList = [X || {X,_} <- NNL], - NewC = {0,length(NewList)-1}, - emit(["case ",Value," of",nl]), - emit_enc_enumerated_cases(Erules, NewC, NewList, 0); -gen_encode_prim(per=Erules, D, Value) -> - asn1ct_gen_per_rt2ct:gen_encode_prim(Erules, D, Value); gen_encode_prim(Erules, #type{}=D, Value) -> - Constraint = D#type.constraint, - SizeConstr = asn1ct_imm:effective_constraint(bitstring, Constraint), - Pa = case lists:keyfind('PermittedAlphabet', 1, Constraint) of - false -> no; - {_,Pa0} -> Pa0 - end, - case D#type.def of + Aligned = case Erules of + uper -> false; + per -> true + end, + Imm = gen_encode_prim_imm(Value, D, Aligned), + asn1ct_imm:enc_cg(Imm, Aligned). + +gen_encode_prim_imm(Val, #type{def=Type0,constraint=Constraint}, Aligned) -> + case simplify_type(Type0) of + k_m_string -> + Type = case Type0 of + 'GeneralizedTime' -> 'VisibleString'; + 'UTCTime' -> 'VisibleString'; + _ -> Type0 + end, + asn1ct_imm:per_enc_k_m_string(Val, Type, Constraint, Aligned); + restricted_string -> + ToBinary = {erlang,iolist_to_binary}, + asn1ct_imm:per_enc_restricted_string(Val, ToBinary, Aligned); + {'ENUMERATED',NNL} -> + asn1ct_imm:per_enc_enumerated(Val, NNL, Aligned); 'INTEGER' -> - Args = [{asis,asn1ct_imm:effective_constraint(integer,Constraint)}, - Value], - call(Erules, encode_integer, Args); - {'INTEGER',NamedNumberList} -> - Args = [{asis,asn1ct_imm:effective_constraint(integer,Constraint)}, - Value,{asis,NamedNumberList}], - call(Erules, encode_integer, Args); + asn1ct_imm:per_enc_integer(Val, Constraint, Aligned); + {'INTEGER',NNL} -> + asn1ct_imm:per_enc_integer(Val, NNL, Constraint, Aligned); 'REAL' -> - emit_enc_real(Erules, Value); - - {'BIT STRING',NamedNumberList} -> - call(Erules, encode_bit_string, - [{asis,SizeConstr},Value, - {asis,NamedNumberList}]); + ToBinary = {real_common,encode_real}, + asn1ct_imm:per_enc_restricted_string(Val, ToBinary, Aligned); + {'BIT STRING',NNL} -> + asn1ct_imm:per_enc_bit_string(Val, NNL, Constraint, Aligned); 'NULL' -> - emit("[]"); + asn1ct_imm:per_enc_null(Val, Aligned); 'OBJECT IDENTIFIER' -> - call(Erules, encode_object_identifier, [Value]); + ToBinary = {per_common,encode_oid}, + asn1ct_imm:per_enc_restricted_string(Val, ToBinary, Aligned); 'RELATIVE-OID' -> - call(Erules, encode_relative_oid, [Value]); - 'ObjectDescriptor' -> - call(Erules, encode_ObjectDescriptor, - [{asis,Constraint},Value]); + ToBinary = {per_common,encode_relative_oid}, + asn1ct_imm:per_enc_restricted_string(Val, ToBinary, Aligned); 'BOOLEAN' -> - call(Erules, encode_boolean, [Value]); + asn1ct_imm:per_enc_boolean(Val, Aligned); 'OCTET STRING' -> - case SizeConstr of - 0 -> - emit("[]"); - no -> - call(Erules, encode_octet_string, [Value]); - C -> - call(Erules, encode_octet_string, [{asis,C},Value]) - end; - 'NumericString' -> - call(Erules, encode_NumericString, [{asis,SizeConstr}, - {asis,Pa},Value]); - TString when TString == 'TeletexString'; - TString == 'T61String' -> - call(Erules, encode_TeletexString, [{asis,Constraint},Value]); - 'VideotexString' -> - call(Erules, encode_VideotexString, [{asis,Constraint},Value]); - 'UTCTime' -> - call(Erules, encode_VisibleString, [{asis,SizeConstr}, - {asis,Pa},Value]); - 'GeneralizedTime' -> - call(Erules, encode_VisibleString, [{asis,SizeConstr}, - {asis,Pa},Value]); - 'GraphicString' -> - call(Erules, encode_GraphicString, [{asis,Constraint},Value]); - 'VisibleString' -> - call(Erules, encode_VisibleString, [{asis,SizeConstr}, - {asis,Pa},Value]); - 'GeneralString' -> - call(Erules, encode_GeneralString, [{asis,Constraint},Value]); - 'PrintableString' -> - call(Erules, encode_PrintableString, [{asis,SizeConstr}, - {asis,Pa},Value]); - 'IA5String' -> - call(Erules, encode_IA5String, [{asis,SizeConstr}, - {asis,Pa},Value]); - 'BMPString' -> - call(Erules, encode_BMPString, [{asis,SizeConstr}, - {asis,Pa},Value]); - 'UniversalString' -> - call(Erules, encode_UniversalString, [{asis,SizeConstr}, - {asis,Pa},Value]); - 'UTF8String' -> - call(Erules, encode_UTF8String, [Value]); + asn1ct_imm:per_enc_octet_string(Val, Constraint, Aligned); 'ASN1_OPEN_TYPE' -> - NewValue = case Constraint of - [#'Externaltypereference'{type=Tname}] -> - asn1ct_func:need({Erules,complete,1}), - io_lib:format( - "complete(enc_~s(~s))",[Tname,Value]); - [#type{def=#'Externaltypereference'{type=Tname}}] -> - asn1ct_func:need({Erules,complete,1}), - io_lib:format( - "complete(enc_~s(~s))", - [Tname,Value]); - _ -> - io_lib:format("iolist_to_binary(~s)", - [Value]) - end, - call(Erules, encode_open_type, [NewValue]) - end. - -emit_enc_real(Erules, Real) -> - asn1ct_name:new(tmpval), - asn1ct_name:new(tmplen), - emit(["begin",nl, - "{",{curr,tmpval},com,{curr,tmplen},"} = ", - {call,real_common,encode_real,[Real]},com,nl, - "[",{call,Erules,encode_length,[{curr,tmplen}]},",", - {curr,tmpval},"]",nl, - "end"]). - -emit_enc_enumerated_cases(Erules, C, ['EXT_MARK'|T], _Count) -> - %% Reset enumeration counter. - emit_enc_enumerated_cases(Erules, C, T, 0); -emit_enc_enumerated_cases(Erules, C, [H|T], Count) -> - emit_enc_enumerated_case(Erules, C, H, Count), - emit([";",nl]), - emit_enc_enumerated_cases(Erules, C, T, Count+1); -emit_enc_enumerated_cases(_Erules, _, [], _Count) -> - emit(["EnumVal -> " - "exit({error,{asn1,{enumerated_not_in_range, EnumVal}}})",nl, - "end"]). - -emit_enc_enumerated_case(Erules, C, {0,EnumName}, Count) -> - %% ENUMERATED with extensionmark; the value lies within then extension root - Enc = enc_ext_and_val(Erules, 0, encode_constrained_number, [C,Count]), - emit(["'",EnumName,"' -> ",{asis,Enc}]); -emit_enc_enumerated_case(Erules, _C, {1,EnumName}, Count) -> - %% ENUMERATED with extensionmark; the value is higher than extension root - Enc = enc_ext_and_val(Erules, 1, encode_small_number, [Count]), - emit(["'",EnumName,"' -> ",{asis,Enc}]); -emit_enc_enumerated_case(Erules, C, EnumName, Count) -> - %% ENUMERATED without extension - EvalMod = eval_module(Erules), - emit(["'",EnumName,"' -> ", - {asis,EvalMod:encode_constrained_number(C, Count)}]). - -enc_ext_and_val(per, E, F, Args) -> - [E|apply(asn1ct_eval_per, F, Args)]; -enc_ext_and_val(uper, E, F, Args) -> - Bs = list_to_bitstring([apply(asn1ct_eval_uper, F, Args)]), - <<E:1,Bs/bitstring>>. - - -%% Object code generating for encoding and decoding -%% ------------------------------------------------ - -gen_obj_code(Erules,_Module,Obj) when is_record(Obj,typedef) -> - ObjName = Obj#typedef.name, - Def = Obj#typedef.typespec, - #'Externaltypereference'{module=Mod,type=ClassName} = - Def#'Object'.classname, - Class = asn1_db:dbget(Mod,ClassName), - {object,_,Fields} = Def#'Object'.def, - emit({nl,nl,nl,"%%================================"}), - emit({nl,"%% ",ObjName}), - emit({nl,"%%================================",nl}), - EncConstructed = - gen_encode_objectfields(Erules, ClassName,get_class_fields(Class), - ObjName,Fields,[]), - emit(nl), - gen_encode_constr_type(Erules,EncConstructed), - emit(nl), - DecConstructed = - gen_decode_objectfields(Erules, ClassName, get_class_fields(Class), - ObjName, Fields, []), - emit(nl), - gen_decode_constr_type(Erules,DecConstructed), - emit(nl). - - -gen_encode_objectfields(Erule, ClassName, - [{typefield,Name,OptOrMand}|Rest], - ObjName, ObjectFields, ConstrAcc) -> - EmitFuncClause = - fun(V) -> - emit(["'enc_",ObjName,"'(",{asis,Name}, - ",",V,",_RestPrimFieldName) ->",nl]) - end, -% emit(["'enc_",ObjName,"'(",{asis,Name}, -% ", Val, _RestPrimFieldName) ->",nl]), - MaybeConstr = - case {get_object_field(Name,ObjectFields),OptOrMand} of - {false,'MANDATORY'} -> %% this case is illegal - exit({error,{asn1,{"missing mandatory field in object", - ObjName}}}); - {false,'OPTIONAL'} -> - EmitFuncClause("Val"), - case Erule of - uper -> - emit(" Val"); - per -> - emit([" if",nl, - " is_list(Val) ->",nl, - " NewVal = list_to_binary(Val),",nl, - " [20,byte_size(NewVal),NewVal];",nl, - " is_binary(Val) ->",nl, - " [20,byte_size(Val),Val]",nl, - " end"]) - end, - []; - {false,{'DEFAULT',DefaultType}} -> - EmitFuncClause("Val"), - gen_encode_default_call(Erule, ClassName, Name, DefaultType); - {{Name,TypeSpec},_} -> - %% A specified field owerwrites any 'DEFAULT' or - %% 'OPTIONAL' field in the class - EmitFuncClause("Val"), - gen_encode_field_call(Erule, ObjName, Name, TypeSpec) - end, - case more_genfields(Rest) of - true -> - emit([";",nl]); - false -> - emit([".",nl]) - end, - gen_encode_objectfields(Erule,ClassName,Rest,ObjName,ObjectFields, - MaybeConstr++ConstrAcc); -gen_encode_objectfields(Erule,ClassName,[{objectfield,Name,_,_,OptOrMand}|Rest], - ObjName,ObjectFields,ConstrAcc) -> - CurrentMod = get(currmod), - EmitFuncClause = - fun(Attrs) -> - emit(["'enc_",ObjName,"'(",{asis,Name}, - ",",Attrs,") ->",nl]) - end, -% emit(["'enc_",ObjName,"'(",{asis,Name}, -% ", Val,[H|T]) ->",nl]), - case {get_object_field(Name,ObjectFields),OptOrMand} of - {false,'MANDATORY'} -> - exit({error,{asn1,{"missing mandatory field in object", - ObjName}}}); - {false,'OPTIONAL'} -> - EmitFuncClause("_,_"), - emit([" exit({error,{'use of missing field in object', ",{asis,Name}, - "}})"]); - {false,{'DEFAULT',_DefaultObject}} -> - exit({error,{asn1,{"not implemented yet",Name}}}); - {{Name,#'Externalvaluereference'{module=CurrentMod, - value=TypeName}},_} -> - EmitFuncClause(" Val, [H|T]"), - emit({indent(3),"'enc_",TypeName,"'(H, Val, T)"}); - {{Name,#'Externalvaluereference'{module=M,value=TypeName}},_} -> - EmitFuncClause(" Val, [H|T]"), - emit({indent(3),"'",M,"':'enc_",TypeName,"'(H, Val, T)"}); - {{Name,TypeSpec},_} -> - EmitFuncClause("Val,[H|T]"), - case TypeSpec#typedef.name of - {ExtMod,TypeName} -> - emit({indent(3),"'",ExtMod,"':'enc_",TypeName, - "'(H, Val, T)"}); - TypeName -> - emit({indent(3),"'enc_",TypeName,"'(H, Val, T)"}) + case Constraint of + [#'Externaltypereference'{type=Tname}] -> + EncFunc = enc_func(Tname), + Imm = [{apply,EncFunc,[{expr,Val}]}], + asn1ct_imm:per_enc_open_type(Imm, Aligned); + [] -> + Imm = [{call,erlang,iolist_to_binary,[{expr,Val}]}], + asn1ct_imm:per_enc_open_type(Imm, Aligned) end - end, - case more_genfields(Rest) of - true -> - emit([";",nl]); - false -> - emit([".",nl]) - end, - gen_encode_objectfields(Erule,ClassName,Rest,ObjName,ObjectFields,ConstrAcc); -gen_encode_objectfields(Erule,ClassName,[_C|Cs],O,OF,Acc) -> - gen_encode_objectfields(Erule,ClassName,Cs,O,OF,Acc); -gen_encode_objectfields(_, _,[],_,_,Acc) -> - Acc. - - -gen_encode_constr_type(Erules,[TypeDef|Rest]) when is_record(TypeDef,typedef) -> - case is_already_generated(enc,TypeDef#typedef.name) of - true -> ok; - _ -> -%% FuncName = list_to_atom(lists:concat(["enc_",TypeDef#typedef.name])), - FuncName = asn1ct_gen:list2rname(TypeDef#typedef.name ++ [enc]), - emit(["'",FuncName,"'(Val) ->",nl]), - Def = TypeDef#typedef.typespec, - InnerType = asn1ct_gen:get_inner(Def#type.def), - asn1ct_gen:gen_encode_constructed(Erules,TypeDef#typedef.name, - InnerType,Def), - gen_encode_constr_type(Erules,Rest) - end; -gen_encode_constr_type(_,[]) -> - ok. - -gen_encode_field_call(_Erules, _ObjName, _FieldName, - #'Externaltypereference'{module=M,type=T}) -> - CurrentMod = get(currmod), - if - M == CurrentMod -> - emit({" 'enc_",T,"'(Val)"}), - []; - true -> - emit({" '",M,"':'enc_",T,"'(Val)"}), - [] - end; -gen_encode_field_call(Erules, ObjName, FieldName, Type) -> - Def = Type#typedef.typespec, - case Type#typedef.name of - {primitive,bif} -> - gen_encode_prim(Erules, Def, "Val"), - []; - {constructed,bif} -> - emit({" 'enc_",ObjName,'_',FieldName, - "'(Val)"}), -%% [Type#typedef{name=list_to_atom(lists:concat([ObjName,'_',FieldName]))}]; - [Type#typedef{name=[FieldName,ObjName]}]; - {ExtMod,TypeName} -> - emit({" '",ExtMod,"':'enc_",TypeName, - "'(Val)"}), - []; - TypeName -> - emit({" 'enc_",TypeName,"'(Val)"}), - [] end. -gen_encode_default_call(Erules, ClassName, FieldName, Type) -> - CurrentMod = get(currmod), - InnerType = asn1ct_gen:get_inner(Type#type.def), - case asn1ct_gen:type(InnerType) of - {constructed,bif} -> -%% asn1ct_gen:gen_encode_constructed(Erules,Typename,InnerType,Type); - emit([" 'enc_",ClassName,'_',FieldName,"'(Val)"]), -%% [#typedef{name=list_to_atom(lists:concat([ClassName,'_',FieldName])), - [#typedef{name=[FieldName,ClassName], - typespec=Type}]; - {primitive,bif} -> - gen_encode_prim(Erules, Type, "Val"), - []; - #'Externaltypereference'{module=CurrentMod,type=Etype} -> - emit([" 'enc_",Etype,"'(Val)",nl]), - []; - #'Externaltypereference'{module=Emod,type=Etype} -> - emit([" '",Emod,"':'enc_",Etype,"'(Val)",nl]), - [] - end. - - -gen_decode_objectfields(Erules, ClassName, - [{typefield,Name,OptOrMand}|Rest], - ObjName, ObjectFields, ConstrAcc) -> - EmitFuncClause = - fun(Bytes) -> - emit(["'dec_",ObjName,"'(",{asis,Name},",",Bytes, - ",_,_RestPrimFieldName) ->",nl]) - end, - MaybeConstr= - case {get_object_field(Name,ObjectFields),OptOrMand} of - {false,'MANDATORY'} -> %% this case is illegal - exit({error,{asn1,{"missing mandatory field in object", - ObjName}}}); - {false,'OPTIONAL'} -> - EmitFuncClause("Bytes"), - emit([" {Bytes,[]}"]), - []; - {false,{'DEFAULT',DefaultType}} -> - EmitFuncClause("Bytes"), - gen_decode_default_call(Erules, ClassName, Name, "Bytes", - DefaultType); - {{Name,TypeSpec},_} -> - %% A specified field owerwrites any 'DEFAULT' or - %% 'OPTIONAL' field in the class - EmitFuncClause("Bytes"), - gen_decode_field_call(Erules, ObjName, Name, "Bytes", TypeSpec) - end, - case more_genfields(Rest) of - true -> - emit([";",nl]); - false -> - emit([".",nl]) - end, - gen_decode_objectfields(Erules, ClassName, Rest, ObjName, - ObjectFields, MaybeConstr++ConstrAcc); -gen_decode_objectfields(Erules, ClassName, - [{objectfield,Name,_,_,OptOrMand}|Rest], - ObjName, ObjectFields, ConstrAcc) -> - CurrentMod = get(currmod), - EmitFuncClause = - fun(Attrs) -> - emit(["'dec_",ObjName,"'(",{asis,Name}, - ",",Attrs,") ->",nl]) - end, -% emit(["'dec_",ObjName,"'(",{asis,Name}, -% ", Bytes,_,[H|T]) ->",nl]), - case {get_object_field(Name,ObjectFields),OptOrMand} of - {false,'MANDATORY'} -> - exit({error,{asn1,{"missing mandatory field in object", - ObjName}}}); - {false,'OPTIONAL'} -> - EmitFuncClause("_,_,_"), - emit([" exit({error,{'illegal use of missing field in object', ",{asis,Name}, - "}})"]); - {false,{'DEFAULT',_DefaultObject}} -> - exit({error,{asn1,{"not implemented yet",Name}}}); - {{Name,#'Externalvaluereference'{module=CurrentMod, - value=TypeName}},_} -> - EmitFuncClause("Bytes,_,[H|T]"), - emit({indent(3),"'dec_",TypeName,"'(H, Bytes, telltype, T)"}); - {{Name,#'Externalvaluereference'{module=M,value=TypeName}},_} -> - EmitFuncClause("Bytes,_,[H|T]"), - emit({indent(3),"'",M,"':'dec_",TypeName, - "'(H, Bytes, telltype, T)"}); - {{Name,TypeSpec},_} -> - EmitFuncClause("Bytes,_,[H|T]"), - case TypeSpec#typedef.name of - {ExtMod,TypeName} -> - emit({indent(3),"'",ExtMod,"':'dec_",TypeName, - "'(H, Bytes, telltype, T)"}); - TypeName -> - emit({indent(3),"'dec_",TypeName,"'(H, Bytes, telltype, T)"}) - end - end, - case more_genfields(Rest) of - true -> - emit([";",nl]); - false -> - emit([".",nl]) - end, - gen_decode_objectfields(Erules, ClassName, Rest, ObjName, - ObjectFields, ConstrAcc); -gen_decode_objectfields(Erules, CN, [_C|Cs], O, OF, CAcc) -> - gen_decode_objectfields(Erules, CN, Cs, O, OF, CAcc); -gen_decode_objectfields(_, _, [], _, _, CAcc) -> - CAcc. - - - -gen_decode_field_call(_Erules, _ObjName, _FieldName, Bytes, - #'Externaltypereference'{}=Etype) -> - emit(" "), - gen_dec_external(Etype, Bytes), - []; -gen_decode_field_call(Erules, ObjName, FieldName, Bytes, Type) -> - Def = Type#typedef.typespec, - case Type#typedef.name of - {primitive,bif} -> - gen_dec_prim(Erules, Def, Bytes), - []; - {constructed,bif} -> - emit({" 'dec_",ObjName,'_',FieldName, - "'(",Bytes,",telltype)"}), -%% [Type#typedef{name=list_to_atom(lists:concat([ObjName,'_',FieldName]))}]; - [Type#typedef{name=[FieldName,ObjName]}]; - {ExtMod,TypeName} -> - emit({" '",ExtMod,"':'dec_",TypeName, - "'(",Bytes,", telltype)"}), - []; - TypeName -> - emit({" 'dec_",TypeName,"'(",Bytes,", telltype)"}), - [] - end. - -gen_decode_default_call(Erules, ClassName, FieldName, Bytes, Type) -> - InnerType = asn1ct_gen:get_inner(Type#type.def), - case asn1ct_gen:type(InnerType) of - {constructed,bif} -> - emit([" 'dec_",ClassName,'_',FieldName,"'(",Bytes,", telltype)"]), -%% [#typedef{name=list_to_atom(lists:concat([ClassName,'_',FieldName])), - [#typedef{name=[FieldName,ClassName], - typespec=Type}]; - {primitive,bif} -> - gen_dec_prim(Erules, Type, Bytes), - []; - #'Externaltypereference'{}=Etype -> - asn1ct_gen_per:gen_dec_external(Etype, Bytes), - [] +dec_func(Tname) -> + list_to_atom(lists:concat(["dec_",Tname])). + +enc_func(Tname) -> + list_to_atom(lists:concat(["enc_",Tname])). + +simplify_type(Type) -> + case Type of + 'BMPString' -> k_m_string; + 'IA5String' -> k_m_string; + 'NumericString' -> k_m_string; + 'PrintableString' -> k_m_string; + 'VisibleString' -> k_m_string; + 'UniversalString' -> k_m_string; + 'GeneralizedTime' -> k_m_string; + 'UTCTime' -> k_m_string; + 'TeletexString' -> restricted_string; + 'T61String' -> restricted_string; + 'VideotexString' -> restricted_string; + 'GraphicString' -> restricted_string; + 'GeneralString' -> restricted_string; + 'UTF8String' -> restricted_string; + 'ObjectDescriptor' -> restricted_string; + Other -> Other end. +%% Object code generating for encoding and decoding +%% ------------------------------------------------ -gen_decode_constr_type(Erules,[TypeDef|Rest]) when is_record(TypeDef,typedef) -> - case is_already_generated(dec,TypeDef#typedef.name) of - true -> ok; - _ -> - gen_decode(Erules,TypeDef#typedef{name=asn1ct_gen:list2rname(TypeDef#typedef.name)}) - end, - gen_decode_constr_type(Erules,Rest); -gen_decode_constr_type(_,[]) -> +gen_obj_code(_Erules, _Module, #typedef{}) -> ok. - -more_genfields([]) -> - false; -more_genfields([Field|Fields]) -> - case element(1,Field) of - typefield -> - true; - objectfield -> - true; - _ -> - more_genfields(Fields) - end. - %% Object Set code generating for encoding and decoding %% ---------------------------------------------------- -gen_objectset_code(Erules,ObjSet) -> - ObjSetName = ObjSet#typedef.name, - Def = ObjSet#typedef.typespec, -%% {ClassName,ClassDef} = Def#'ObjectSet'.class, - #'Externaltypereference'{module=ClassModule, - type=ClassName} = Def#'ObjectSet'.class, - ClassDef = asn1_db:dbget(ClassModule,ClassName), - UniqueFName = Def#'ObjectSet'.uniquefname, - Set = Def#'ObjectSet'.set, - emit({nl,nl,nl,"%%================================"}), - emit({nl,"%% ",ObjSetName}), - emit({nl,"%%================================",nl}), - case ClassName of - {_Module,ExtClassName} -> - gen_objset_code(Erules,ObjSetName,UniqueFName,Set, - ExtClassName,ClassDef); - _ -> - gen_objset_code(Erules,ObjSetName,UniqueFName,Set, - ClassName,ClassDef) - end, - emit(nl). - -gen_objset_code(Erules,ObjSetName,UniqueFName,Set,ClassName,ClassDef)-> - ClassFields = (ClassDef#classdef.typespec)#objectclass.fields, - InternalFuncs= - gen_objset_enc(Erules,ObjSetName,UniqueFName,Set,ClassName,ClassFields,1,[]), - gen_objset_dec(Erules, ObjSetName,UniqueFName,Set,ClassName,ClassFields,1), - gen_internal_funcs(Erules,InternalFuncs). - -%% gen_objset_enc iterates over the objects of the object set -gen_objset_enc(_,_,{unique,undefined},_,_,_,_,_) -> - %% There is no unique field in the class of this object set - %% don't bother about the constraint - []; -gen_objset_enc(Erule, ObjSetName, UniqueName, [{ObjName,Val,Fields}|T], - ClName, ClFields, NthObj, Acc)-> - emit(["'getenc_",ObjSetName,"'(",{asis,UniqueName},",",{asis,Val}, - ") ->",nl]), - CurrMod = get(currmod), - {InternalFunc,NewNthObj}= - case ObjName of - {no_mod,no_name} -> - gen_inlined_enc_funs(Erule, Fields, ClFields, - ObjSetName, NthObj); - {CurrMod,Name} -> - emit({" fun 'enc_",Name,"'/3"}), - {[],0}; - {ModName,Name} -> - emit_ext_encfun(ModName,Name), - {[],0}; - _Other -> - emit({" fun 'enc_",ObjName,"'/3"}), - {[],0} - end, - emit({";",nl}), - gen_objset_enc(Erule, ObjSetName, UniqueName, T, ClName, ClFields, - NewNthObj, InternalFunc ++ Acc); -gen_objset_enc(uper, ObjSetName, _UniqueName, ['EXTENSIONMARK'], - _ClName, _ClFields, _NthObj, Acc) -> - emit({"'getenc_",ObjSetName,"'(_, _) ->",nl}), - emit({indent(3),"fun(_, Val, _) ->",nl}), - emit([indent(6),"Val",nl, - indent(3),"end.",nl,nl]), - Acc; -gen_objset_enc(per, ObjSetName, _UniqueName, ['EXTENSIONMARK'], - _ClName, _ClFields, _NthObj, Acc) -> - emit(["'getenc_",ObjSetName,"'(_, _) ->",nl, - indent(3),"fun(_, Val, _) ->",nl, - indent(6),"BinVal = if",nl, - indent(9),"is_list(Val) -> list_to_binary(Val);",nl, - indent(9),"true -> Val",nl, - indent(6),"end,",nl, - indent(6),"Size = byte_size(BinVal),",nl, - indent(6),"if",nl, - indent(9),"Size < 256 ->",nl, - indent(12),"[20,Size,BinVal];",nl, - indent(9),"true ->",nl, - indent(12),"[21,<<Size:16>>,Val]",nl, - indent(6),"end",nl, - indent(3),"end.",nl,nl]), - Acc; -gen_objset_enc(_, ObjSetName, UniqueName, [], _, _, _, Acc) -> - emit_default_getenc(ObjSetName, UniqueName), - emit([".",nl,nl]), - Acc. - -emit_ext_encfun(ModuleName,Name) -> - emit([indent(4),"fun(T,V,O) -> '",ModuleName,"':'enc_", - Name,"'(T,V,O) end"]). - -emit_default_getenc(ObjSetName,UniqueName) -> - emit(["'getenc_",ObjSetName,"'(",{asis,UniqueName},", ErrV) ->",nl]), - emit([indent(4),"fun(C,V,_) -> exit({'Type not compatible with table constraint',{component,C},{value,V},{unique_name_and_value,",{asis,UniqueName},",ErrV}}) end"]). - - -%% gen_inlined_enc_funs for each object iterates over all fields of a -%% class, and for each typefield it checks if the object has that -%% field and emits the proper code. -gen_inlined_enc_funs(Erule, Fields, [{typefield,_,_}|_]=T, - ObjSetName, NthObj) -> - emit([indent(3),"fun(Type, Val, _) ->",nl, - indent(6),"case Type of",nl]), - gen_inlined_enc_funs1(Erule, Fields, T, ObjSetName, [], NthObj, []); -gen_inlined_enc_funs(Erule,Fields,[_H|Rest],ObjSetName,NthObj) -> - gen_inlined_enc_funs(Erule,Fields,Rest,ObjSetName,NthObj); -gen_inlined_enc_funs(_,_,[],_,NthObj) -> - {[],NthObj}. - -gen_inlined_enc_funs1(Erule, Fields, [{typefield,Name,_}|Rest], ObjSetName, - Sep0, NthObj, Acc0) -> - emit(Sep0), - Sep = [";",nl], - CurrentMod = get(currmod), - InternalDefFunName = asn1ct_gen:list2name([NthObj,Name,ObjSetName]), - {Acc,NAdd} = - case lists:keyfind(Name, 1, Fields) of - {_,#type{}=Type} -> - {Ret,N} = emit_inner_of_fun(Erule, Type, InternalDefFunName), - {Ret++Acc0,N}; - {_,#typedef{}=Type} -> - emit([indent(9),{asis,Name}," ->",nl]), - {Ret,N} = emit_inner_of_fun(Erule, Type, InternalDefFunName), - {Ret++Acc0,N}; - {_,#'Externaltypereference'{module=CurrentMod,type=T}} -> - emit([indent(9),{asis,Name}," ->",nl, - indent(12),"'enc_",T,"'(Val)"]), - {Acc0,0}; - {_,#'Externaltypereference'{module=M,type=T}} -> - emit([indent(9),{asis,Name}," ->",nl, - indent(12),"'",M,"'",":'enc_",T,"'(Val)"]), - {Acc0,0}; - false when Erule =:= uper -> - emit([indent(9),{asis,Name}," ->",nl, - indent(12),"Val",nl]), - {Acc0,0}; - false when Erule =:= per -> - emit([indent(9),{asis,Name}," ->",nl, - indent(12),"Size = case Val of",nl, - indent(15),"B when is_binary(B) -> size(B);",nl, - indent(15),"_ -> length(Val)",nl, - indent(12),"end,",nl, - indent(12),"if",nl, - indent(15),"Size < 256 -> [20,Size,Val];",nl, - indent(15),"true -> [21,<<Size:16>>,Val]",nl, - indent(12),"end"]), - {Acc0,0} - end, - gen_inlined_enc_funs1(Erule, Fields, Rest, ObjSetName, Sep, - NthObj+NAdd, Acc); -gen_inlined_enc_funs1(Erule, Fields, [_|T], ObjSetName, Sep, NthObj, Acc)-> - gen_inlined_enc_funs1(Erule, Fields, T, ObjSetName, Sep, NthObj, Acc); -gen_inlined_enc_funs1(_, _, [], _, _, NthObj, Acc) -> - emit([nl,indent(6),"end",nl, - indent(3),"end"]), - {Acc,NthObj}. - -emit_inner_of_fun(Erule, #typedef{name={ExtMod,Name},typespec=Type}=TDef, - InternalDefFunName) -> - case {ExtMod,Name} of - {primitive,bif} -> - emit(indent(12)), - gen_encode_prim(Erule, Type, "Val"), - {[],0}; - {constructed,bif} -> - emit([indent(12),"'enc_", - InternalDefFunName,"'(Val)"]), - {[TDef#typedef{name=InternalDefFunName}],1}; - _ -> - emit({indent(12),"'",ExtMod,"':'enc_",Name,"'(Val)"}), - {[],0} - end; -emit_inner_of_fun(_Erule, #typedef{name=Name}, _) -> - emit({indent(12),"'enc_",Name,"'(Val)"}), - {[],0}; -emit_inner_of_fun(Erule, #type{}=Type, _) -> - CurrMod = get(currmod), - case Type#type.def of - Def when is_atom(Def) -> - emit({indent(9),Def," ->",nl,indent(12)}), - gen_encode_prim(Erule, Type, "Val"); - #'Externaltypereference'{module=CurrMod,type=T} -> - emit({indent(9),T," ->",nl,indent(12),"'enc_",T,"'(Val)"}); - #'Externaltypereference'{module=ExtMod,type=T} -> - emit({indent(9),T," ->",nl,indent(12),ExtMod,":'enc_", - T,"'(Val)"}) - end, - {[],0}. - -indent(N) -> - lists:duplicate(N,32). % 32 = space - - -gen_objset_dec(_, _, {unique,undefined}, _, _, _, _) -> - %% There is no unique field in the class of this object set - %% don't bother about the constraint - ok; -gen_objset_dec(Erule, ObjSName, UniqueName, [{ObjName,Val,Fields}|T], ClName, - ClFields, NthObj)-> - emit({"'getdec_",ObjSName,"'(",{asis,UniqueName},",",{asis,Val}, - ") ->",nl}), - CurrMod = get(currmod), - NewNthObj= - case ObjName of - {no_mod,no_name} -> - gen_inlined_dec_funs(Erule, Fields, ClFields, - ObjSName, NthObj); - {CurrMod,Name} -> - emit([" fun 'dec_",Name,"'/4"]), - NthObj; - {ModName,Name} -> - emit_ext_decfun(ModName,Name), - NthObj; - _Other -> - emit({" fun 'dec_",ObjName,"'/4"}), - NthObj - end, - emit({";",nl}), - gen_objset_dec(Erule, ObjSName, UniqueName, T, ClName, ClFields, NewNthObj); -gen_objset_dec(_Erule, ObjSetName, _UniqueName, ['EXTENSIONMARK'], - _ClName, _ClFields, _NthObj) -> - emit({"'getdec_",ObjSetName,"'(_, _) ->",nl}), - emit({indent(3),"fun(Attr1, Bytes, _,_) ->",nl}), - emit({indent(6),"{Bytes,Attr1}",nl}), - emit({indent(3),"end.",nl,nl}), - ok; -gen_objset_dec(_Erule, ObjSetName, UniqueName, [], _, _, _) -> - emit_default_getdec(ObjSetName, UniqueName), - emit([".",nl,nl]), +gen_objectset_code(_Erules, _ObjSet) -> ok. -emit_ext_decfun(ModuleName,Name) -> - emit([indent(3),"fun(T,V,O1,O2) -> '",ModuleName,"':'dec_", - Name,"'(T,V,O1,O2) end"]). - -emit_default_getdec(ObjSetName,UniqueName) -> - emit(["'getdec_",ObjSetName,"'(",{asis,UniqueName},", ErrV) ->",nl]), - emit([indent(2), "fun(C,V,_,_) -> exit({{component,C},{value,V},{unique_name_and_value,",{asis,UniqueName},",ErrV}}) end"]). - - -gen_inlined_dec_funs(Erule, Fields, List, ObjSetName, NthObj0) -> - emit([indent(3),"fun(Type, Val, _, _) ->",nl, - indent(6),"case Type of",nl]), - NthObj = gen_inlined_dec_funs1(Erule, Fields, List, - ObjSetName, "", NthObj0), - emit([nl,indent(6),"end",nl, - indent(3),"end"]), - NthObj. - -gen_inlined_dec_funs1(Erule, Fields, [{typefield,Name,_}|Rest], - ObjSetName, Sep0, NthObj) -> - InternalDefFunName = [NthObj,Name,ObjSetName], - emit(Sep0), - Sep = [";",nl], - N = case lists:keyfind(Name, 1, Fields) of - {_,#type{}=Type} -> - emit_inner_of_decfun(Erule, Type, InternalDefFunName); - {_,#typedef{}=Type} -> - emit([indent(9),{asis,Name}," ->",nl]), - emit_inner_of_decfun(Erule, Type, InternalDefFunName); - {_,#'Externaltypereference'{}=Etype} -> - emit([indent(9),{asis,Name}," ->",nl, - indent(12)]), - gen_dec_external(Etype, "Val"), - 0; - false -> - emit([indent(9),{asis,Name}," -> {Val,Type}"]), - 0 - end, - gen_inlined_dec_funs1(Erule, Fields, Rest, ObjSetName, Sep, NthObj+N); -gen_inlined_dec_funs1(Erule, Fields, [_|Rest], ObjSetName, Sep, NthObj) -> - gen_inlined_dec_funs1(Erule, Fields, Rest, ObjSetName, Sep, NthObj); -gen_inlined_dec_funs1(_, _, [], _, _, NthObj) -> NthObj. - -emit_inner_of_decfun(Erule, #typedef{name={ExtName,Name},typespec=Type}, - InternalDefFunName) -> - case {ExtName,Name} of - {primitive,bif} -> - emit(indent(12)), - gen_dec_prim(Erule, Type, "Val"), - 0; - {constructed,bif} -> - emit({indent(12),"'dec_", - asn1ct_gen:list2name(InternalDefFunName),"'(Val)"}), - 1; - _ -> - emit({indent(12),"'",ExtName,"':'dec_",Name,"'(Val, telltype)"}), - 0 - end; -emit_inner_of_decfun(_Erule, #typedef{name=Name}, _) -> - emit({indent(12),"'dec_",Name,"'(Val, telltype)"}), - 0; -emit_inner_of_decfun(Erule, #type{}=Type, _) -> - CurrMod = get(currmod), - case Type#type.def of - Def when is_atom(Def) -> - emit({indent(9),Def," ->",nl,indent(12)}), - gen_dec_prim(Erule, Type, "Val"); - #'Externaltypereference'{module=CurrMod,type=T} -> - emit({indent(9),T," ->",nl,indent(12),"'dec_",T,"'(Val)"}); - #'Externaltypereference'{module=ExtMod,type=T} -> - emit({indent(9),T," ->",nl,indent(12),ExtMod,":'dec_", - T,"'(Val)"}) - end, - 0. - - -gen_internal_funcs(_,[]) -> - ok; -gen_internal_funcs(Erules,[TypeDef|Rest]) -> - gen_encode_user(Erules,TypeDef), - emit([nl,nl,"'dec_",TypeDef#typedef.name,"'(Bytes) ->",nl]), - gen_decode_user(Erules,TypeDef), - gen_internal_funcs(Erules,Rest). - - - %% DECODING ***************************** %%*************************************** -gen_decode(Erules,Type) when is_record(Type,typedef) -> - D = Type, - emit({nl,nl}), - emit({"'dec_",Type#typedef.name,"'(Bytes,_) ->",nl}), +gen_decode(Erules, #typedef{}=Type) -> + DecFunc = dec_func(Type#typedef.name), + emit([nl,nl,{asis,DecFunc},"(Bytes) ->",nl]), dbdec(Type#typedef.name), - gen_decode_user(Erules,D). + gen_decode_user(Erules, Type). gen_decode(Erules,Tname,#'ComponentType'{name=Cname,typespec=Type}) -> NewTname = [Cname|Tname], @@ -944,8 +218,9 @@ gen_decode(Erules,Typename,Type) when is_record(Type,type) -> _ -> "" end, - emit({nl,"'dec_",asn1ct_gen:list2name(Typename), - "'(Bytes,_",ObjFun,") ->",nl}), + emit([nl, + {asis,dec_func(asn1ct_gen:list2name(Typename))}, + "(Bytes",ObjFun,") ->",nl]), dbdec(Typename), asn1ct_gen:gen_decode_constructed(Erules,Typename,InnerType,Type); _ -> @@ -982,8 +257,8 @@ gen_dec_external(Ext, BytesVar) -> #'Externaltypereference'{module=Mod,type=Type} = Ext, emit([case CurrMod of Mod -> []; - _ -> ["'",Mod,"':"] - end,"'dec_",Type,"'(",BytesVar,",telltype)"]). + _ -> [{asis,Mod},":"] + end,{asis,dec_func(Type)},"(",BytesVar,")"]). gen_dec_imm(Erule, #type{def=Name,constraint=C}) -> Aligned = case Erule of @@ -1103,35 +378,6 @@ gen_dec_prim(Erule, Type, BytesVar) -> Imm = gen_dec_imm(Erule, Type), asn1ct_imm:dec_code_gen(Imm, BytesVar). -is_already_generated(Operation,Name) -> - case get(class_default_type) of - undefined -> - put(class_default_type,[{Operation,Name}]), - false; - GeneratedList -> - case lists:member({Operation,Name},GeneratedList) of - true -> - true; - false -> - put(class_default_type,[{Operation,Name}|GeneratedList]), - false - end - end. - -get_class_fields(#classdef{typespec=ObjClass}) -> - ObjClass#objectclass.fields; -get_class_fields(#objectclass{fields=Fields}) -> - Fields; -get_class_fields(_) -> - []. - - -get_object_field(Name,ObjectFields) -> - case lists:keysearch(Name,1,ObjectFields) of - {value,Field} -> Field; - false -> false - end. - %% For PER the ExtensionAdditionGroup notation has significance for the encoding and decoding %% the components within the ExtensionAdditionGroup is treated in a similar way as if they @@ -1170,11 +416,8 @@ imm_dec_open_type_1(Type, Aligned) -> asn1ct_name:new(tmpval), emit(["begin",nl, "{",{curr,tmpval},",_} = ", - "dec_",Type,"(",OpenType,", mandatory),",nl, + {asis,dec_func(Type)},"(",OpenType,"),",nl, "{",{curr,tmpval},com,Buf,"}",nl, "end"]) end, {call,D,asn1ct_imm:per_dec_open_type(Aligned)}. - -eval_module(per) -> asn1ct_eval_per; -eval_module(uper) -> asn1ct_eval_uper. diff --git a/lib/asn1/src/asn1ct_gen_per_rt2ct.erl b/lib/asn1/src/asn1ct_gen_per_rt2ct.erl deleted file mode 100644 index 012d54e7a1..0000000000 --- a/lib/asn1/src/asn1ct_gen_per_rt2ct.erl +++ /dev/null @@ -1,461 +0,0 @@ -%% -%% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2002-2013. All Rights Reserved. -%% -%% The contents of this file are subject to the Erlang Public License, -%% Version 1.1, (the "License"); you may not use this file except in -%% compliance with the License. You should have received a copy of the -%% Erlang Public License along with this software. If not, it can be -%% retrieved online at http://www.erlang.org/. -%% -%% Software distributed under the License is distributed on an "AS IS" -%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See -%% the License for the specific language governing rights and limitations -%% under the License. -%% -%% %CopyrightEnd% -%% -%% --module(asn1ct_gen_per_rt2ct). - -%% Handle encoding of primitives for aligned PER. - --include("asn1_records.hrl"). - --export([gen_encode_prim/3]). - --import(asn1ct_gen, [emit/1,demit/1]). --import(asn1ct_func, [call/3]). - -gen_encode_prim(Erules, #type{}=D, Value) -> - Constraint = D#type.constraint, - case D#type.def of - 'INTEGER' -> - EffectiveConstr = effective_constraint(integer,Constraint), - emit([" %%INTEGER with effective constraint: ", - {asis,EffectiveConstr},nl]), - emit_enc_integer(Erules,EffectiveConstr,Value); - {'INTEGER',NamedNumberList} -> - EffectiveConstr = effective_constraint(integer,Constraint), - %% maybe an emit_enc_NNL_integer - emit([" %%INTEGER with effective constraint: ", - {asis,EffectiveConstr},nl]), - emit_enc_integer_NNL(Erules,EffectiveConstr,Value,NamedNumberList); - 'REAL' -> - emit_enc_real(Erules, Value); - - {'BIT STRING',NamedNumberList} -> - EffectiveC = effective_constraint(bitstring,Constraint), - case EffectiveC of - 0 -> - emit({"[]"}); - _ -> - call(Erules, encode_bit_string, - [{asis,EffectiveC},Value, - {asis,NamedNumberList}]) - end; - 'NULL' -> - emit("[]"); - 'OBJECT IDENTIFIER' -> - call(Erules, encode_object_identifier, [Value]); - 'RELATIVE-OID' -> - call(Erules, encode_relative_oid, [Value]); - 'ObjectDescriptor' -> - call(Erules, encode_ObjectDescriptor, - [{asis,Constraint},Value]); - 'BOOLEAN' -> - emit({"case ",Value," of",nl, - " true -> [1];",nl, - " false -> [0];",nl, - " _ -> exit({error,{asn1,{encode_boolean,",Value,"}}})",nl, - "end"}); - 'OCTET STRING' -> - emit_enc_octet_string(Erules,Constraint,Value); - - 'NumericString' -> - emit_enc_known_multiplier_string('NumericString',Constraint,Value); - TString when TString == 'TeletexString'; - TString == 'T61String' -> - call(Erules, encode_TeletexString, [{asis,Constraint},Value]); - 'VideotexString' -> - call(Erules, encode_VideotexString, [{asis,Constraint},Value]); - 'UTCTime' -> - emit_enc_known_multiplier_string('VisibleString',Constraint,Value); - 'GeneralizedTime' -> - emit_enc_known_multiplier_string('VisibleString',Constraint,Value); - 'GraphicString' -> - call(Erules, encode_GraphicString, [{asis,Constraint},Value]); - 'VisibleString' -> - emit_enc_known_multiplier_string('VisibleString',Constraint,Value); - 'GeneralString' -> - call(Erules, encode_GeneralString, [{asis,Constraint},Value]); - 'PrintableString' -> - emit_enc_known_multiplier_string('PrintableString',Constraint,Value); - 'IA5String' -> - emit_enc_known_multiplier_string('IA5String',Constraint,Value); - 'BMPString' -> - emit_enc_known_multiplier_string('BMPString',Constraint,Value); - 'UniversalString' -> - emit_enc_known_multiplier_string('UniversalString',Constraint,Value); - 'UTF8String' -> - call(Erules, encode_UTF8String, [Value]); - 'ASN1_OPEN_TYPE' -> - NewValue = case Constraint of - [#'Externaltypereference'{type=Tname}] -> - asn1ct_func:need({Erules,complete,1}), - io_lib:format( - "complete(enc_~s(~s))",[Tname,Value]); - [#type{def=#'Externaltypereference'{type=Tname}}] -> - asn1ct_func:need({Erules,complete,1}), - io_lib:format( - "complete(enc_~s(~s))", - [Tname,Value]); - _ -> - io_lib:format("iolist_to_binary(~s)", - [Value]) - end, - call(Erules, encode_open_type, [NewValue]) - end. - -emit_enc_real(Erules, Real) -> - asn1ct_name:new(tmpval), - asn1ct_name:new(tmplen), - emit(["begin",nl, - "{",{curr,tmpval},com,{curr,tmplen},"} = ", - {call,real_common,encode_real,[Real]},com,nl, - "[",{call,Erules,encode_length,[{curr,tmplen}]},",",nl, - {call,Erules,octets_to_complete, - [{curr,tmplen},{curr,tmpval}]},"]",nl, - "end"]). - -emit_enc_known_multiplier_string(StringType,C,Value) -> - SizeC = effective_constraint(bitstring, C), - PAlphabC = get_constraint(C,'PermittedAlphabet'), - case {StringType,PAlphabC} of - {'UniversalString',{_,_}} -> - exit({error,{asn1,{'not implemented',"UniversalString with " - "PermittedAlphabet constraint"}}}); - {'BMPString',{_,_}} -> - exit({error,{asn1,{'not implemented',"BMPString with " - "PermittedAlphabet constraint"}}}); - _ -> ok - end, - NumBits = get_NumBits(C,StringType), - CharOutTab = get_CharOutTab(C,StringType), - %% NunBits and CharOutTab for chars_encode - emit_enc_k_m_string(SizeC, NumBits, CharOutTab, Value). - -emit_enc_k_m_string(0, _NumBits, _CharOutTab, _Value) -> - emit({"[]"}); -emit_enc_k_m_string(SizeC, NumBits, CharOutTab, Value) -> - call(per, encode_known_multiplier_string, - [{asis,SizeC},NumBits,{asis,CharOutTab},Value]). - - -%% copied from run time module - -get_CharOutTab(C, StringType) -> - case get_constraint(C,'PermittedAlphabet') of - {'SingleValue',Sv} -> - get_CharTab2(C, StringType, hd(Sv), lists:max(Sv), Sv); - no -> - case StringType of - 'IA5String' -> - {0,16#7F,notab}; - 'VisibleString' -> - get_CharTab2(C, StringType, 16#20, 16#7F, notab); - 'PrintableString' -> - Chars = lists:sort( - " '()+,-./0123456789:=?ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"), - get_CharTab2(C, StringType, hd(Chars), - lists:max(Chars), Chars); - 'NumericString' -> - get_CharTab2(C, StringType, 16#20, $9, " 0123456789"); - 'UniversalString' -> - {0,16#FFFFFFFF,notab}; - 'BMPString' -> - {0,16#FFFF,notab} - end - end. - -get_CharTab2(C, StringType, Min, Max, Chars) -> - BitValMax = (1 bsl get_NumBits(C,StringType))-1, - if - Max =< BitValMax -> - {0,Max,notab}; - true -> - {Min,Max,create_char_tab(Min,Chars)} - end. - -create_char_tab(Min,L) -> - list_to_tuple(create_char_tab(Min,L,0)). -create_char_tab(Min,[Min|T],V) -> - [V|create_char_tab(Min+1,T,V+1)]; -create_char_tab(_Min,[],_V) -> - []; -create_char_tab(Min,L,V) -> - [false|create_char_tab(Min+1,L,V)]. - -get_NumBits(C,StringType) -> - case get_constraint(C,'PermittedAlphabet') of - {'SingleValue',Sv} -> - charbits(length(Sv),aligned); - no -> - case StringType of - 'IA5String' -> - charbits(128,aligned); % 16#00..16#7F - 'VisibleString' -> - charbits(95,aligned); % 16#20..16#7E - 'PrintableString' -> - charbits(74,aligned); % [$\s,$',$(,$),$+,$,,$-,$.,$/,"0123456789",$:,$=,$?,$A..$Z,$a..$z - 'NumericString' -> - charbits(11,aligned); % $ ,"0123456789" - 'UniversalString' -> - 32; - 'BMPString' -> - 16 - end - end. - -charbits(NumOfChars,aligned) -> - case charbits(NumOfChars) of - 1 -> 1; - 2 -> 2; - B when B =< 4 -> 4; - B when B =< 8 -> 8; - B when B =< 16 -> 16; - B when B =< 32 -> 32 - end. - -charbits(NumOfChars) when NumOfChars =< 2 -> 1; -charbits(NumOfChars) when NumOfChars =< 4 -> 2; -charbits(NumOfChars) when NumOfChars =< 8 -> 3; -charbits(NumOfChars) when NumOfChars =< 16 -> 4; -charbits(NumOfChars) when NumOfChars =< 32 -> 5; -charbits(NumOfChars) when NumOfChars =< 64 -> 6; -charbits(NumOfChars) when NumOfChars =< 128 -> 7; -charbits(NumOfChars) when NumOfChars =< 256 -> 8; -charbits(NumOfChars) when NumOfChars =< 512 -> 9; -charbits(NumOfChars) when NumOfChars =< 1024 -> 10; -charbits(NumOfChars) when NumOfChars =< 2048 -> 11; -charbits(NumOfChars) when NumOfChars =< 4096 -> 12; -charbits(NumOfChars) when NumOfChars =< 8192 -> 13; -charbits(NumOfChars) when NumOfChars =< 16384 -> 14; -charbits(NumOfChars) when NumOfChars =< 32768 -> 15; -charbits(NumOfChars) when NumOfChars =< 65536 -> 16; -charbits(NumOfChars) when is_integer(NumOfChars) -> - 16 + charbits1(NumOfChars bsr 16). - -charbits1(0) -> - 0; -charbits1(NumOfChars) -> - 1 + charbits1(NumOfChars bsr 1). - -%% copied from run time module - -emit_enc_octet_string(Erules, Constraint, Value) -> - case effective_constraint(bitstring, Constraint) of - 0 -> - emit({" []"}); - 1 -> - asn1ct_name:new(tmpval), - emit({" begin",nl}), - emit({" [",{curr,tmpval},"] = ",Value,",",nl}), - emit([" [[10,8],",{curr,tmpval},"]",nl]), - emit(" end"); - 2 -> - asn1ct_name:new(tmpval), - emit([" begin",nl, - " ",{curr,tmpval}," = ",Value,",",nl, - " case length(",{curr,tmpval},") of",nl, - " 2 ->",nl, - " [[45,16,2]|",{curr,tmpval},"];",nl, - " _ ->",nl, - " exit({error,{value_out_of_bounds,", - {curr,tmpval},"}})",nl, - " end",nl, - " end"]); - Sv when is_integer(Sv), Sv < 256 -> - asn1ct_name:new(tmpval), - asn1ct_name:new(tmplen), - emit([" begin",nl, - " ",{curr,tmpval}," = ",Value,",",nl, - " case length(",{curr,tmpval},") of",nl, - " ",Sv,"=",{curr,tmplen}," ->",nl, - " [20,",{curr,tmplen},"|",{curr,tmpval},"];",nl, - " _ ->",nl, - " exit({error,{value_out_of_bounds,", - {curr,tmpval},"}})",nl, - " end",nl, - " end"]); - Sv when is_integer(Sv),Sv =< 65535 -> - asn1ct_name:new(tmpval), - asn1ct_name:new(tmplen), - emit([" begin",nl, - " ",{curr,tmpval}," = ",Value,",",nl, - " case length(",{curr,tmpval},") of",nl, - " ",Sv,"=",{curr,tmplen}," ->",nl, - " [<<21,",{curr,tmplen},":16>>|",Value,"];",nl, - " _ ->",nl, - " exit({error,{value_out_of_bounds,", - {curr,tmpval},"}})",nl, - " end",nl, - " end"]); - C -> - call(Erules, encode_octet_string, - [{asis,C},Value]) - end. - -emit_enc_integer_case(Value) -> - case get(component_type) of - {true,#'ComponentType'{prop=Prop}} -> - emit({" begin",nl}), - case Prop of - Opt when Opt=='OPTIONAL'; - is_tuple(Opt),element(1,Opt)=='DEFAULT' -> - emit({" case ",Value," of",nl}), - ok; - _ -> - emit({" ",{curr,tmpval},"=",Value,",",nl}), - emit({" case ",{curr,tmpval}," of",nl}), - asn1ct_name:new(tmpval) - end; -% asn1ct_name:new(tmpval); - _ -> - emit({" case ",Value," of ",nl}) - end. -emit_enc_integer_end_case() -> - case get(component_type) of - {true,_} -> - emit({nl," end"}); % end of begin ... end - _ -> ok - end. - - -emit_enc_integer_NNL(Erules,C,Value,NNL) -> - EncVal = enc_integer_NNL_cases(Value,NNL), - emit_enc_integer(Erules,C,EncVal). - -enc_integer_NNL_cases(Value,NNL) -> - asn1ct_name:new(tmpval), - TmpVal = asn1ct_gen:mk_var(asn1ct_name:curr(tmpval)), - Cases=enc_integer_NNL_cases1(NNL), - lists:flatten(io_lib:format("(case ~s of "++Cases++ - "~s when is_atom(~s)->exit({error,{asn1,{namednumber,~s}}});_->~s end)",[Value,TmpVal,TmpVal,TmpVal,Value])). - -enc_integer_NNL_cases1([{NNo,No}|Rest]) -> - io_lib:format("~w->~w;",[NNo,No])++enc_integer_NNL_cases1(Rest); -enc_integer_NNL_cases1([]) -> - "". - -emit_enc_integer(_Erule,[{'SingleValue',Int}],Value) -> - asn1ct_name:new(tmpval), - emit_enc_integer_case(Value),% emit([" case ",Value," of",nl]), - emit([" ",Int," -> [];",nl]), - emit([" ",{curr,tmpval}," ->",nl]), - emit([" exit({error,{value_out_of_bounds,",{curr,tmpval},"}})", - nl," end",nl]), - emit_enc_integer_end_case(); - -emit_enc_integer(_Erule,[{_,{Lb,Ub},_Range,{bits,NoBs}}],Value) -> % Range =< 255 - asn1ct_name:new(tmpval), - emit_enc_integer_case(Value), - emit([" ",{curr,tmpval}," when ",{curr,tmpval},"=<",Ub,",", - {curr,tmpval},">=",Lb," ->",nl]), - emit([" [10,",NoBs,",",{curr,tmpval},"- ",Lb,"];",nl]), - emit([" ",{curr,tmpval}," ->",nl]), - emit([" exit({error,{value_out_of_bounds,", - {curr,tmpval},"}})",nl," end",nl]), - emit_enc_integer_end_case(); - -emit_enc_integer(_Erule,[{_,{Lb,Ub},Range,_}],Value) when Range =< 256 -> - asn1ct_name:new(tmpval), - emit_enc_integer_case(Value), - emit([" ",{curr,tmpval}," when ",{curr,tmpval},"=<",Ub,",", - {curr,tmpval},">=",Lb," ->",nl]), - emit([" [20,1,",{curr,tmpval},"- ",Lb,"];",nl]), - emit([" ",{curr,tmpval}," ->",nl]), - emit([" exit({error,{value_out_of_bounds,",{curr,tmpval},"}})", - nl," end",nl]), - emit_enc_integer_end_case(); - -emit_enc_integer(_Erule,[{_,{Lb,Ub},Range,_}],Value) when Range =< 65536 -> - asn1ct_name:new(tmpval), - emit_enc_integer_case(Value), - emit([" ",{curr,tmpval}," when ",{curr,tmpval},"=<",Ub,",", - {curr,tmpval},">=",Lb," ->",nl]), - emit([" [20,2,<<(",{curr,tmpval},"- ",Lb,"):16>>];",nl]), - emit([" ",{curr,tmpval}," ->",nl]), - emit([" exit({error,{value_out_of_bounds,",{curr,tmpval},"}})", - nl," end",nl]), - emit_enc_integer_end_case(); - -emit_enc_integer(Erule, [{'ValueRange',{Lb,Ub}=VR}], Value) - when is_integer(Lb), is_integer(Ub) -> - call(Erule, encode_constrained_number, [{asis,VR},Value]); - -emit_enc_integer(Erule, C, Value) -> - call(Erule, encode_integer, [{asis,C},Value]). - - -get_constraint([{Key,V}],Key) -> - V; -get_constraint([],_) -> - no; -get_constraint(C,Key) -> - case lists:keysearch(Key,1,C) of - false -> - no; - {value,{_,V}} -> - V - end. - -%% effective_constraint(Type,C) -%% Type = atom() -%% C = [C1,...] -%% C1 = {'SingleValue',SV} | {'ValueRange',VR} | {atom(),term()} -%% SV = integer() | [integer(),...] -%% VR = {Lb,Ub} -%% Lb = 'MIN' | integer() -%% Ub = 'MAX' | integer() -%% Returns a single value if C only has a single value constraint, and no -%% value range constraints, that constrains to a single value, otherwise -%% returns a value range that has the lower bound set to the lowest value -%% of all single values and lower bound values in C and the upper bound to -%% the greatest value. -effective_constraint(integer,[C={{_,_},_}|_Rest]) -> % extension - [C]; %% [C|effective_constraint(integer,Rest)]; XXX what is possible ??? -effective_constraint(integer,C) -> - pre_encode(integer, asn1ct_imm:effective_constraint(integer, C)); -effective_constraint(bitstring,C) -> - asn1ct_imm:effective_constraint(bitstring, C). - -pre_encode(integer,[]) -> - []; -pre_encode(integer,C=[{'SingleValue',_}]) -> - C; -pre_encode(integer,C=[{'ValueRange',VR={Lb,Ub}}]) when is_integer(Lb),is_integer(Ub)-> - Range = Ub-Lb+1, - if - Range =< 255 -> - NoBits = no_bits(Range), - [{'ValueRange',VR,Range,{bits,NoBits}}]; - Range =< 256 -> - [{'ValueRange',VR,Range,{octets,1}}]; - Range =< 65536 -> - [{'ValueRange',VR,Range,{octets,2}}]; - true -> - C - end; -pre_encode(integer,C) -> - C. - -no_bits(2) -> 1; -no_bits(N) when N=<4 -> 2; -no_bits(N) when N=<8 -> 3; -no_bits(N) when N=<16 -> 4; -no_bits(N) when N=<32 -> 5; -no_bits(N) when N=<64 -> 6; -no_bits(N) when N=<128 -> 7; -no_bits(N) when N=<255 -> 8. diff --git a/lib/asn1/src/asn1ct_imm.erl b/lib/asn1/src/asn1ct_imm.erl index bf362db843..892178f61b 100644 --- a/lib/asn1/src/asn1ct_imm.erl +++ b/lib/asn1/src/asn1ct_imm.erl @@ -26,6 +26,18 @@ per_dec_octet_string/2,per_dec_open_type/1,per_dec_real/1, per_dec_restricted_string/1]). -export([per_dec_constrained/3,per_dec_normally_small_number/1]). +-export([per_enc_bit_string/4,per_enc_boolean/2, + per_enc_choice/3,per_enc_enumerated/3, + per_enc_integer/3,per_enc_integer/4, + per_enc_null/2, + per_enc_k_m_string/4,per_enc_octet_string/3, + per_enc_open_type/2, + per_enc_restricted_string/3, + per_enc_small_number/2]). +-export([per_enc_extension_bit/2,per_enc_extensions/4,per_enc_optional/3]). +-export([per_enc_sof/5]). +-export([enc_absent/3,enc_append/1,enc_bind_var/1]). +-export([enc_cg/2]). -export([optimize_alignment/1,optimize_alignment/2, dec_slim_cg/2,dec_code_gen/2]). -export([effective_constraint/2]). @@ -115,29 +127,18 @@ per_dec_named_integer(Constraint, NamedList0, Aligned) -> per_dec_k_m_string(StringType, Constraint, Aligned) -> SzConstr = effective_constraint(bitstring, Constraint), N = string_num_bits(StringType, Constraint, Aligned), - %% X.691 (07/2002) 27.5.7 says if the upper bound times the number - %% of bits is greater than or equal to 16, then the bit field should - %% be aligned. - Imm = dec_string(SzConstr, N, Aligned, fun(_, Ub) -> Ub >= 16 end), + Imm = dec_string(SzConstr, N, Aligned, k_m_string), Chars = char_tab(Constraint, StringType, N), convert_string(N, Chars, Imm). per_dec_octet_string(Constraint, Aligned) -> - dec_string(Constraint, 8, Aligned, - %% Aligned unless the size is fixed and =< 16. - fun(Sv, Sv) -> Sv > 16; - (_, _) -> true - end). + dec_string(Constraint, 8, Aligned, 'OCTET STRING'). per_dec_raw_bitstring(Constraint, Aligned) -> - dec_string(Constraint, 1, Aligned, - fun(Sv, Sv) -> Sv > 16; - (_, _) -> true - end). + dec_string(Constraint, 1, Aligned, 'BIT STRING'). per_dec_open_type(Aligned) -> - {get_bits,decode_unconstrained_length(true, Aligned), - [8,binary,{align,Aligned}]}. + dec_string(no, 8, Aligned, open_type). per_dec_real(Aligned) -> Dec = fun(V, Buf) -> @@ -152,26 +153,285 @@ per_dec_restricted_string(Aligned) -> DecLen = decode_unconstrained_length(true, Aligned), {get_bits,DecLen,[8,binary]}. +%%% +%%% Encoding. +%%% + +per_enc_bit_string(Val0, [], Constraint0, Aligned) -> + {B,[Val,Bs,Bits]} = mk_vars(Val0, [bs,bits]), + Constraint = effective_constraint(bitstring, Constraint0), + ExtraArgs = case constr_min_size(Constraint) of + no -> []; + Lb -> [Lb] + end, + B ++ [{call,per_common,to_bitstring,[Val|ExtraArgs],Bs}, + {call,erlang,bit_size,[Bs],Bits}| + per_enc_length(Bs, 1, Bits, Constraint, Aligned, 'BIT STRING')]; +per_enc_bit_string(Val0, NNL0, Constraint0, Aligned) -> + {B,[Val,Bs,Bits,Positions]} = mk_vars(Val0, [bs,bits,positions]), + NNL = lists:keysort(2, NNL0), + Constraint = effective_constraint(bitstring, Constraint0), + ExtraArgs = case constr_min_size(Constraint) of + no -> []; + Lb -> [Lb] + end, + B ++ [{'try', + [bit_string_name2pos_fun(NNL, Val)], + {Positions, + [{call,per_common,bitstring_from_positions, + [Positions|ExtraArgs]}]}, + [{call,per_common,to_named_bitstring,[Val|ExtraArgs]}],Bs}, + {call,erlang,bit_size,[Bs],Bits}| + per_enc_length(Bs, 1, Bits, Constraint, Aligned, 'BIT STRING')]. + +per_enc_boolean(Val0, _Aligned) -> + {B,[Val]} = mk_vars(Val0, []), + B++build_cond([[{eq,Val,false},{put_bits,0,1,[1]}], + [{eq,Val,true},{put_bits,1,1,[1]}]]). + +per_enc_choice(Val0, Cs0, _Aligned) -> + {B,[Val]} = mk_vars(Val0, []), + Cs = [[{eq,Val,Tag}|opt_choice(Imm)] || {Tag,Imm} <- Cs0], + B++build_cond(Cs). + +per_enc_enumerated(Val0, {Root,Ext}, Aligned) -> + {B,[Val]} = mk_vars(Val0, []), + Constr = enumerated_constraint(Root), + RootCs = per_enc_enumerated_root(Root, [{put_bits,0,1,[1]}], + Val, Constr, Aligned), + ExtCs = per_enc_enumerated_ext(Ext, Val, Aligned), + B++[{'cond',RootCs++ExtCs++enumerated_error(Val)}]; +per_enc_enumerated(Val0, Root, Aligned) -> + {B,[Val]} = mk_vars(Val0, []), + Constr = enumerated_constraint(Root), + Cs = per_enc_enumerated_root(Root, [], Val, Constr, Aligned), + B++[{'cond',Cs++enumerated_error(Val)}]. + +enumerated_error(Val) -> + [['_',{error,Val}]]. + +per_enc_integer(Val0, Constraint0, Aligned) -> + {B,[Val]} = mk_vars(Val0, []), + Constraint = effective_constraint(integer, Constraint0), + B ++ per_enc_integer_1(Val, Constraint, Aligned). + +per_enc_integer(Val0, NNL, Constraint0, Aligned) -> + {B,[Val]} = mk_vars(Val0, []), + Constraint = effective_constraint(integer, Constraint0), + Cs = [[{eq,Val,N}|per_enc_integer_1(V, Constraint, Aligned)] || + {N,V} <- NNL], + case per_enc_integer_1(Val, Constraint, Aligned) of + [{'cond',IntCs}] -> + B ++ [{'cond',Cs++IntCs}]; + Other -> + B ++ [{'cond',Cs++[['_'|Other]]}] + end. + +per_enc_null(_Val, _Aligned) -> + []. + +per_enc_k_m_string(Val0, StringType, Constraint, Aligned) -> + {B,[Val,Bin,Len]} = mk_vars(Val0, [bin,len]), + SzConstraint = effective_constraint(bitstring, Constraint), + Unit = string_num_bits(StringType, Constraint, Aligned), + Chars0 = char_tab(Constraint, StringType, Unit), + Args = case enc_char_tab(Chars0) of + notab -> [Val,Unit]; + Chars -> [Val,Unit,Chars] + end, + Enc = case Unit of + 16 -> + {call,per_common,encode_chars_16bit,[Val],Bin}; + 32 -> + {call,per_common,encode_big_chars,[Val],Bin}; + 8 -> + {call,erlang,list_to_binary,[Val],Bin}; + _ -> + {call,per_common,encode_chars,Args,Bin} + end, + case Unit of + 8 -> + B ++ [Enc,{call,erlang,byte_size,[Bin],Len}]; + _ -> + B ++ [{call,erlang,length,[Val],Len},Enc] + end ++ per_enc_length(Bin, Unit, Len, SzConstraint, Aligned, k_m_string). + +per_enc_open_type([], Aligned) -> + [{put_bits,1,8,unit(1, Aligned)},{put_bits,0,8,[1]}]; +per_enc_open_type([{'cond', + [['_', + {put_bits,0,0,_}, + {call,per_common,encode_unconstrained_number,_}=Call]]}], + Aligned) -> + %% We KNOW that encode_unconstrained_number/1 will return an IO list; + %% therefore the call to complete/1 can be replaced with a cheaper + %% call to iolist_to_binary/1. + {Dst,Imm} = per_enc_open_type_output([Call], []), + ToBin = {erlang,iolist_to_binary}, + Imm ++ per_enc_open_type(Dst, ToBin, Aligned); +per_enc_open_type([{call,erlang,iolist_to_binary,Args}], Aligned) -> + {_,[_,Bin,Len]} = mk_vars('dummy', [bin,len]), + [{call,erlang,iolist_to_binary,Args,Bin}, + {call,erlang,byte_size,[Bin],Len}|per_enc_length(Bin, 8, Len, Aligned)]; +per_enc_open_type(Imm0, Aligned) -> + try + {Prefix,Imm1} = split_off_nonbuilding(Imm0), + Prefix ++ enc_open_type(Imm1, Aligned) + catch + throw:impossible -> + {Dst,Imm} = per_enc_open_type_output(Imm0, []), + ToBin = {enc_mod(Aligned),complete}, + Imm ++ per_enc_open_type(Dst, ToBin, Aligned) + end. + +per_enc_octet_string(Val0, Constraint0, Aligned) -> + {B,[Val,Bin,Len]} = mk_vars(Val0, [bin,len]), + Constraint = effective_constraint(bitstring, Constraint0), + B ++ [{call,erlang,iolist_to_binary,[Val],Bin}, + {call,erlang,byte_size,[Bin],Len}| + per_enc_length(Bin, 8, Len, Constraint, Aligned, 'OCTET STRING')]. + +per_enc_restricted_string(Val0, {M,F}, Aligned) -> + {B,[Val,Bin,Len]} = mk_vars(Val0, [bin,len]), + B ++ [{call,M,F,[Val],Bin}, + {call,erlang,byte_size,[Bin],Len}| + per_enc_length(Bin, 8, Len, Aligned)]. + +per_enc_small_number(Val, Aligned) -> + build_cond([[{lt,Val,64},{put_bits,Val,7,[1]}], + ['_',{put_bits,1,1,[1]}| + per_enc_unsigned(Val, Aligned)]]). + +per_enc_extension_bit(Val0, _Aligned) -> + {B,[Val]} = mk_vars(Val0, []), + B++build_cond([[{eq,Val,[]},{put_bits,0,1,[1]}], + ['_',{put_bits,1,1,[1]}]]). + +per_enc_extensions(Val0, Pos0, NumBits, Aligned) when NumBits > 0 -> + Pos = Pos0 + 1, + {B,[Val,Bitmap]} = mk_vars(Val0, [bitmap]), + Length = per_enc_small_length(NumBits, Aligned), + PutBits = case NumBits of + 1 -> [{put_bits,1,1,[1]}]; + _ -> [{put_bits,Bitmap,NumBits,[1]}] + end, + B++[{call,per_common,extension_bitmap,[Val,Pos,Pos+NumBits],Bitmap}, + {'cond',[[{eq,Bitmap,0}], + ['_'|Length ++ PutBits]],{var,"Extensions"}}]. + +per_enc_optional(Val0, {Pos,Def}, _Aligned) when is_integer(Pos) -> + Val1 = lists:concat(["element(",Pos,", ",Val0,")"]), + {B,[Val]} = mk_vars(Val1, []), + Zero = {put_bits,0,1,[1]}, + One = {put_bits,1,1,[1]}, + B++[{'cond',[[{eq,Val,asn1_DEFAULT},Zero], + [{eq,Val,Def},Zero], + ['_',One]]}]; +per_enc_optional(Val0, Pos, _Aligned) when is_integer(Pos) -> + Val1 = lists:concat(["element(",Pos,", ",Val0,")"]), + {B,[Val]} = mk_vars(Val1, []), + Zero = {put_bits,0,1,[1]}, + One = {put_bits,1,1,[1]}, + B++[{'cond',[[{eq,Val,asn1_NOVALUE},Zero], + ['_',One]]}]. + +per_enc_sof(Val0, Constraint, ElementVar, ElementImm, Aligned) -> + {B,[Val,Len]} = mk_vars(Val0, [len]), + SzConstraint = effective_constraint(bitstring, Constraint), + LenImm = enc_length(Len, SzConstraint, Aligned), + Lc0 = [{lc,ElementImm,{var,atom_to_list(ElementVar)},Val}], + Lc = opt_lc(Lc0, LenImm), + PreBlock = B ++ [{call,erlang,length,[Val],Len}], + case LenImm of + [{'cond',[[C|Action]]}] -> + PreBlock ++ [{'cond',[[C|Action++Lc]]}]; + [{sub,_,_,_}=Sub,{'cond',[[C|Action]]}] -> + PreBlock ++ + [Sub,{'cond',[[C|Action++Lc]]}]; + EncLen -> + PreBlock ++ EncLen ++ Lc + end. + +enc_absent(Val0, AbsVals, Body) -> + {B,[Var]} = mk_vars(Val0, []), + Cs = [[{eq,Var,Aval}] || Aval <- AbsVals] ++ [['_'|Body]], + B++build_cond(Cs). + +enc_append([[]|T]) -> + enc_append(T); +enc_append([[{put_bits,_,_,_}|_]=Pb|[Imm|T]=T0]) -> + case opt_choice(Pb++Imm) of + [{put_bits,_,_,_}|_] -> + [{block,Pb}|enc_append(T0)]; + Opt -> + enc_append([Opt|T]) + end; +enc_append([Imm0|[Imm1|T]=T0]) -> + try combine_imms(Imm0, Imm1) of + Imm -> + enc_append([Imm|T]) + catch + throw:impossible -> + [{block,Imm0}|enc_append(T0)] + end; +enc_append([H|T]) -> + [{block,H}|enc_append(T)]; +enc_append([]) -> []. + +enc_bind_var(Val) -> + {B,[{var,Var}]} = mk_vars(Val, []), + {B,list_to_atom(Var)}. + +enc_cg(Imm0, false) -> + Imm1 = enc_cse(Imm0), + Imm = enc_pre_cg(Imm1), + enc_cg(Imm); +enc_cg(Imm0, true) -> + Imm1 = enc_cse(Imm0), + Imm2 = enc_hoist_align(Imm1), + Imm3 = enc_opt_al(Imm2), + Imm4 = per_fixup(Imm3), + Imm = enc_pre_cg(Imm4), + enc_cg(Imm). %%% %%% Local functions. %%% -dec_string(Sv, U, Aligned0, AF) when is_integer(Sv) -> +%% is_aligned(StringType, LowerBound, UpperBound) -> boolean() +%% StringType = 'OCTET STRING' | 'BIT STRING' | k_m_string +%% LowerBound = UpperBound = number of bits +%% Determine whether a string should be aligned in PER. + +is_aligned(T, Lb, Ub) when T =:= 'OCTET STRING'; T =:= 'BIT STRING' -> + %% OCTET STRINGs and BIT STRINGs are aligned to a byte boundary + %% unless the size is fixed and less than or equal to 16 bits. + Lb =/= Ub orelse Lb > 16; +is_aligned(k_m_string, _Lb, Ub) -> + %% X.691 (07/2002) 27.5.7 says if the upper bound times the number + %% of bits is greater than or equal to 16, then the bit field should + %% be aligned. + Ub >= 16. + +%%% +%%% Generating the intermediate format format for decoding. +%%% + +dec_string(Sv, U, Aligned0, T) when is_integer(Sv) -> Bits = U*Sv, - Aligned = Aligned0 andalso AF(Bits, Bits), + Aligned = Aligned0 andalso is_aligned(T, Bits, Bits), {get_bits,Sv,[U,binary,{align,Aligned}]}; -dec_string({{Sv,Sv},[]}, U, Aligned, AF) -> - bit_case(dec_string(Sv, U, Aligned, AF), - dec_string(no, U, Aligned, AF)); -dec_string({{_,_}=C,[]}, U, Aligned, AF) -> - bit_case(dec_string(C, U, Aligned, AF), - dec_string(no, U, Aligned, AF)); -dec_string({Lb,Ub}, U, Aligned0, AF) -> +dec_string({{Sv,Sv},[]}, U, Aligned, T) -> + bit_case(dec_string(Sv, U, Aligned, T), + dec_string(no, U, Aligned, T)); +dec_string({{_,_}=C,[]}, U, Aligned, T) -> + bit_case(dec_string(C, U, Aligned, T), + dec_string(no, U, Aligned, T)); +dec_string({Lb,Ub}, U, Aligned0, T) -> Len = per_dec_constrained(Lb, Ub, Aligned0), - Aligned = Aligned0 andalso AF(Lb*U, Ub*U), + Aligned = Aligned0 andalso is_aligned(T, Lb*U, Ub*U), {get_bits,Len,[U,binary,{align,Aligned}]}; -dec_string(_, U, Aligned, _AF) -> +dec_string(_, U, Aligned, _T) -> Al = [{align,Aligned}], DecRest = fun(V, Buf) -> asn1ct_func:call(per_common, @@ -692,6 +952,1164 @@ mk_dest(I) when is_integer(I) -> integer_to_list(I); mk_dest(S) -> S. +%%% +%%% Constructing the intermediate format for encoding. +%%% + +split_off_nonbuilding(Imm) -> + lists:splitwith(fun is_nonbuilding/1, Imm). + +is_nonbuilding({apply,_,_,_}) -> true; +is_nonbuilding({assign,_,_}) -> true; +is_nonbuilding({call,_,_,_,_}) -> true; +is_nonbuilding({'cond',_,_}) -> true; +is_nonbuilding({lc,_,_,_,_}) -> true; +is_nonbuilding({sub,_,_,_}) -> true; +is_nonbuilding({'try',_,_,_,_}) -> true; +is_nonbuilding(_) -> false. + +mk_vars(Input0, Temps) -> + asn1ct_name:new(enc), + Curr = asn1ct_name:curr(enc), + [H|T] = atom_to_list(Curr), + Base = [H - ($a - $A)|T ++ "@"], + if + is_atom(Input0) -> + Input = {var,atom_to_list(Input0)}, + {[],[Input|mk_vars_1(Base, Temps)]}; + is_integer(Input0) -> + {[],[Input0|mk_vars_1(Base, Temps)]}; + Input0 =:= [] -> + {[],[Input0|mk_vars_1(Base, Temps)]}; + true -> + Input = mk_var(Base, input), + {[{assign,Input,Input0}],[Input|mk_vars_1(Base, Temps)]} + end. + +mk_vars_1(Base, Vars) -> + [mk_var(Base, V) || V <- Vars]. + +mk_var(Base, V) -> + {var,Base ++ atom_to_list(V)}. + +per_enc_integer_1(Val, [], Aligned) -> + [{'cond',[['_'|per_enc_unconstrained(Val, Aligned)]]}]; +per_enc_integer_1(Val0, [{{_,_}=Constr,[]}], Aligned) -> + {Prefix,Check,Action} = per_enc_integer_2(Val0, Constr, Aligned), + Prefix++build_cond([[Check,{put_bits,0,1,[1]}|Action], + ['_',{put_bits,1,1,[1]}| + per_enc_unconstrained(Val0, Aligned)]]); +per_enc_integer_1(Val0, [Constr], Aligned) -> + {Prefix,Check,Action} = per_enc_integer_2(Val0, Constr, Aligned), + Prefix++build_cond([[Check|Action], + ['_',{error,Val0}]]). + +per_enc_integer_2(Val, {'SingleValue',Sv}, Aligned) -> + per_enc_constrained(Val, Sv, Sv, Aligned); +per_enc_integer_2(Val0, {'ValueRange',{Lb,'MAX'}}, Aligned) + when is_integer(Lb) -> + {Prefix,Val} = sub_lb(Val0, Lb), + {Prefix,{ge,Val,0},per_enc_unsigned(Val, Aligned)}; +per_enc_integer_2(Val, {'ValueRange',{Lb,Ub}}, Aligned) + when is_integer(Lb), is_integer(Ub) -> + per_enc_constrained(Val, Lb, Ub, Aligned). + +per_enc_constrained(Val, Sv, Sv, _Aligned) -> + {[],{eq,Val,Sv},[]}; +per_enc_constrained(Val0, Lb, Ub, false) -> + {Prefix,Val} = sub_lb(Val0, Lb), + Range = Ub - Lb + 1, + NumBits = uper_num_bits(Range), + Check = {ult,Val,Range}, + Put = [{put_bits,Val,NumBits,[1]}], + {Prefix,Check,Put}; +per_enc_constrained(Val0, Lb, Ub, true) -> + {Prefix,Val} = sub_lb(Val0, Lb), + Range = Ub - Lb + 1, + if + Range < 256 -> + NumBits = per_num_bits(Range), + Check = {ult,Val,Range}, + Put = [{put_bits,Val,NumBits,[1]}], + {Prefix,Check,Put}; + Range =:= 256 -> + NumBits = 8, + Check = {ult,Val,Range}, + Put = [{put_bits,Val,NumBits,[1,align]}], + {Prefix,Check,Put}; + Range =< 65536 -> + Check = {ult,Val,Range}, + Put = [{put_bits,Val,16,[1,align]}], + {Prefix,Check,Put}; + true -> + {var,VarBase} = Val, + Bin = {var,VarBase++"@bin"}, + BinSize0 = {var,VarBase++"@bin_size0"}, + BinSize = {var,VarBase++"@bin_size"}, + Check = {ult,Val,Range}, + RangeOctsLen = byte_size(binary:encode_unsigned(Range - 1)), + BitsNeeded = per_num_bits(RangeOctsLen), + Enc = [{call,binary,encode_unsigned,[Val],Bin}, + {call,erlang,byte_size,[Bin],BinSize0}, + {sub,BinSize0,1,BinSize}, + {'cond',[['_', + {put_bits,BinSize,BitsNeeded,[1]}, + {put_bits,Bin,binary,[8,align]}]]}], + {Prefix,Check,Enc} + end. + +per_enc_unconstrained(Val, Aligned) -> + case Aligned of + false -> []; + true -> [{put_bits,0,0,[1,align]}] + end ++ [{call,per_common,encode_unconstrained_number,[Val]}]. + +per_enc_unsigned(Val, Aligned) -> + case is_integer(Val) of + false -> + {var,VarBase} = Val, + Bin = {var,VarBase++"@bin"}, + BinSize = {var,VarBase++"@bin_size"}, + [{call,binary,encode_unsigned,[Val],Bin}, + {call,erlang,byte_size,[Bin],BinSize}| + per_enc_length(Bin, 8, BinSize, Aligned)]; + true -> + Bin = binary:encode_unsigned(Val), + Len = byte_size(Bin), + per_enc_length(Bin, 8, Len, Aligned) + end. + +%% Encode a length field without any constraint. +per_enc_length(Bin, Unit, Len, Aligned) -> + U = unit(1, Aligned), + PutBits = put_bits_binary(Bin, Unit, Aligned), + EncFragmented = {call,per_common,encode_fragmented,[Bin,Unit]}, + Al = case Aligned of + false -> []; + true -> [{put_bits,0,0,[1,align]}] + end, + build_cond([[{lt,Len,128}, + {put_bits,Len,8,U},PutBits], + [{lt,Len,16384}, + {put_bits,2,2,U},{put_bits,Len,14,[1]},PutBits], + ['_'|Al++[EncFragmented]]]). + +per_enc_length(Bin, Unit, Len, no, Aligned, _Type) -> + per_enc_length(Bin, Unit, Len, Aligned); +per_enc_length(Bin, Unit, Len, {{Lb,Ub},[]}, Aligned, Type) -> + {Prefix,Check,PutLen} = per_enc_constrained(Len, Lb, Ub, Aligned), + NoExt = {put_bits,0,1,[1]}, + U = unit(Unit, Aligned, Type, Lb*Unit, Ub*Unit), + PutBits = [{put_bits,Bin,binary,U}], + [{'cond',ExtConds0}] = per_enc_length(Bin, Unit, Len, Aligned), + Ext = {put_bits,1,1,[1]}, + ExtConds = prepend_to_cond(ExtConds0, Ext), + build_length_cond(Prefix, [[Check,NoExt|PutLen++PutBits]|ExtConds]); +per_enc_length(Bin, Unit, Len, {Lb,Ub}, Aligned, Type) + when is_integer(Lb) -> + {Prefix,Check,PutLen} = per_enc_constrained(Len, Lb, Ub, Aligned), + U = unit(Unit, Aligned, Type, Lb*Unit, Ub*Unit), + PutBits = [{put_bits,Bin,binary,U}], + build_length_cond(Prefix, [[Check|PutLen++PutBits]]); +per_enc_length(Bin, Unit, Len, Sv, Aligned, Type) when is_integer(Sv) -> + NumBits = Sv*Unit, + U = unit(Unit, Aligned, Type, NumBits, NumBits), + Pb = {put_bits,Bin,binary,U}, + [{'cond',[[{eq,Len,Sv},Pb]]}]. + +enc_length(Len, no, Aligned) -> + U = unit(1, Aligned), + build_cond([[{lt,Len,128}, + {put_bits,Len,8,U}], + [{lt,Len,16384}, + {put_bits,2,2,U},{put_bits,Len,14,[1]}]]); +enc_length(Len, {{Lb,Ub},[]}, Aligned) -> + {Prefix,Check,PutLen} = per_enc_constrained(Len, Lb, Ub, Aligned), + NoExt = {put_bits,0,1,[1]}, + [{'cond',ExtConds0}] = enc_length(Len, no, Aligned), + Ext = {put_bits,1,1,[1]}, + ExtConds = prepend_to_cond(ExtConds0, Ext), + build_length_cond(Prefix, [[Check,NoExt|PutLen]|ExtConds]); +enc_length(Len, {Lb,Ub}, Aligned) when is_integer(Lb) -> + {Prefix,Check,PutLen} = per_enc_constrained(Len, Lb, Ub, Aligned), + build_length_cond(Prefix, [[Check|PutLen]]); +enc_length(Len, Sv, _Aligned) when is_integer(Sv) -> + [{'cond',[[{eq,Len,Sv}]]}]. + +put_bits_binary(Bin, _Unit, Aligned) when is_binary(Bin) -> + Sz = byte_size(Bin), + <<Int:Sz/unit:8>> = Bin, + {put_bits,Int,8*Sz,unit(1, Aligned)}; +put_bits_binary(Bin, Unit, Aligned) -> + {put_bits,Bin,binary,unit(Unit, Aligned)}. + +sub_lb(Val, 0) -> + {[],Val}; +sub_lb({var,Var}=Val0, Lb) -> + Val = {var,Var++"@sub"}, + {[{sub,Val0,Lb,Val}],Val}; +sub_lb(Val, Lb) when is_integer(Val) -> + {[],Val-Lb}. + +build_length_cond([{sub,Var0,Base,Var}]=Prefix, Cs) -> + %% Non-zero lower bound, such as: SIZE (50..200, ...) + Prefix++[{'cond',opt_length_nzlb(Cs, {Var0,Var,Base}, 0)}]; +build_length_cond([], Cs) -> + %% Zero lower bound, such as: SIZE (0..200, ...) + [{'cond',opt_length_zlb(Cs, 0)}]. + +opt_length_zlb([[{ult,Var,Val}|Actions]|T], Ub) -> + %% Since the SIZE constraint is zero-based, Var + %% must be greater than zero, and we can use + %% the slightly cheaper signed less than operator. + opt_length_zlb([[{lt,Var,Val}|Actions]|T], Ub); +opt_length_zlb([[{lt,_,Val}|_]=H|T], Ub) -> + if + Val =< Ub -> + %% A previous test has already matched. + opt_length_zlb(T, Ub); + true -> + [H|opt_length_zlb(T, max(Ub, Val))] + end; +opt_length_zlb([H|T], Ub) -> + [H|opt_length_zlb(T, Ub)]; +opt_length_zlb([], _) -> []. + +opt_length_nzlb([[{ult,Var,Val}|_]=H|T], {_,Var,Base}=St, _Ub) -> + [H|opt_length_nzlb(T, St, Base+Val)]; +opt_length_nzlb([[{lt,Var0,Val}|_]=H|T], {Var0,_,_}=St, Ub) -> + if + Val =< Ub -> + %% A previous test has already matched. + opt_length_nzlb(T, St, Ub); + true -> + [H|opt_length_nzlb(T, St, Val)] + end; +opt_length_nzlb([H|T], St, Ub) -> + [H|opt_length_nzlb(T, St, Ub)]; +opt_length_nzlb([], _, _) -> []. + +build_cond(Conds0) -> + case eval_cond(Conds0, gb_sets:empty()) of + [['_'|Actions]] -> + Actions; + Conds -> + [{'cond',Conds}] + end. + +eval_cond([['_',{'cond',Cs}]], Seen) -> + eval_cond(Cs, Seen); +eval_cond([[Cond|Actions]=H|T], Seen0) -> + case gb_sets:is_element(Cond, Seen0) of + false -> + Seen = gb_sets:insert(Cond, Seen0), + case eval_cond_1(Cond) of + false -> + eval_cond(T, Seen); + true -> + [['_'|Actions]]; + maybe -> + [H|eval_cond(T, Seen)] + end; + true -> + eval_cond(T, Seen0) + end; +eval_cond([], _) -> []. + +eval_cond_1({ult,I,N}) when is_integer(I), is_integer(N) -> + 0 =< I andalso I < N; +eval_cond_1({eq,[],[]}) -> + true; +eval_cond_1({eq,I,N}) when is_integer(I), is_integer(N) -> + I =:= N; +eval_cond_1({lt,I,N}) when is_integer(I), is_integer(N) -> + I < N; +eval_cond_1(_) -> maybe. + +prepend_to_cond([H|T], Code) -> + [prepend_to_cond_1(H, Code)|prepend_to_cond(T, Code)]; +prepend_to_cond([], _) -> []. + +prepend_to_cond_1([Check|T], Code) -> + [Check,Code|T]. + +enc_char_tab(notab) -> + notab; +enc_char_tab(Tab0) -> + Tab = tuple_to_list(Tab0), + First = hd(Tab), + {First-1,list_to_tuple(enc_char_tab_1(Tab, First, 0))}. + +enc_char_tab_1([H|T], H, I) -> + [I|enc_char_tab_1(T, H+1, I+1)]; +enc_char_tab_1([_|_]=T, H, I) -> + [ill|enc_char_tab_1(T, H+1, I)]; +enc_char_tab_1([], _, _) -> []. + +enumerated_constraint([_]) -> + [{'SingleValue',0}]; +enumerated_constraint(Root) -> + [{'ValueRange',{0,length(Root)-1}}]. + +per_enc_enumerated_root(NNL, Prefix, Val, Constr, Aligned) -> + per_enc_enumerated_root_1(NNL, Prefix, Val, Constr, Aligned, 0). + +per_enc_enumerated_root_1([{H,_}|T], Prefix, Val, Constr, Aligned, N) -> + [[{eq,Val,H}|Prefix++per_enc_integer_1(N, Constr, Aligned)]| + per_enc_enumerated_root_1(T, Prefix, Val, Constr, Aligned, N+1)]; +per_enc_enumerated_root_1([], _, _, _, _, _) -> []. + +per_enc_enumerated_ext(NNL, Val, Aligned) -> + per_enc_enumerated_ext_1(NNL, Val, Aligned, 0). + +per_enc_enumerated_ext_1([{H,_}|T], Val, Aligned, N) -> + [[{eq,Val,H},{put_bits,1,1,[1]}|per_enc_small_number(N, Aligned)]| + per_enc_enumerated_ext_1(T, Val, Aligned, N+1)]; +per_enc_enumerated_ext_1([], _, _, _) -> []. + +per_enc_small_length(Val0, Aligned) -> + {Sub,Val} = sub_lb(Val0, 1), + U = unit(1, Aligned), + Sub ++ build_cond([[{lt,Val,64},{put_bits,Val,7,[1]}], + [{lt,Val0,128},{put_bits,1,1,[1]}, + {put_bits,Val0,8,U}], + ['_',{put_bits,1,1,[1]}, + {put_bits,2,2,U},{put_bits,Val0,14,[1]}]]). + +constr_min_size(no) -> no; +constr_min_size({{Lb,_},[]}) when is_integer(Lb) -> Lb; +constr_min_size({Lb,_}) when is_integer(Lb) -> Lb; +constr_min_size(Sv) when is_integer(Sv) -> Sv. + +enc_mod(false) -> uper; +enc_mod(true) -> per. + +unit(U, false) -> [U]; +unit(U, true) -> [U,align]. + +unit(U, Aligned, Type, Lb, Ub) -> + case Aligned andalso is_aligned(Type, Lb, Ub) of + true -> [U,align]; + false -> [U] + end. + +opt_choice(Imm) -> + {Pb,T0} = lists:splitwith(fun({put_bits,V,_,_}) when is_integer(V) -> + true; + (_) -> + false + end, Imm), + try + {Prefix,T} = split_off_nonbuilding(T0), + Prefix ++ opt_choice_1(T, Pb) + catch + throw:impossible -> + Imm + end. + +opt_choice_1([{'cond',Cs0}], Pb) -> + case Cs0 of + [[C|Act]] -> + [{'cond',[[C|Pb++Act]]}]; + [[C|Act],['_',{error,_}]=Error] -> + [{'cond',[[C|Pb++Act],Error]}]; + _ -> + [{'cond',opt_choice_2(Cs0, Pb)}] + end; +opt_choice_1(_, _) -> throw(impossible). + +opt_choice_2([[C|[{put_bits,_,_,_}|_]=Act]|T], Pb) -> + [[C|Pb++Act]|opt_choice_2(T, Pb)]; +opt_choice_2([[_,{error,_}]=H|T], Pb) -> + [H|opt_choice_2(T, Pb)]; +opt_choice_2([_|_], _) -> + throw(impossible); +opt_choice_2([], _) -> []. + + +%%% +%%% Helper functions for code generation of open types. +%%% + +per_enc_open_type(Val0, {ToBinMod,ToBinFunc}, Aligned) -> + {B,[Val,Len,Bin]} = mk_vars(Val0, [len,bin]), + B ++ [{call,ToBinMod,ToBinFunc,[Val],Bin}, + {call,erlang,byte_size,[Bin],Len}| + per_enc_length(Bin, 8, Len, Aligned)]. + +enc_open_type([{'cond',Cs}], Aligned) -> + [{'cond',[[C|enc_open_type_1(Act, Aligned)] || [C|Act] <- Cs]}]; +enc_open_type(_, _) -> + throw(impossible). + +enc_open_type_1([{error,_}]=Imm, _) -> + Imm; +enc_open_type_1(Imm, Aligned) -> + NumBits = num_bits(Imm, 0), + Pad = case 8 - (NumBits rem 8) of + 8 -> []; + Pad0 -> [{put_bits,0,Pad0,[1]}] + end, + NumBytes = (NumBits+7) div 8, + enc_length(NumBytes, no, Aligned) ++ Imm ++ Pad. + +num_bits([{put_bits,_,N,[U|_]}|T], Sum) when is_integer(N) -> + num_bits(T, Sum+N*U); +num_bits([_|_], _) -> + throw(impossible); +num_bits([], Sum) -> Sum. + +per_enc_open_type_output([{apply,F,A}], Acc) -> + Dst = output_var(), + {Dst,lists:reverse(Acc, [{apply,F,A,{var,atom_to_list(Dst)}}])}; +per_enc_open_type_output([{call,M,F,A}], Acc) -> + Dst = output_var(), + {Dst,lists:reverse(Acc, [{call,M,F,A,{var,atom_to_list(Dst)}}])}; +per_enc_open_type_output([{'cond',Cs}], Acc) -> + Dst = output_var(), + {Dst,lists:reverse(Acc, [{'cond',Cs,{var,atom_to_list(Dst)}}])}; +per_enc_open_type_output([H|T], Acc) -> + per_enc_open_type_output(T, [H|Acc]). + +output_var() -> + asn1ct_name:new(enc), + Curr = asn1ct_name:curr(enc), + [H|T] = atom_to_list(Curr), + list_to_atom([H - ($a - $A)|T ++ "@output"]). + + +%%% +%%% Optimize list comprehensions (SEQUENCE OF/SET OF). +%%% + +opt_lc([{lc,[{call,erlang,iolist_to_binary,[Var],Bin}, + {call,erlang,byte_size,[Bin],LenVar}, + {'cond',[[{eq,LenVar,Len},{put_bits,Bin,_,[_|Align]}]]}], + Var,Val}]=Lc, LenImm) -> + %% Given a sequence of a fixed length string, such as + %% SEQUENCE OF OCTET STRING (SIZE (4)), attempt to rewrite to + %% a list comprehension that just checks the size, followed by + %% a conversion to binary: + %% + %% _ = [if length(Comp) =:= 4; byte_size(Comp) =:= 4 -> [] end || + %% Comp <- Sof], + %% [align|iolist_to_binary(Sof)] + + CheckImm = [{'cond',[[{eq,{expr,"length("++mk_val(Var)++")"},Len}], + [{eq,{expr,"byte_size("++mk_val(Var)++")"},Len}]]}], + Al = case Align of + [] -> + []; + [align] -> + [{put_bits,0,0,[1|Align]}] + end, + case Al =:= [] orelse + is_end_aligned(LenImm) orelse + lb_is_nonzero(LenImm) of + false -> + %% Not possible because an empty SEQUENCE OF would be + %% improperly aligned. Example: + %% + %% SEQUENCE (SIZE (0..3)) OF ... + + Lc; + true -> + %% Examples: + %% + %% SEQUENCE (SIZE (1..4)) OF ... + %% (OK because there must be at least one element) + %% + %% SEQUENCE OF ... + %% (OK because the length field will force alignment) + %% + Al ++ [{lc,CheckImm,Var,Val,{var,"_"}}, + {call,erlang,iolist_to_binary,[Val]}] + end; +opt_lc([{lc,ElementImm0,V,L}]=Lc, LenImm) -> + %% Attempt to hoist the alignment, putting after the length + %% and before the list comprehension: + %% + %% [Length, + %% align, + %% [Encode(Comp) || Comp <- Sof]] + %% + + case enc_opt_al_1(ElementImm0, 0) of + {ElementImm,0} -> + case is_end_aligned(LenImm) orelse + (is_beginning_aligned(ElementImm0) andalso + lb_is_nonzero(LenImm)) of + false -> + %% Examples: + %% + %% SEQUENCE (SIZE (0..3)) OF OCTET STRING + %% (An empty SEQUENCE OF would be improperly aligned) + %% + %% SEQUENCE (SIZE (1..3)) OF OCTET STRING (SIZE (0..4)) + %% (There would be an improper alignment before the + %% first element) + + Lc; + true -> + %% Examples: + %% + %% SEQUENCE OF INTEGER + %% SEQUENCE (SIZE (1..4)) OF INTEGER + %% SEQUENCE (SIZE (1..4)) OF INTEGER (0..256) + + [{put_bits,0,0,[1,align]},{lc,ElementImm,V,L}] + end; + _ -> + %% Unknown alignment, no alignment, or not aligned at the end. + %% Examples: + %% + %% SEQUENCE OF SomeConstructedType + %% SEQUENCE OF INTEGER (0..15) + + Lc + end. + +is_beginning_aligned([{'cond',Cs}]) -> + lists:all(fun([_|Act]) -> is_beginning_aligned(Act) end, Cs); +is_beginning_aligned([{error,_}|_]) -> true; +is_beginning_aligned([{put_bits,_,_,U}|_]) -> + case U of + [_,align] -> true; + [_] -> false + end; +is_beginning_aligned(Imm0) -> + case split_off_nonbuilding(Imm0) of + {[],_} -> false; + {[_|_],Imm} -> is_beginning_aligned(Imm) + end. + +is_end_aligned(Imm) -> + case enc_opt_al_1(Imm, unknown) of + {_,0} -> true; + {_,_} -> false + end. + +lb_is_nonzero([{sub,_,_,_}|_]) -> true; +lb_is_nonzero(_) -> false. + +%%% +%%% Attempt to combine two chunks of intermediate code. +%%% + +combine_imms(ImmA0, ImmB0) -> + {Prefix0,ImmA} = split_off_nonbuilding(ImmA0), + {Prefix1,ImmB} = split_off_nonbuilding(ImmB0), + Prefix = Prefix0 ++ Prefix1, + Combined = do_combine(ImmA ++ ImmB, 3.0), + Prefix ++ Combined. + +do_combine([{error,_}=Imm|_], _Budget) -> + [Imm]; +do_combine([{'cond',Cs0}|T], Budget0) -> + Budget = debit(Budget0, num_clauses(Cs0, 0)), + Cs = [[C|do_combine(Act++T, Budget)] || [C|Act] <- Cs0], + [{'cond',Cs}]; +do_combine([{put_bits,V,_,_}|_]=L, Budget) when is_integer(V) -> + {Pb,T} = collect_put_bits(L), + do_combine_put_bits(Pb, T,Budget); +do_combine(_, _) -> + throw(impossible). + +do_combine_put_bits(Pb, [], _Budget) -> + Pb; +do_combine_put_bits(Pb, [{'cond',Cs0}|T], Budget) -> + Cs = [case Act of + [{error,_}] -> + [C|Act]; + _ -> + [C|do_combine(Pb++Act, Budget)] + end || [C|Act] <- Cs0], + do_combine([{'cond',Cs}|T], Budget); +do_combine_put_bits(_, _, _) -> + throw(impossible). + +debit(Budget0, Alternatives) -> + case Budget0 - log2(Alternatives) of + Budget when Budget > 0.0 -> + Budget; + _ -> + throw(impossible) + end. + +num_clauses([[_,{error,_}]|T], N) -> + num_clauses(T, N); +num_clauses([_|T], N) -> + num_clauses(T, N+1); +num_clauses([], N) -> N. + +log2(N) -> + math:log(N) / math:log(2.0). + +collect_put_bits(Imm) -> + lists:splitwith(fun({put_bits,V,_,_}) when is_integer(V) -> true; + (_) -> false + end, Imm). + +%%% +%%% Simple common subexpression elimination to avoid fetching +%%% the same element twice. +%%% + +enc_cse([{assign,{var,V},E}=H|T]) -> + [H|enc_cse_1(T, E, V)]; +enc_cse(Imm) -> Imm. + +enc_cse_1([{assign,Dst,E}|T], E, V) -> + [{assign,Dst,V}|enc_cse_1(T, E, V)]; +enc_cse_1([{block,Bl}|T], E, V) -> + [{block,enc_cse_1(Bl, E, V)}|enc_cse_1(T, E, V)]; +enc_cse_1([H|T], E, V) -> + [H|enc_cse_1(T, E, V)]; +enc_cse_1([], _, _) -> []. + + +%%% +%%% Pre-process the intermediate code to simplify code generation. +%%% + +enc_pre_cg(Imm) -> + enc_pre_cg_1(Imm, outside_list, in_seq). + +enc_pre_cg_1([], _StL, _StB) -> + nil; +enc_pre_cg_1([H], StL, StB) -> + enc_pre_cg_2(H, StL, StB); +enc_pre_cg_1([H0|T0], StL, StB) -> + case is_nonbuilding(H0) of + true -> + H = enc_pre_cg_nonbuilding(H0, StL), + Seq = {seq,H,enc_pre_cg_1(T0, StL, in_seq)}, + case StB of + outside_seq -> {block,Seq}; + in_seq -> Seq + end; + false -> + H = enc_pre_cg_2(H0, in_head, outside_seq), + T = enc_pre_cg_1(T0, in_tail, outside_seq), + enc_make_cons(H, T) + end. + +enc_pre_cg_2(align, StL, _StB) -> + case StL of + in_head -> align; + in_tail -> {cons,align,nil} + end; +enc_pre_cg_2({apply,_,_}=Imm, _, _) -> + Imm; +enc_pre_cg_2({block,Bl0}, StL, StB) -> + enc_pre_cg_1(Bl0, StL, StB); +enc_pre_cg_2({call,_,_,_}=Imm, _, _) -> + Imm; +enc_pre_cg_2({call_gen,_,_,_,_}=Imm, _, _) -> + Imm; +enc_pre_cg_2({'cond',Cs0}, StL, _StB) -> + Cs = [{C,enc_pre_cg_1(Act, StL, outside_seq)} || [C|Act] <- Cs0], + {'cond',Cs}; +enc_pre_cg_2({error,_}=E, _, _) -> + E; +enc_pre_cg_2({lc,B0,V,L}, StL, _StB) -> + B = enc_pre_cg_1(B0, StL, outside_seq), + {lc,B,V,L}; +enc_pre_cg_2({put_bits,V,8,[1]}, StL, _StB) -> + case StL of + in_head -> {integer,V}; + in_tail -> {cons,{integer,V},nil}; + outside_list -> {cons,{integer,V},nil} + end; +enc_pre_cg_2({put_bits,V,binary,_}, _StL, _StB) -> + V; +enc_pre_cg_2({put_bits,_,_,[_]}=PutBits, _StL, _StB) -> + {binary,[PutBits]}; +enc_pre_cg_2({var,_}=Imm, _, _) -> Imm. + +enc_make_cons({binary,H}, {binary,T}) -> + {binary,H++T}; +enc_make_cons({binary,H0}, {cons,{binary,H1},T}) -> + {cons,{binary,H0++H1},T}; +enc_make_cons({integer,Int}, {binary,T}) -> + {binary,[{put_bits,Int,8,[1]}|T]}; +enc_make_cons(H, T) -> + {cons,H,T}. + +enc_pre_cg_nonbuilding({'cond',Cs0,Dst}, StL) -> + Cs = [{C,enc_pre_cg_1(Act, StL, outside_seq)} || [C|Act] <- Cs0], + {'cond',Cs,Dst}; +enc_pre_cg_nonbuilding({lc,B0,Var,List,Dst}, StL) -> + B = enc_pre_cg_1(B0, StL, outside_seq), + {lc,B,Var,List,Dst}; +enc_pre_cg_nonbuilding({'try',Try0,{P,Succ0},Else0,Dst}, StL) -> + Try = enc_pre_cg_1(Try0, StL, outside_seq), + Succ = enc_pre_cg_1(Succ0, StL, outside_seq), + Else = enc_pre_cg_1(Else0, StL, outside_seq), + {'try',Try,{P,Succ},Else,Dst}; +enc_pre_cg_nonbuilding(Imm, _) -> Imm. + + +%%% +%%% Code generation for encoding. +%%% + +enc_cg({cons,_,_}=Cons) -> + enc_cg_cons(Cons); +enc_cg({block,Imm}) -> + emit(["begin",nl]), + enc_cg(Imm), + emit([nl, + "end"]); +enc_cg({seq,First,Then}) -> + enc_cg(First), + emit([com,nl]), + enc_cg(Then); +enc_cg(align) -> + emit(align); +enc_cg({apply,F0,As0}) -> + As = enc_call_args(As0, ""), + case F0 of + {M,F} -> + emit([{asis,M},":",{asis,F},"(",As,")"]); + F when is_atom(F) -> + emit([{asis,F},"(",As,")"]) + end; +enc_cg({apply,F0,As0,Dst}) -> + As = enc_call_args(As0, ""), + emit([mk_val(Dst)," = "]), + case F0 of + {M,F} -> + emit([{asis,M},":",{asis,F},"(",As,")"]); + F when is_atom(F) -> + emit([{asis,F},"(",As,")"]) + end; +enc_cg({assign,Dst0,Expr}) -> + Dst = mk_val(Dst0), + emit([Dst," = ",Expr]); +enc_cg({binary,PutBits}) -> + emit(["<<",enc_cg_put_bits(PutBits, ""),">>"]); +enc_cg({call,M,F,As0}) -> + As = [mk_val(A) || A <- As0], + asn1ct_func:call(M, F, As); +enc_cg({call,M,F,As0,Dst}) -> + As = [mk_val(A) || A <- As0], + emit([mk_val(Dst)," = "]), + asn1ct_func:call(M, F, As); +enc_cg({call_gen,Prefix,Key,Gen,As0}) -> + As = [mk_val(A) || A <- As0], + asn1ct_func:call_gen(Prefix, Key, Gen, As); +enc_cg({'cond',Cs}) -> + enc_cg_cond(Cs); +enc_cg({'cond',Cs,Dst0}) -> + Dst = mk_val(Dst0), + emit([Dst," = "]), + enc_cg_cond(Cs); +enc_cg({error,Error}) when is_function(Error, 0) -> + Error(); +enc_cg({error,Var0}) -> + Var = mk_val(Var0), + emit(["exit({error,{asn1,{illegal_value,",Var,"}}})"]); +enc_cg({integer,Int}) -> + emit(mk_val(Int)); +enc_cg({lc,Body,Var,List}) -> + emit("["), + enc_cg(Body), + emit([" || ",mk_val(Var)," <- ",mk_val(List),"]"]); +enc_cg({lc,Body,Var,List,Dst}) -> + emit([mk_val(Dst)," = ["]), + enc_cg(Body), + emit([" || ",mk_val(Var)," <- ",mk_val(List),"]"]); +enc_cg(nil) -> + emit("[]"); +enc_cg({sub,Src0,Int,Dst0}) -> + Src = mk_val(Src0), + Dst = mk_val(Dst0), + emit([Dst," = ",Src," - ",Int]); +enc_cg({'try',Try,{P,Succ},Else,Dst}) -> + emit([mk_val(Dst)," = try "]), + enc_cg(Try), + emit([" of",nl, + mk_val(P)," ->",nl]), + enc_cg(Succ), + emit([nl, + "catch throw:invalid ->",nl]), + enc_cg(Else), + emit([nl, + "end"]); +enc_cg({var,V}) -> + emit(V). + +enc_cg_cons(Cons) -> + emit("["), + enc_cg_cons_1(Cons), + emit("]"). + +enc_cg_cons_1({cons,H,{cons,_,_}=T}) -> + enc_cg(H), + emit([com,nl]), + enc_cg_cons_1(T); +enc_cg_cons_1({cons,H,nil}) -> + enc_cg(H); +enc_cg_cons_1({cons,H,T}) -> + enc_cg(H), + emit("|"), + enc_cg(T). + +enc_call_args([A|As], Sep) -> + [Sep,mk_val(A)|enc_call_args(As, ", ")]; +enc_call_args([], _) -> []. + +enc_cg_cond([{'_',Action}]) -> + enc_cg(Action); +enc_cg_cond(Cs) -> + emit("if "), + enc_cg_cond(Cs, ""), + emit([nl, + "end"]). + +enc_cg_cond([C|Cs], Sep) -> + emit(Sep), + enc_cg_cond_1(C), + enc_cg_cond(Cs, [";",nl]); +enc_cg_cond([], _) -> ok. + +enc_cg_cond_1({Cond,Action}) -> + enc_cond_term(Cond), + emit([" ->",nl]), + enc_cg(Action). + +enc_cond_term('_') -> + emit("true"); +enc_cond_term({ult,Var0,Int}) -> + Var = mk_val(Var0), + N = uper_num_bits(Int), + case 1 bsl N of + Int -> + emit([Var," bsr ",N," =:= 0"]); + _ -> + emit(["0 =< ",Var,", ",Var," < ",Int]) + end; +enc_cond_term({eq,Var0,Term}) -> + Var = mk_val(Var0), + emit([Var," =:= ",{asis,Term}]); +enc_cond_term({ge,Var0,Int}) -> + Var = mk_val(Var0), + emit([Var," >= ",Int]); +enc_cond_term({lt,Var0,Int}) -> + Var = mk_val(Var0), + emit([Var," < ",Int]). + +enc_cg_put_bits([{put_bits,Val0,N,[1]}|T], Sep) -> + Val = mk_val(Val0), + [[Sep,Val,":",integer_to_list(N)]|enc_cg_put_bits(T, ",")]; +enc_cg_put_bits([], _) -> []. + +mk_val({var,Str}) -> Str; +mk_val({expr,Str}) -> Str; +mk_val(Int) when is_integer(Int) -> integer_to_list(Int); +mk_val(Other) -> {asis,Other}. + +%%% +%%% Generate a function that maps a name of a bit position +%%% to the bit position. +%%% + +bit_string_name2pos_fun(NNL, Src) -> + {call_gen,"bit_string_name2pos_",NNL, + fun(Fd, Name) -> gen_name2pos(Fd, Name, NNL) end,[Src]}. + +gen_name2pos(Fd, Name, Names) -> + Cs0 = gen_name2pos_cs(Names, Name), + Cs = Cs0 ++ [bit_clause(Name),nil_clause(),invalid_clause()], + F = {function,1,Name,1,Cs}, + file:write(Fd, [erl_pp:function(F)]). + +gen_name2pos_cs([{K,V}|T], Name) -> + P = [{cons,0,{atom,0,K},{var,0,'T'}}], + B = [{cons,0,{integer,0,V},{call,0,{atom,0,Name},[{var,0,'T'}]}}], + [{clause,0,P,[],B}|gen_name2pos_cs(T, Name)]; +gen_name2pos_cs([], _) -> []. + +bit_clause(Name) -> + VarT = {var,0,'T'}, + VarPos = {var,0,'Pos'}, + P = [{cons,0,{tuple,0,[{atom,0,bit},VarPos]},VarT}], + G = [[{call,0,{atom,0,is_integer},[VarPos]}]], + B = [{cons,0,VarPos,{call,0,{atom,0,Name},[VarT]}}], + {clause,0,P,G,B}. + +nil_clause() -> + P = B = [{nil,0}], + {clause,0,P,[],B}. + +invalid_clause() -> + P = [{var,0,'_'}], + B = [{call,0,{atom,0,throw},[{atom,0,invalid}]}], + {clause,0,P,[],B}. + +%%% +%%% Hoist alignment to reduce the number of list elements in +%%% encode. Fewer lists elements means faster traversal in +%%% complete/{2,3}. +%%% +%%% For example, the following data sequence: +%%% +%%% [align,<<1:1,0:1>>,[align,<<Len:16>>|Data]] +%%% +%%% can be rewritten to: +%%% +%%% [align,<<1:1,0:1,0:6>>,[<<Len:16>>|Data]] +%%% +%%% The change from the literal <<1:1,0:1>> to <<1:1,0:1,0:6>> +%%% comes for free, and we have eliminated one element of the +%%% sub list. +%%% +%%% We must be careful not to rewrite: +%%% +%%% [<<1:1,0:1>>,[align,<<Len:16>>|Data]] +%%% +%%% to: +%%% +%%% [[<<1:1,0:1>>,align],[<<Len:16>>|Data]] +%%% +%%% because even though [<<1:0,0:1>>,align] is a literal and does +%%% not add any additional construction cost, there is one more +%%% sub list that needs to be traversed. +%%% + +enc_hoist_align(Imm0) -> + Imm = enc_hoist_align_reverse(Imm0, []), + enc_hoist_align(Imm, false, []). + +enc_hoist_align_reverse([H|T], Acc) -> + case enc_opt_al_1([H], 0) of + {[H],_} -> + enc_hoist_align_reverse(T, [H|Acc]); + {_,_} -> + lists:reverse(T, [H,stop|Acc]) + end; +enc_hoist_align_reverse([], Acc) -> Acc. + +enc_hoist_align([stop|T], _Aligned, Acc) -> + lists:reverse(T, Acc); +enc_hoist_align([{block,Bl0}|T], Aligned, Acc) -> + Bl = case Aligned of + false -> Bl0; + true -> enc_hoist_block(Bl0) + end, + case is_beginning_aligned(Bl) of + false -> + enc_hoist_align(T, false, [{block,Bl}|Acc]); + true -> + enc_hoist_align(T, true, [{put_bits,0,0,[1,align]}, + {block,Bl}|Acc]) + end; +enc_hoist_align([H|T], _, Acc) -> + enc_hoist_align(T, false, [H|Acc]); +enc_hoist_align([], _, Acc) -> Acc. + +enc_hoist_block(Bl) -> + try + enc_hoist_block_1(lists:reverse(Bl)) + catch + throw:impossible -> + Bl + end. + +enc_hoist_block_1([{'cond',Cs0}|T]) -> + Cs = [[C|enc_hoist_block_2(Act)] || [C|Act] <- Cs0], + H = {'cond',Cs}, + lists:reverse(T, [H]); +enc_hoist_block_1(_) -> + throw(impossible). + +enc_hoist_block_2([{'cond',_}|_]=L) -> + enc_hoist_block(L); +enc_hoist_block_2([{error,_}]=L) -> + L; +enc_hoist_block_2([]) -> + [{put_bits,0,0,[1,align]}]; +enc_hoist_block_2(L) -> + case lists:last(L) of + {put_bits,_,_,_} -> + L ++ [{put_bits,0,0,[1,align]}]; + _ -> + throw(impossible) + end. + +%%% +%%% Optimize alignment for encoding. +%%% + +enc_opt_al(Imm0) -> + {Imm,_} = enc_opt_al_1(Imm0, unknown), + Imm. + +enc_opt_al_1([{'cond',Cs0,Dst},{call,per,complete,[Dst],Bin}|T0], Al0) -> + {Cs1,{M,F}} = enc_opt_al_prepare_cond(Cs0), + {Cs,_} = enc_opt_al_cond(Cs1, 0), + {T,Al} = enc_opt_al_1([{call,M,F,[Dst],Bin}|T0], Al0), + {[{'cond',Cs,Dst}|T],Al}; +enc_opt_al_1([H0|T0], Al0) -> + {H,Al1} = enc_opt_al(H0, Al0), + {T,Al} = enc_opt_al_1(T0, Al1), + {H++T,Al}; +enc_opt_al_1([], Al) -> {[],Al}. + +enc_opt_al({apply,_,_,_}=Imm, Al) -> + {[Imm],Al}; +enc_opt_al({assign,_,_}=Imm, Al) -> + {[Imm],Al}; +enc_opt_al({block,Bl0}, Al0) -> + {Bl,Al} = enc_opt_al_1(Bl0, Al0), + {[{block,Bl}],Al}; +enc_opt_al({call,erlang,iolist_to_binary,[_]}=Imm, Al) -> + {[Imm],Al}; +enc_opt_al({call,per_common,encode_fragmented,[_,U]}=Call, Al) -> + case U rem 8 of + 0 -> {[Call],Al}; + _ -> {[Call],unknown} + end; +enc_opt_al({call,per_common,encode_unconstrained_number,[_]}=Call, _) -> + {[Call],0}; +enc_opt_al({call,_,_,_,_}=Call, Al) -> + {[Call],Al}; +enc_opt_al({'cond',Cs0}, Al0) -> + {Cs,Al} = enc_opt_al_cond(Cs0, Al0), + {[{'cond',Cs}],Al}; +enc_opt_al({error,_}=Imm, Al) -> + {[Imm],Al}; +enc_opt_al({put_bits,V,N,[U,align]}, Al0) when Al0 rem 8 =:= 0 -> + Al = if + is_integer(N) -> N*U; + N =:= binary, U rem 8 =:= 0 -> 0; + true -> unknown + end, + {[{put_bits,V,N,[U]}],Al}; +enc_opt_al({put_bits,V,binary,[U,align]}, Al0) when is_integer(Al0) -> + N = 8 - (Al0 rem 8), + Al = case U rem 8 of + 0 -> 0; + _ -> unknown + end, + {[{put_bits,0,N,[1]},{put_bits,V,binary,[U]}],Al}; +enc_opt_al({put_bits,V,N0,[U,align]}, Al0) when is_integer(N0), is_integer(Al0) -> + N = N0 + (8 - Al0 rem 8), + Al = N0*U, + {[{put_bits,V,N,[1]}],Al}; +enc_opt_al({put_bits,_,N,[U,align]}=PutBits, _) when is_integer(N) -> + {[PutBits],N*U}; +enc_opt_al({put_bits,_,binary,[U,align]}=PutBits, _) when U rem 8 =:= 0 -> + {[PutBits],0}; +enc_opt_al({put_bits,_,N,[U]}=PutBits, Al) when is_integer(N), is_integer(Al) -> + {[PutBits],Al+N*U}; +enc_opt_al({put_bits,_,binary,[U]}=PutBits, Al) when U rem 8 =:= 0 -> + {[PutBits],Al}; +enc_opt_al({sub,_,_,_}=Imm, Al) -> + {[Imm],Al}; +enc_opt_al(Imm, _) -> + {[Imm],unknown}. + +enc_opt_al_cond(Cs0, Al0) -> + enc_opt_al_cond_1(Cs0, Al0, [], []). + +enc_opt_al_cond_1([['_',{error,_}]=C|Cs], Al, CAcc, AAcc) -> + enc_opt_al_cond_1(Cs, Al, [C|CAcc], AAcc); +enc_opt_al_cond_1([[C|Act0]|Cs0], Al0, CAcc, AAcc) -> + {Act,Al1} = enc_opt_al_1(Act0, Al0), + Al = if + Al1 =:= unknown -> Al1; + true -> Al1 rem 8 + end, + enc_opt_al_cond_1(Cs0, Al0, [[C|Act]|CAcc], [Al|AAcc]); +enc_opt_al_cond_1([], _, CAcc, AAcc) -> + Al = case lists:usort(AAcc) of + [] -> unknown; + [Al0] -> Al0; + [_|_] -> unknown + end, + {lists:reverse(CAcc),Al}. + +enc_opt_al_prepare_cond(Cs0) -> + try enc_opt_al_prepare_cond_1(Cs0) of + Cs -> + {Cs,{erlang,iolist_to_binary}} + catch + throw:impossible -> + {Cs0,{per,complete}} + end. + +enc_opt_al_prepare_cond_1(Cs) -> + [[C|enc_opt_al_prepare_cond_2(Act)] || [C|Act] <- Cs]. + +enc_opt_al_prepare_cond_2([{put_bits,_,binary,[U|_]}|_]) when U rem 8 =/= 0 -> + throw(impossible); +enc_opt_al_prepare_cond_2([{put_bits,_,_,_}=H|T]) -> + [H|enc_opt_al_prepare_cond_2(T)]; +enc_opt_al_prepare_cond_2([{call,per_common,encode_fragmented,_}=H|T]) -> + [H|enc_opt_al_prepare_cond_2(T)]; +enc_opt_al_prepare_cond_2([_|_]) -> + throw(impossible); +enc_opt_al_prepare_cond_2([]) -> + [{put_bits,0,0,[1,align]}]. + + +%%% +%%% For the aligned PER format, fix up the intermediate format +%%% before code generation. Code generation will be somewhat +%%% easier if 'align' appear as a separate instruction. +%%% + +per_fixup([{apply,_,_}=H|T]) -> + [H|per_fixup(T)]; +per_fixup([{apply,_,_,_}=H|T]) -> + [H|per_fixup(T)]; +per_fixup([{block,Block}|T]) -> + [{block,per_fixup(Block)}|per_fixup(T)]; +per_fixup([{'assign',_,_}=H|T]) -> + [H|per_fixup(T)]; +per_fixup([{'cond',Cs0}|T]) -> + Cs = [[C|per_fixup(Act)] || [C|Act] <- Cs0], + [{'cond',Cs}|per_fixup(T)]; +per_fixup([{'cond',Cs0,Dst}|T]) -> + Cs = [[C|per_fixup(Act)] || [C|Act] <- Cs0], + [{'cond',Cs,Dst}|per_fixup(T)]; +per_fixup([{call,_,_,_}=H|T]) -> + [H|per_fixup(T)]; +per_fixup([{call,_,_,_,_}=H|T]) -> + [H|per_fixup(T)]; +per_fixup([{call_gen,_,_,_,_}=H|T]) -> + [H|per_fixup(T)]; +per_fixup([{error,_}=H|T]) -> + [H|per_fixup(T)]; +per_fixup([{lc,B,V,L}|T]) -> + [{lc,per_fixup(B),V,L}|per_fixup(T)]; +per_fixup([{lc,B,V,L,Dst}|T]) -> + [{lc,per_fixup(B),V,L,Dst}|per_fixup(T)]; +per_fixup([{sub,_,_,_}=H|T]) -> + [H|per_fixup(T)]; +per_fixup([{'try',Try0,{P,Succ0},Else0,Dst}|T]) -> + Try = per_fixup(Try0), + Succ = per_fixup(Succ0), + Else = per_fixup(Else0), + [{'try',Try,{P,Succ},Else,Dst}|per_fixup(T)]; +per_fixup([{put_bits,_,_,_}|_]=L) -> + fixup_put_bits(L); +per_fixup([{var,_}=H|T]) -> + [H|per_fixup(T)]; +per_fixup([]) -> []. + +fixup_put_bits([{put_bits,0,0,[_,align]}|T]) -> + [align|fixup_put_bits(T)]; +fixup_put_bits([{put_bits,0,0,_}|T]) -> + fixup_put_bits(T); +fixup_put_bits([{put_bits,V,N,[U,align]}|T]) -> + [align,{put_bits,V,N,[U]}|fixup_put_bits(T)]; +fixup_put_bits([{put_bits,_,_,_}=H|T]) -> + [H|fixup_put_bits(T)]; +fixup_put_bits(Other) -> per_fixup(Other). + %% effective_constraint(Type,C) %% Type = atom() %% C = [C1,...] diff --git a/lib/asn1/src/asn1ct_parser2.erl b/lib/asn1/src/asn1ct_parser2.erl index 1abccc8626..283616b157 100644 --- a/lib/asn1/src/asn1ct_parser2.erl +++ b/lib/asn1/src/asn1ct_parser2.erl @@ -38,6 +38,7 @@ parse(Tokens) -> {error,{Reason,hd(Tokens)}}; {ModuleDefinition,Rest1} -> {Types,Rest2} = parse_AssignmentList(Rest1), + clean_process_dictionary(), case Rest2 of [{'END',_}|_Rest3] -> {ok,ModuleDefinition#module{typeorval = Types}}; @@ -48,6 +49,13 @@ parse(Tokens) -> end end. +clean_process_dictionary() -> + Mod = erase(asn1_module), + _ = erase({Mod,imports}), + _ = erase(tagdefault), + _ = erase(extensiondefault), + ok. + parse_ModuleDefinition([{typereference,L1,ModuleIdentifier}|Rest0]) -> put(asn1_module,ModuleIdentifier), {_DefinitiveIdentifier,Rest02} = diff --git a/lib/asn1/src/asn1ct_value.erl b/lib/asn1/src/asn1ct_value.erl index ecdfa3f645..992210232f 100644 --- a/lib/asn1/src/asn1ct_value.erl +++ b/lib/asn1/src/asn1ct_value.erl @@ -32,11 +32,11 @@ from_type(M,Typename) -> - case asn1_db:dbget(M,Typename) of - undefined -> + case asn1_db:dbload(M) of + error -> {error,{not_found,{M,Typename}}}; - Tdef when is_record(Tdef,typedef) -> - Type = Tdef#typedef.typespec, + ok -> + #typedef{typespec=Type} = asn1_db:dbget(M, Typename), from_type(M,[Typename],Type); Vdef when is_record(Vdef,valuedef) -> from_value(Vdef); diff --git a/lib/asn1/src/asn1rtt_ber.erl b/lib/asn1/src/asn1rtt_ber.erl index b5429fe324..583ff790b7 100644 --- a/lib/asn1/src/asn1rtt_ber.erl +++ b/lib/asn1/src/asn1rtt_ber.erl @@ -22,8 +22,7 @@ %% encoding / decoding of BER -export([ber_decode_nif/1,ber_decode_erlang/1,match_tags/2,ber_encode/1]). --export([encode_tags/2, - encode_tags/3, +-export([encode_tags/3, skip_ExtensionAdditions/2]). -export([encode_boolean/2,decode_boolean/2, encode_integer/2,encode_integer/3, diff --git a/lib/asn1/src/asn1rtt_per.erl b/lib/asn1/src/asn1rtt_per.erl index 9f4b7500d8..672c84593c 100644 --- a/lib/asn1/src/asn1rtt_per.erl +++ b/lib/asn1/src/asn1rtt_per.erl @@ -18,62 +18,7 @@ %% -module(asn1rtt_per). --export([setext/1, fixextensions/2, - skipextensions/3, - set_choice/3,encode_integer/2, - encode_small_number/1, - encode_constrained_number/2, - encode_length/1, - encode_length/2, - encode_bit_string/3, - encode_object_identifier/1, - encode_relative_oid/1, - complete/1, - encode_open_type/1, - encode_GeneralString/2, - encode_GraphicString/2, - encode_TeletexString/2, - encode_VideotexString/2, - encode_ObjectDescriptor/2, - encode_UTF8String/1, - encode_octet_string/2, - encode_known_multiplier_string/4, - octets_to_complete/2]). - --define('16K',16384). --define('32K',32768). --define('64K',65536). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% setext(true|false) -> CompleteList -%% - -setext(false) -> - [0]; -setext(true) -> - [1]. - -fixextensions({ext,ExtPos,ExtNum},Val) -> - case fixextensions(ExtPos,ExtNum+ExtPos,Val,0) of - 0 -> []; - ExtBits -> - [encode_small_length(ExtNum)|pre_complete_bits(ExtNum,ExtBits)] - end. - -fixextensions(Pos,MaxPos,_,Acc) when Pos >= MaxPos -> - Acc; -fixextensions(Pos,ExtPos,Val,Acc) -> - Bit = case catch(element(Pos+1,Val)) of - asn1_NOVALUE -> - 0; - asn1_NOEXTVALUE -> - 0; - {'EXIT',_} -> - 0; - _ -> - 1 - end, - fixextensions(Pos+1,ExtPos,Val,(Acc bsl 1)+Bit). +-export([skipextensions/3,complete/1]). skipextensions(Bytes0, Nr, ExtensionBitstr) when is_bitstring(ExtensionBitstr) -> Prev = Nr - 1, @@ -95,270 +40,6 @@ align(BitStr) when is_bitstring(BitStr) -> <<_:AlignBits,Rest/binary>> = BitStr, Rest. -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% set_choice(Alt,Choices,Altnum) -> ListofBitSettings -%% Alt = atom() -%% Altnum = integer() | {integer(),integer()}% number of alternatives -%% Choices = [atom()] | {[atom()],[atom()]} -%% When Choices is a tuple the first list is the Rootset and the -%% second is the Extensions and then Altnum must also be a tuple with the -%% lengths of the 2 lists -%% -set_choice(Alt,{L1,L2},{Len1,_Len2}) -> - case set_choice_tag(Alt,L1) of - N when is_integer(N), Len1 > 1 -> - [0, % the value is in the root set - encode_constrained_number({0,Len1-1},N)]; - N when is_integer(N) -> - [0]; % no encoding if only 0 or 1 alternative - false -> - [1, % extension value - case set_choice_tag(Alt, L2) of - N2 when is_integer(N2) -> - encode_small_number(N2); - false -> - unknown_choice_alt - end] - end; -set_choice(Alt, L, Len) -> - case set_choice_tag(Alt, L) of - N when is_integer(N), Len > 1 -> - encode_constrained_number({0,Len-1},N); - N when is_integer(N) -> - []; % no encoding if only 0 or 1 alternative - false -> - [unknown_choice_alt] - end. - -set_choice_tag(Alt,Choices) -> - set_choice_tag(Alt,Choices,0). - -set_choice_tag(Alt,[Alt|_Rest],Tag) -> - Tag; -set_choice_tag(Alt,[_H|Rest],Tag) -> - set_choice_tag(Alt,Rest,Tag+1); -set_choice_tag(_Alt,[],_Tag) -> - false. - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% encode_open_type(Constraint, Value) -> CompleteList -%% Value = list of bytes of an already encoded value (the list must be flat) -%% | binary -%% Contraint = not used in this version -%% -encode_open_type(Val) -> - case byte_size(Val) of - Size when Size > 255 -> - [encode_length(Size),21,<<Size:16>>,Val]; % octets implies align - Size -> - [encode_length(Size),20,Size,Val] - end. - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% encode_integer(Constraint, Value) -> CompleteList -%% -encode_integer([{Rc,_Ec}],Val) when is_tuple(Rc) -> - try - [0|encode_integer([Rc], Val)] - catch - _:{error,{asn1,_}} -> - [1|encode_unconstrained_number(Val)] - end; -encode_integer([], Val) -> - encode_unconstrained_number(Val); -%% The constraint is the effective constraint, and in this case is a number -encode_integer([{'SingleValue',V}], V) -> - []; -encode_integer([{'ValueRange',{Lb,Ub}=VR,Range,PreEnc}],Val) - when Val >= Lb, Ub >= Val -> - %% this case when NamedNumberList - encode_constrained_number(VR, Range, PreEnc, Val); -encode_integer([{'ValueRange',{Lb,'MAX'}}], Val) when Lb =< Val -> - encode_semi_constrained_number(Lb, Val); -encode_integer([{'ValueRange',{'MIN',_}}], Val) -> - encode_unconstrained_number(Val); -encode_integer([{'ValueRange',VR={_Lb,_Ub}}], Val) -> - encode_constrained_number(VR, Val); -encode_integer(_,Val) -> - exit({error,{asn1,{illegal_value,Val}}}). - - -%% X.691:10.6 Encoding of a normally small non-negative whole number -%% Use this for encoding of CHOICE index if there is an extension marker in -%% the CHOICE -encode_small_number(Val) when Val < 64 -> - [10,7,Val]; -encode_small_number(Val) -> - [1|encode_semi_constrained_number(0, Val)]. - -%% X.691:10.7 Encoding of a semi-constrained whole number -encode_semi_constrained_number(Lb, Val) -> - Val2 = Val - Lb, - Oct = eint_positive(Val2), - Len = length(Oct), - if - Len < 128 -> - [20,Len+1,Len|Oct]; - Len < 256 -> - [encode_length(Len),20,Len|Oct]; - true -> - [encode_length(Len),21,<<Len:16>>|Oct] - end. - -encode_constrained_number({Lb,_Ub},_Range,{bits,N},Val) -> - Val2 = Val-Lb, - [10,N,Val2]; -encode_constrained_number({Lb,_Ub},_Range,{octets,N},Val) when N < 256-> - %% N is 8 or 16 (1 or 2 octets) - Val2 = Val-Lb, - [20,N,Val2]; -encode_constrained_number({Lb,_Ub},_Range,{octets,N},Val) -> % N>255 - %% N is 8 or 16 (1 or 2 octets) - Val2 = Val-Lb, - [21,<<N:16>>,Val2]; -encode_constrained_number({Lb,_Ub},Range,_,Val) -> - Val2 = Val-Lb, - if - Range =< 16#1000000 -> % max 3 octets - Octs = eint_positive(Val2), - L = length(Octs), - [encode_length({1,3},L),[20,L,Octs]]; - Range =< 16#100000000 -> % max 4 octets - Octs = eint_positive(Val2), - L = length(Octs), - [encode_length({1,4},L),[20,L,Octs]]; - Range =< 16#10000000000 -> % max 5 octets - Octs = eint_positive(Val2), - L = length(Octs), - [encode_length({1,5},L),[20,L,Octs]]; - true -> - exit({not_supported,{integer_range,Range}}) - end. - -encode_constrained_number({Lb,Ub}, Val) when Val >= Lb, Ub >= Val -> - Range = Ub - Lb + 1, - Val2 = Val - Lb, - if - Range == 1 -> []; - Range == 2 -> - [Val2]; - Range =< 4 -> - [10,2,Val2]; - Range =< 8 -> - [10,3,Val2]; - Range =< 16 -> - [10,4,Val2]; - Range =< 32 -> - [10,5,Val2]; - Range =< 64 -> - [10,6,Val2]; - Range =< 128 -> - [10,7,Val2]; - Range =< 255 -> - [10,8,Val2]; - Range =< 256 -> - [20,1,Val2]; - Range =< 65536 -> - [20,2,<<Val2:16>>]; - Range =< (1 bsl (255*8)) -> - Octs = binary:encode_unsigned(Val2), - RangeOcts = binary:encode_unsigned(Range - 1), - OctsLen = byte_size(Octs), - RangeOctsLen = byte_size(RangeOcts), - LengthBitsNeeded = minimum_bits(RangeOctsLen - 1), - [10,LengthBitsNeeded,OctsLen-1,20,OctsLen,Octs]; - true -> - exit({not_supported,{integer_range,Range}}) - end; -encode_constrained_number({_,_},Val) -> - exit({error,{asn1,{illegal_value,Val}}}). - -%% For some reason the minimum bits needed in the length field in -%% the encoding of constrained whole numbers must always be at least 2? -minimum_bits(N) when N < 4 -> 2; -minimum_bits(N) when N < 8 -> 3; -minimum_bits(N) when N < 16 -> 4; -minimum_bits(N) when N < 32 -> 5; -minimum_bits(N) when N < 64 -> 6; -minimum_bits(N) when N < 128 -> 7; -minimum_bits(_N) -> 8. - -%% X.691:10.8 Encoding of an unconstrained whole number - -encode_unconstrained_number(Val) -> - Oct = if - Val >= 0 -> - eint(Val, []); - true -> - enint(Val, []) - end, - Len = length(Oct), - if - Len < 128 -> - [20,Len + 1,Len|Oct]; - Len < 256 -> - [20,Len + 2,<<2:2,Len:14>>|Oct]; - true -> - [encode_length(Len),21,<<Len:16>>|Oct] - end. - -%% used for positive Values which don't need a sign bit -%% returns a list -eint_positive(Val) -> - case eint(Val,[]) of - [0,B1|T] -> - [B1|T]; - T -> - T - end. - - -eint(0, [B|Acc]) when B < 128 -> - [B|Acc]; -eint(N, Acc) -> - eint(N bsr 8, [N band 16#ff| Acc]). - -enint(-1, [B1|T]) when B1 > 127 -> - [B1|T]; -enint(N, Acc) -> - enint(N bsr 8, [N band 16#ff|Acc]). - -%% X.691:10.9 Encoding of a length determinant -%%encode_small_length(undefined,Len) -> % null means no UpperBound -%% encode_small_number(Len). - -%% X.691:10.9.3.5 -%% X.691:10.9.3.7 -encode_length(Len) -> % unconstrained - if - Len < 128 -> - [20,1,Len]; - Len < 16384 -> - <<20,2,2:2,Len:14>>; - true -> % should be able to endode length >= 16384 i.e. fragmented length - exit({error,{asn1,{encode_length,{nyi,above_16k}}}}) - end. - -encode_length({C,[]}, Len) -> - case C of - {Lb,Ub}=Vr when Lb =< Len, Len =< Ub -> - [0|encode_constrained_number(Vr, Len)]; - _ -> - [1|encode_length(Len)] - end; -encode_length(Len, Len) -> - []; -encode_length(Vr, Len) -> - encode_constrained_number(Vr, Len). - -%% X.691 10.9.3.4 (only used for length of bitmap that prefixes extension -%% additions in a sequence or set -encode_small_length(Len) when Len =< 64 -> - [10,7,Len-1]; -encode_small_length(Len) -> - [1,encode_length(Len)]. - - decode_length(Buffer) -> % un-constrained case align(Buffer) of <<0:1,Oct:7,Rest/binary>> -> @@ -370,511 +51,70 @@ decode_length(Buffer) -> % un-constrained exit({error,{asn1,{decode_length,{nyi,above_16k}}}}) end. -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% bitstring NamedBitList -%% Val can be of: -%% - [identifiers] where only named identifers are set to one, -%% the Constraint must then have some information of the -%% bitlength. -%% - [list of ones and zeroes] all bits -%% - integer value representing the bitlist -%% C is constraint Len, only valid when identifiers - - -%% when the value is a list of {Unused,BinBits}, where -%% Unused = integer(), -%% BinBits = binary(). - -encode_bit_string(C, Bits, NamedBitList) when is_bitstring(Bits) -> - PadLen = (8 - (bit_size(Bits) band 7)) band 7, - Compact = {PadLen,<<Bits/bitstring,0:PadLen>>}, - encode_bin_bit_string(C, Compact, NamedBitList); -encode_bit_string(C, {Unused,BinBits}=Bin, NamedBitList) - when is_integer(Unused), is_binary(BinBits) -> - encode_bin_bit_string(C,Bin,NamedBitList); - -%% when the value is a list of named bits - -encode_bit_string(C, LoNB=[FirstVal | _RestVal], NamedBitList) when is_atom(FirstVal) -> - ToSetPos = get_all_bitposes(LoNB, NamedBitList, []), - BitList = make_and_set_list(ToSetPos,0), - encode_bit_string(C,BitList,NamedBitList);% consider the constraint - -encode_bit_string(C, BL=[{bit,_} | _RestVal], NamedBitList) -> - ToSetPos = get_all_bitposes(BL, NamedBitList, []), - BitList = make_and_set_list(ToSetPos,0), - encode_bit_string(C,BitList,NamedBitList); - -%% when the value is a list of ones and zeroes -encode_bit_string(Int, BitListValue, _) - when is_list(BitListValue),is_integer(Int),Int =< 16 -> - %% The type is constrained by a single value size constraint - %% range_check(Int,length(BitListValue)), - [40,Int,length(BitListValue),BitListValue]; -encode_bit_string(Int, BitListValue, _) - when is_list(BitListValue),is_integer(Int), Int =< 255 -> - %% The type is constrained by a single value size constraint - %% range_check(Int,length(BitListValue)), - [2,40,Int,length(BitListValue),BitListValue]; -encode_bit_string(Int, BitListValue, _) - when is_list(BitListValue),is_integer(Int), Int < ?'64K' -> - {Code,DesiredLength,Length} = - case length(BitListValue) of - B1 when B1 > Int -> - exit({error,{'BIT_STRING_length_greater_than_SIZE', - Int,BitListValue}}); - B1 when B1 =< 255,Int =< 255 -> - {40,Int,B1}; - B1 when B1 =< 255 -> - {42,<<Int:16>>,B1}; - B1 -> - {43,<<Int:16>>,<<B1:16>>} - end, - %% The type is constrained by a single value size constraint - [2,Code,DesiredLength,Length,BitListValue]; -encode_bit_string(no, BitListValue,[]) - when is_list(BitListValue) -> - [encode_length(length(BitListValue)), - 2|BitListValue]; -encode_bit_string({{Fix,Fix},Ext}, BitListValue,[]) - when is_integer(Fix), is_list(Ext) -> - case length(BitListValue) of - Len when Len =< Fix -> - [0|encode_bit_string(Fix, BitListValue, [])]; - _ -> - [1|encode_bit_string(no, BitListValue, [])] - end; -encode_bit_string(C, BitListValue,[]) - when is_list(BitListValue) -> - [encode_length(C, length(BitListValue)), - 2|BitListValue]; -encode_bit_string(no, BitListValue,_NamedBitList) - when is_list(BitListValue) -> - %% this case with an unconstrained BIT STRING can be made more efficient - %% if the complete driver can take a special code so the length field - %% is encoded there. - NewBitLVal = lists:reverse(lists:dropwhile(fun(0)->true;(1)->false end, - lists:reverse(BitListValue))), - [encode_length(length(NewBitLVal)),2|NewBitLVal]; -encode_bit_string({{Fix,Fix},Ext}, BitListValue, NamedBitList) - when is_integer(Fix), is_list(Ext) -> - case length(BitListValue) of - Len when Len =< Fix -> - [0|encode_bit_string(Fix, BitListValue, NamedBitList)]; - _ -> - [1|encode_bit_string(no, BitListValue, NamedBitList)] - end; -encode_bit_string(C, BitListValue, _NamedBitList) - when is_list(BitListValue) -> % C = {_,'MAX'} - NewBitLVal = bit_string_trailing_zeros(BitListValue, C), - [encode_length(C, length(NewBitLVal)),2|NewBitLVal]; - - -%% when the value is an integer -encode_bit_string(C, IntegerVal, NamedBitList) when is_integer(IntegerVal)-> - BitList = int_to_bitlist(IntegerVal), - encode_bit_string(C,BitList,NamedBitList). - -bit_string_trailing_zeros(BitList,C) when is_integer(C) -> - bit_string_trailing_zeros1(BitList,C,C); -bit_string_trailing_zeros(BitList,{Lb,Ub}) when is_integer(Lb) -> - bit_string_trailing_zeros1(BitList,Lb,Ub); -bit_string_trailing_zeros(BitList,{{Lb,Ub},_}) when is_integer(Lb) -> - bit_string_trailing_zeros1(BitList,Lb,Ub); -bit_string_trailing_zeros(BitList,_) -> - BitList. - -bit_string_trailing_zeros1(BitList,Lb,Ub) -> - case length(BitList) of - Lb -> BitList; - B when B < Lb -> BitList++lists:duplicate(Lb-B, 0); - D -> F = fun(L,LB,LB,_,_)->lists:reverse(L); - ([0|R],L1,LB,UB,Fun)->Fun(R,L1-1,LB,UB,Fun); - (L,L1,_,UB,_)when L1 =< UB -> lists:reverse(L); - (_,_L1,_,_,_) ->exit({error,{list_length_BIT_STRING, - BitList}}) end, - F(lists:reverse(BitList),D,Lb,Ub,F) - end. - -%% encode_bin_bit_string/3, when value is a tuple of Unused and BinBits. -%% Unused = integer(),i.e. number unused bits in least sign. byte of -%% BinBits = binary(). -encode_bin_bit_string(C, {Unused,BinBits}, _NamedBitList) - when is_integer(C),C=<16 -> - range_check(C, bit_size(BinBits) - Unused), - [45,C,byte_size(BinBits),BinBits]; -encode_bin_bit_string(C, {Unused,BinBits}, _NamedBitList) - when is_integer(C), C =< 255 -> - range_check(C, bit_size(BinBits) - Unused), - [2,45,C,byte_size(BinBits),BinBits]; -encode_bin_bit_string(C, {Unused,BinBits}, _NamedBitList) - when is_integer(C), C =< 65535 -> - range_check(C, bit_size(BinBits) - Unused), - case byte_size(BinBits) of - Size when Size =< 255 -> - [2,46,<<C:16>>,Size,BinBits]; - Size -> - [2,47,<<C:16>>,<<Size:16>>,BinBits] - end; -encode_bin_bit_string(C,UnusedAndBin={_,_},NamedBitList) -> - {Unused1,Bin1} = - %% removes all trailing bits if NamedBitList is not empty - remove_trailing_bin(NamedBitList,UnusedAndBin), - case C of - {Lb,Ub} when is_integer(Lb),is_integer(Ub) -> - Size = byte_size(Bin1), - [encode_length({Lb,Ub}, Size*8 - Unused1), - 2,octets_unused_to_complete(Unused1,Size,Bin1)]; - no -> - Size = byte_size(Bin1), - [encode_length(Size*8 - Unused1), - 2|octets_unused_to_complete(Unused1, Size, Bin1)]; - {{Fix,Fix},Ext} when is_integer(Fix),is_list(Ext) -> - case byte_size(Bin1)*8 - Unused1 of - Size when Size =< Fix -> - [0|encode_bin_bit_string(Fix,UnusedAndBin,NamedBitList)]; - _Size -> - [1|encode_bin_bit_string(no,UnusedAndBin,NamedBitList)] - end; - Sc -> - Size = byte_size(Bin1), - [encode_length(Sc, Size*8 - Unused1), - 2|octets_unused_to_complete(Unused1,Size,Bin1)] - end. - -range_check(C,C) when is_integer(C) -> - ok; -range_check(C1,C2) when is_integer(C1) -> - exit({error,{asn1,{bit_string_out_of_range,{C1,C2}}}}). - -remove_trailing_bin([], {Unused,Bin}) -> - {Unused,Bin}; -remove_trailing_bin(_NamedNumberList,{_Unused,<<>>}) -> - {0,<<>>}; -remove_trailing_bin(NamedNumberList, {_Unused,Bin}) -> - Size = byte_size(Bin)-1, - <<Bfront:Size/binary, LastByte:8>> = Bin, - %% clear the Unused bits to be sure - Unused1 = trailingZeroesInNibble(LastByte band 15), - Unused2 = - case Unused1 of - 4 -> - 4 + trailingZeroesInNibble(LastByte bsr 4); - _ -> Unused1 - end, - case Unused2 of - 8 -> - remove_trailing_bin(NamedNumberList,{0,Bfront}); - _ -> - {Unused2,Bin} - end. - - -trailingZeroesInNibble(0) -> - 4; -trailingZeroesInNibble(1) -> - 0; -trailingZeroesInNibble(2) -> - 1; -trailingZeroesInNibble(3) -> - 0; -trailingZeroesInNibble(4) -> - 2; -trailingZeroesInNibble(5) -> - 0; -trailingZeroesInNibble(6) -> - 1; -trailingZeroesInNibble(7) -> - 0; -trailingZeroesInNibble(8) -> - 3; -trailingZeroesInNibble(9) -> - 0; -trailingZeroesInNibble(10) -> - 1; -trailingZeroesInNibble(11) -> - 0; -trailingZeroesInNibble(12) -> %#1100 - 2; -trailingZeroesInNibble(13) -> - 0; -trailingZeroesInNibble(14) -> - 1; -trailingZeroesInNibble(15) -> - 0. - - -%%%%%%%%%%%%%%% -%% - -int_to_bitlist(Int) when is_integer(Int), Int > 0 -> - [Int band 1 | int_to_bitlist(Int bsr 1)]; -int_to_bitlist(0) -> - []. - - -%%%%%%%%%%%%%%%%%% -%% get_all_bitposes([list of named bits to set], named_bit_db, []) -> -%% [sorted_list_of_bitpositions_to_set] - -get_all_bitposes([{bit,ValPos}|Rest], NamedBitList, Ack) -> - get_all_bitposes(Rest, NamedBitList, [ValPos | Ack ]); - -get_all_bitposes([Val | Rest], NamedBitList, Ack) -> - case lists:keyfind(Val, 1, NamedBitList) of - {_ValName, ValPos} -> - get_all_bitposes(Rest, NamedBitList, [ValPos | Ack]); - false -> - exit({error,{asn1, {bitstring_namedbit, Val}}}) - end; -get_all_bitposes([], _NamedBitList, Ack) -> - lists:sort(Ack). - -%%%%%%%%%%%%%%%%%% -%% make_and_set_list([list of positions to set to 1])-> -%% returns list with all in SetPos set. -%% in positioning in list the first element is 0, the second 1 etc.., but -%% - -make_and_set_list([XPos|SetPos], XPos) -> - [1 | make_and_set_list(SetPos, XPos + 1)]; -make_and_set_list([Pos|SetPos], XPos) -> - [0 | make_and_set_list([Pos | SetPos], XPos + 1)]; -make_and_set_list([], _) -> - []. - - - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% X.691:16 -%% encode_octet_string(Constraint, Val) -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -encode_octet_string({{Sv,Sv},Ext}=SZ, Val) when is_list(Ext), Sv =< 2 -> - Len = length(Val), - try - case encode_length(SZ, Len) of - [0|_]=EncLen -> - [EncLen,45,Sv*8,Sv,Val]; - [_|_]=EncLen -> - [EncLen|octets_to_complete(Len, Val)] - end - catch - exit:{error,{asn1,{encode_length,_}}} -> - encode_fragmented_octet_string(Val) - end; -encode_octet_string({_,_}=SZ, Val) -> - Len = length(Val), - try - [encode_length(SZ, Len),2|octets_to_complete(Len, Val)] - catch - exit:{error,{asn1,{encode_length,_}}} -> - encode_fragmented_octet_string(Val) - end; -encode_octet_string(Sv, Val) when is_integer(Sv) -> - encode_fragmented_octet_string(Val); -encode_octet_string(no, Val) -> - Len = length(Val), - try - [encode_length(Len),2|octets_to_complete(Len, Val)] - catch - exit:{error,{asn1,{encode_length,_}}} -> - encode_fragmented_octet_string(Val) - end. - -encode_fragmented_octet_string(Val) -> - Bin = iolist_to_binary(Val), - efos_1(Bin). - -efos_1(<<B1:16#C000/binary,B2:16#4000/binary,T/binary>>) -> - [20,1,<<3:2,4:6>>, - octets_to_complete(16#C000, B1), - octets_to_complete(16#4000, B2)|efos_1(T)]; -efos_1(<<B:16#C000/binary,T/binary>>) -> - [20,1,<<3:2,3:6>>,octets_to_complete(16#C000, B)|efos_1(T)]; -efos_1(<<B:16#8000/binary,T/binary>>) -> - [20,1,<<3:2,2:6>>,octets_to_complete(16#8000, B)|efos_1(T)]; -efos_1(<<B:16#4000/binary,T/binary>>) -> - [20,1,<<3:2,1:6>>,octets_to_complete(16#4000, B)|efos_1(T)]; -efos_1(<<>>) -> - [20,1,0]; -efos_1(<<B/bitstring>>) -> - Len = byte_size(B), - [encode_length(Len)|octets_to_complete(Len, B)]. - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% Restricted char string types -%% (NumericString, PrintableString,VisibleString,IA5String,BMPString,UniversalString) -%% X.691:26 and X.680:34-36 - -encode_restricted_string(Val) when is_list(Val)-> - Len = length(Val), - [encode_length(Len)|octets_to_complete(Len, Val)]. - -encode_known_multiplier_string(SizeC, NumBits, CharOutTab, Val) -> - Result = chars_encode2(Val, NumBits, CharOutTab), - case SizeC of - Ub when is_integer(Ub), Ub*NumBits < 16 -> - Result; - Ub when is_integer(Ub) -> - [2,Result]; - {{_,Ub},Ext}=SZ when is_list(Ext) -> - Len = length(Val), - case encode_length(SZ, Len) of - [0|_]=EncLen when Ub*NumBits < 16 -> - [EncLen,45,Len*NumBits,Len,Val]; - [_|_]=EncLen -> - [EncLen,2|Result] - end; - {_,Ub}=Range -> - [encode_length(Range, length(Val))| - if - Ub*NumBits < 16 -> Result; - true -> [2|Result] - end]; - no -> - [encode_length(length(Val)),2,Result] - end. - -encode_GeneralString(_C,Val) -> - encode_restricted_string(Val). - -encode_GraphicString(_C,Val) -> - encode_restricted_string(Val). - -encode_ObjectDescriptor(_C,Val) -> - encode_restricted_string(Val). - -encode_TeletexString(_C,Val) -> % equivalent with T61String - encode_restricted_string(Val). - -encode_VideotexString(_C,Val) -> - encode_restricted_string(Val). - - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% chars_encode(C,StringType,Value) -> ValueList -%% -%% encodes chars according to the per rules taking the constraint -%% PermittedAlphabet into account. -%% -%% This function only encodes the value part and NOT the length. - -chars_encode2([H|T],NumBits,T1={Min,Max,notab}) when H =< Max, H >= Min -> - [pre_complete_bits(NumBits,H-Min)|chars_encode2(T,NumBits,T1)]; -chars_encode2([H|T],NumBits,T1={Min,Max,Tab}) when H =< Max, H >= Min -> - [pre_complete_bits(NumBits,exit_if_false(H,element(H-Min+1,Tab)))| - chars_encode2(T,NumBits,T1)]; -chars_encode2([{A,B,C,D}|T],NumBits,T1={Min,_Max,notab}) -> - %% no value range check here (ought to be, but very expensive) - [pre_complete_bits(NumBits, - ((((((A bsl 8)+B) bsl 8)+C) bsl 8)+D)-Min)| - chars_encode2(T,NumBits,T1)]; -chars_encode2([H={A,B,C,D}|T],NumBits,{Min,Max,Tab}) -> - %% no value range check here (ought to be, but very expensive) - [pre_complete_bits(NumBits,exit_if_false(H,element(((((((A bsl 8)+B) bsl 8)+C) bsl 8)+D)-Min,Tab)))|chars_encode2(T,NumBits,{Min,Max,notab})]; -chars_encode2([H|_T],_NumBits,{_Min,_Max,_Tab}) -> - exit({error,{asn1,{illegal_char_value,H}}}); -chars_encode2([],_,_) -> - []. - -exit_if_false(V,false)-> - exit({error,{asn1,{"illegal value according to Permitted alphabet constraint",V}}}); -exit_if_false(_,V) ->V. - -pre_complete_bits(NumBits,Val) when NumBits =< 8 -> - [10,NumBits,Val]; -pre_complete_bits(NumBits,Val) when NumBits =< 16 -> - [10,NumBits-8,Val bsr 8,10,8,(Val band 255)]; -pre_complete_bits(NumBits,Val) when NumBits =< 2040 -> % 255 * 8 - Unused = (8 - (NumBits rem 8)) rem 8, - Len = NumBits + Unused, - [30,Unused,Len div 8,<<(Val bsl Unused):Len>>]. - - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% encode_UTF8String(Val) -> CompleteList -%% Val -> <<utf8encoded binary>> -%% CompleteList -> [apropriate codes and values for driver complete] -%% -encode_UTF8String(Val) when is_binary(Val) -> - Sz = byte_size(Val), - [encode_length(Sz),octets_to_complete(Sz, Val)]; -encode_UTF8String(Val) -> - encode_UTF8String(list_to_binary(Val)). - - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% encode_object_identifier(Val) -> CompleteList -%% encode_object_identifier({Name,Val}) -> CompleteList -%% Val -> {Int1,Int2,...,IntN} % N >= 2 -%% Name -> atom() -%% Int1 -> integer(0..2) -%% Int2 -> integer(0..39) when Int1 (0..1) else integer() -%% Int3-N -> integer() -%% CompleteList -> [{bits,8,Val}|{octets,Ol}|align|...] -%% -encode_object_identifier(Val) -> - OctetList = e_object_identifier(Val), - Octets = list_to_binary(OctetList), - Sz = byte_size(Octets), - [encode_length(Sz), - octets_to_complete(Sz, Octets)]. - -e_object_identifier({'OBJECT IDENTIFIER',V}) -> - e_object_identifier(V); -e_object_identifier(V) when is_tuple(V) -> - e_object_identifier(tuple_to_list(V)); - -%% E1 = 0|1|2 and (E2 < 40 when E1 = 0|1) -e_object_identifier([E1,E2|Tail]) when E1 >= 0, E1 < 2, E2 < 40 ; E1==2 -> - Head = 40*E1 + E2, % weird - e_object_elements([Head|Tail],[]); -e_object_identifier(Oid=[_,_|_Tail]) -> - exit({error,{asn1,{'illegal_value',Oid}}}). - -e_object_elements([],Acc) -> - lists:reverse(Acc); -e_object_elements([H|T],Acc) -> - e_object_elements(T,[e_object_element(H)|Acc]). - -e_object_element(Num) when Num < 128 -> - [Num]; -e_object_element(Num) -> - [e_o_e(Num bsr 7)|[Num band 2#1111111]]. -e_o_e(Num) when Num < 128 -> - Num bor 2#10000000; -e_o_e(Num) -> - [e_o_e(Num bsr 7)|[(Num band 2#1111111) bor 2#10000000]]. - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% encode_relative_oid(Val) -> CompleteList -%% encode_relative_oid({Name,Val}) -> CompleteList -encode_relative_oid(Val) when is_tuple(Val) -> - encode_relative_oid(tuple_to_list(Val)); -encode_relative_oid(Val) when is_list(Val) -> - Octets = list_to_binary([e_object_element(X)||X <- Val]), - Sz = byte_size(Octets), - [encode_length(Sz)|octets_to_complete(Sz, Octets)]. - %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% complete(InList) -> ByteList %% Takes a coded list with bits and bytes and converts it to a list of bytes %% Should be applied as the last step at encode of a complete ASN.1 type %% -complete(L) -> - case asn1rt_nif:encode_per_complete(L) of +complete(L0) -> + L = complete(L0, []), + case list_to_bitstring(L) of <<>> -> <<0>>; Bin -> Bin end. -octets_to_complete(Len,Val) when Len < 256 -> - [20,Len,Val]; -octets_to_complete(Len,Val) -> - [21,<<Len:16>>,Val]. - -octets_unused_to_complete(Unused,Len,Val) when Len < 256 -> - [30,Unused,Len,Val]; -octets_unused_to_complete(Unused,Len,Val) -> - [31,Unused,<<Len:16>>,Val]. +complete([], []) -> + []; +complete([], [H|More]) -> + complete(H, More); +complete([align|T], More) -> + complete(T, More); +complete([[]|T], More) -> + complete(T, More); +complete([[_|_]=H], More) -> + complete(H, More); +complete([[_|_]=H|T], More) -> + complete(H, [T|More]); +complete([H|T], More) when is_integer(H); is_binary(H) -> + [H|complete(T, More)]; +complete([H|T], More) -> + [H|complete(T, bit_size(H), More)]; +complete(Bin, More) when is_binary(Bin) -> + [Bin|complete([], More)]; +complete(Bin, More) -> + [Bin|complete([], bit_size(Bin), More)]. + +complete([], Bits, []) -> + case Bits band 7 of + 0 -> []; + N -> [<<0:(8-N)>>] + end; +complete([], Bits, [H|More]) -> + complete(H, Bits, More); +complete([align|T], Bits, More) -> + case Bits band 7 of + 0 -> complete(T, More); + 1 -> [<<0:7>>|complete(T, More)]; + 2 -> [<<0:6>>|complete(T, More)]; + 3 -> [<<0:5>>|complete(T, More)]; + 4 -> [<<0:4>>|complete(T, More)]; + 5 -> [<<0:3>>|complete(T, More)]; + 6 -> [<<0:2>>|complete(T, More)]; + 7 -> [<<0:1>>|complete(T, More)] + end; +complete([[]|T], Bits, More) -> + complete(T, Bits, More); +complete([[_|_]=H], Bits, More) -> + complete(H, Bits, More); +complete([[_|_]=H|T], Bits, More) -> + complete(H, Bits, [T|More]); +complete([H|T], Bits, More) when is_integer(H); + is_binary(H) -> + [H|complete(T, Bits, More)]; +complete([H|T], Bits, More) -> + [H|complete(T, Bits+bit_size(H), More)]; +complete(Bin, Bits, More) when is_binary(Bin) -> + [Bin|complete([], Bits, More)]; +complete(Bin, Bits, More) -> + [Bin|complete([], Bits+bit_size(Bin), More)]. diff --git a/lib/asn1/src/asn1rtt_per_common.erl b/lib/asn1/src/asn1rtt_per_common.erl index e7edc2b65f..9e9fd87ec3 100644 --- a/lib/asn1/src/asn1rtt_per_common.erl +++ b/lib/asn1/src/asn1rtt_per_common.erl @@ -28,7 +28,16 @@ decode_chars/2,decode_chars/3, decode_chars_16bit/1, decode_big_chars/2, - decode_oid/1,decode_relative_oid/1]). + decode_oid/1,decode_relative_oid/1, + encode_chars/2,encode_chars/3, + encode_chars_16bit/1,encode_big_chars/1, + encode_fragmented/2, + encode_oid/1,encode_relative_oid/1, + encode_unconstrained_number/1, + bitstring_from_positions/1,bitstring_from_positions/2, + to_bitstring/1,to_bitstring/2, + to_named_bitstring/1,to_named_bitstring/2, + extension_bitmap/3]). -define('16K',16384). @@ -90,6 +99,182 @@ decode_oid(Octets) -> decode_relative_oid(Octets) -> list_to_tuple(dec_subidentifiers(Octets, 0, [])). +encode_chars(Val, NumBits) -> + << <<C:NumBits>> || C <- Val >>. + +encode_chars(Val, NumBits, {Lb,Tab}) -> + << <<(enc_char(C, Lb, Tab)):NumBits>> || C <- Val >>. + +encode_chars_16bit(Val) -> + L = [case C of + {0,0,A,B} -> [A,B]; + C when is_integer(C) -> [0,C] + end || C <- Val], + iolist_to_binary(L). + +encode_big_chars(Val) -> + L = [case C of + {_,_,_,_} -> tuple_to_list(C); + C when is_integer(C) -> [<<0,0,0>>,C] + end || C <- Val], + iolist_to_binary(L). + +encode_fragmented(Bin, Unit) -> + encode_fragmented_1(Bin, Unit, 4). + +encode_oid(Val) when is_tuple(Val) -> + encode_oid(tuple_to_list(Val)); +encode_oid(Val) -> + iolist_to_binary(e_object_identifier(Val)). + +encode_relative_oid(Val) when is_tuple(Val) -> + encode_relative_oid(tuple_to_list(Val)); +encode_relative_oid(Val) when is_list(Val) -> + list_to_binary([e_object_element(X)||X <- Val]). + +encode_unconstrained_number(Val) when Val >= 0 -> + if + Val < 16#80 -> + [1,Val]; + Val < 16#100 -> + [<<2,0>>,Val]; + true -> + case binary:encode_unsigned(Val) of + <<0:1,_/bitstring>>=Bin -> + case byte_size(Bin) of + Sz when Sz < 128 -> + [Sz,Bin]; + Sz when Sz < 16384 -> + [<<2:2,Sz:14>>,Bin] + end; + <<1:1,_/bitstring>>=Bin -> + case byte_size(Bin)+1 of + Sz when Sz < 128 -> + [Sz,0,Bin]; + Sz when Sz < 16384 -> + [<<2:2,Sz:14,0:8>>,Bin] + end + end + end; +encode_unconstrained_number(Val) -> + Oct = enint(Val, []), + Len = length(Oct), + if + Len < 128 -> + [Len|Oct]; + Len < 16384 -> + [<<2:2,Len:14>>|Oct] + end. + +%% bitstring_from_positions([Position]) -> BitString +%% Given an unsorted list of bit positions (0..MAX), construct +%% a BIT STRING. The rightmost bit will always be a one. + +bitstring_from_positions([]) -> <<>>; +bitstring_from_positions([_|_]=L0) -> + L1 = lists:sort(L0), + L = diff(L1, -1), + << <<1:(N+0)>> || N <- L >>. + +%% bitstring_from_positions([Position], Lb) -> BitString +%% Given an unsorted list of bit positions (0..MAX) and a lower bound +%% for the number of bits, construct BIT STRING (zero-padded on the +%% right side if needed). + +bitstring_from_positions(L0, Lb) -> + L1 = lists:sort(L0), + L = diff(L1, -1, Lb-1), + << <<B:(N+0)>> || {B,N} <- L >>. + +%% to_bitstring(Val) -> BitString +%% Val = BitString | {Unused,Binary} | [OneOrZero] | Integer +%% Given one of the possible representations for a BIT STRING, +%% return a bitstring (without adding or removing any zero bits +%% at the right end). + +to_bitstring({0,Bs}) when is_binary(Bs) -> + Bs; +to_bitstring({Unused,Bs0}) when is_binary(Bs0) -> + Sz = bit_size(Bs0) - Unused, + <<Bs:Sz/bits,_/bits>> = Bs0, + Bs; +to_bitstring(Bs) when is_bitstring(Bs) -> + Bs; +to_bitstring(Int) when is_integer(Int), Int >= 0 -> + L = int_to_bitlist(Int), + << <<B:1>> || B <- L >>; +to_bitstring(L) when is_list(L) -> + << <<B:1>> || B <- L >>. + +%% to_bitstring(Val, Lb) -> BitString +%% Val = BitString | {Unused,Binary} | [OneOrZero] | Integer +%% Lb = Integer +%% Given one of the possible representations for a BIT STRING +%% and the lower bound for the number of bits, +%% return a bitstring at least Lb bits long (padded with zeroes +%% if needed). + +to_bitstring({0,Bs}, Lb) when is_binary(Bs) -> + case bit_size(Bs) of + Sz when Sz < Lb -> + <<Bs/bits,0:(Lb-Sz)>>; + _ -> + Bs + end; +to_bitstring({Unused,Bs0}, Lb) when is_binary(Bs0) -> + Sz = bit_size(Bs0) - Unused, + if + Sz < Lb -> + <<Bs0:Sz/bits,0:(Lb-Sz)>>; + true -> + <<Bs:Sz/bits,_/bits>> = Bs0, + Bs + end; +to_bitstring(Bs, Lb) when is_bitstring(Bs) -> + adjust_size(Bs, Lb); +to_bitstring(Int, Lb) when is_integer(Int), Int >= 0 -> + L = int_to_bitlist(Int), + Bs = << <<B:1>> || B <- L >>, + adjust_size(Bs, Lb); +to_bitstring(L, Lb) when is_list(L) -> + Bs = << <<B:1>> || B <- L >>, + adjust_size(Bs, Lb). + +%% to_named_bitstring(Val) -> BitString +%% Val = BitString | {Unused,Binary} | [OneOrZero] | Integer +%% Given one of the possible representations for a BIT STRING, +%% return a bitstring where any trailing zeroes have been stripped. + +to_named_bitstring(Val) -> + Bs = to_bitstring(Val), + bs_drop_trailing_zeroes(Bs). + +%% to_named_bitstring(Val, Lb) -> BitString +%% Val = BitString | {Unused,Binary} | [OneOrZero] | Integer +%% Lb = Integer +%% Given one of the possible representations for a BIT STRING +%% and the lower bound for the number of bits, +%% return a bitstring that is at least Lb bits long. There will +%% be zeroes at the right only if needed to reach the lower bound +%% for the number of bits. + +to_named_bitstring({0,Bs}, Lb) when is_binary(Bs) -> + adjust_trailing_zeroes(Bs, Lb); +to_named_bitstring({Unused,Bs0}, Lb) when is_binary(Bs0) -> + Sz = bit_size(Bs0) - Unused, + <<Bs:Sz/bits,_/bits>> = Bs0, + adjust_trailing_zeroes(Bs, Lb); +to_named_bitstring(Bs, Lb) when is_bitstring(Bs) -> + adjust_trailing_zeroes(Bs, Lb); +to_named_bitstring(Val, Lb) -> + %% Obsolete representations: list or integer. Optimize + %% for correctness, not speed. + adjust_trailing_zeroes(to_bitstring(Val), Lb). + + +extension_bitmap(Val, Pos, Limit) -> + extension_bitmap(Val, Pos, Limit, 0). + %%% %%% Internal functions. %%% @@ -124,3 +309,149 @@ dec_subidentifiers([H|T], Av, Al) -> dec_subidentifiers(T, 0, [(Av bsl 7) bor H|Al]); dec_subidentifiers([], _Av, Al) -> lists:reverse(Al). + +enc_char(C0, Lb, Tab) -> + try element(C0-Lb, Tab) of + ill -> + illegal_char_error(); + C -> + C + catch + error:badarg -> + illegal_char_error() + end. + +illegal_char_error() -> + error({error,{asn1,"value forbidden by FROM constraint"}}). + +encode_fragmented_1(Bin, Unit, N) -> + SegSz = Unit * N * ?'16K', + case Bin of + <<B:SegSz/bitstring,T/bitstring>> -> + [<<3:2,N:6>>,B|encode_fragmented_1(T, Unit, N)]; + _ when N > 1 -> + encode_fragmented_1(Bin, Unit, N-1); + _ -> + case bit_size(Bin) div Unit of + Len when Len < 128 -> + [Len,Bin]; + Len when Len < 16384 -> + [<<2:2,Len:14>>,Bin] + end + end. + +%% E1 = 0|1|2 and (E2 < 40 when E1 = 0|1) +e_object_identifier([E1,E2|Tail]) when E1 >= 0, E1 < 2, E2 < 40; E1 =:= 2 -> + Head = 40*E1 + E2, + e_object_elements([Head|Tail], []); +e_object_identifier([_,_|_Tail]=Oid) -> + exit({error,{asn1,{'illegal_value',Oid}}}). + +e_object_elements([], Acc) -> + lists:reverse(Acc); +e_object_elements([H|T], Acc) -> + e_object_elements(T, [e_object_element(H)|Acc]). + +e_object_element(Num) when Num < 128 -> + [Num]; +e_object_element(Num) -> + [e_o_e(Num bsr 7)|[Num band 2#1111111]]. + +e_o_e(Num) when Num < 128 -> + Num bor 2#10000000; +e_o_e(Num) -> + [e_o_e(Num bsr 7)|[(Num band 2#1111111) bor 2#10000000]]. + +enint(-1, [B1|T]) when B1 > 127 -> + [B1|T]; +enint(N, Acc) -> + enint(N bsr 8, [N band 16#ff|Acc]). + +diff([H|T], Prev) -> + [H-Prev|diff(T, H)]; +diff([], _) -> []. + +diff([H|T], Prev, Last) -> + [{1,H-Prev}|diff(T, H, Last)]; +diff([], Prev, Last) when Last >= Prev -> + [{0,Last-Prev}]; +diff([], _, _) -> []. + +int_to_bitlist(0) -> []; +int_to_bitlist(Int) -> [Int band 1|int_to_bitlist(Int bsr 1)]. + +adjust_size(Bs, Lb) -> + case bit_size(Bs) of + Sz when Sz < Lb -> + <<Bs:Sz/bits,0:(Lb-Sz)>>; + _ -> + Bs + end. + +adjust_trailing_zeroes(Bs0, Lb) -> + case bit_size(Bs0) of + Sz when Sz < Lb -> + %% Too short - pad with zeroes. + <<Bs0:Sz/bits,0:(Lb-Sz)>>; + Lb -> + %% Exactly the right size - nothing to do. + Bs0; + _ -> + %% Longer than the lower bound - drop trailing zeroes. + <<_:Lb/bits,Tail/bits>> = Bs0, + Sz = Lb + bit_size(bs_drop_trailing_zeroes(Tail)), + <<Bs:Sz/bits,_/bits>> = Bs0, + Bs + end. + +bs_drop_trailing_zeroes(Bs) -> + bs_drop_trailing_zeroes(Bs, bit_size(Bs)). + +bs_drop_trailing_zeroes(Bs0, Sz0) when Sz0 < 8 -> + <<Byte:Sz0>> = Bs0, + Sz = Sz0 - ntz(Byte), + <<Bs:Sz/bits,_/bits>> = Bs0, + Bs; +bs_drop_trailing_zeroes(Bs0, Sz0) -> + Sz1 = Sz0 - 8, + <<Bs1:Sz1/bits,Byte:8>> = Bs0, + case ntz(Byte) of + 8 -> + bs_drop_trailing_zeroes(Bs1, Sz1); + Ntz -> + Sz = Sz0 - Ntz, + <<Bs:Sz/bits,_:Ntz/bits>> = Bs0, + Bs + end. + +%% ntz(Byte) -> Number of trailing zeroes. +ntz(Byte) -> + %% The table was calculated like this: + %% NTZ = fun (B, N, NTZ) when B band 1 =:= 0 -> NTZ(B bsr 1, N+1, NTZ); (_, N, _) -> N end. + %% io:format("~w\n", [list_to_tuple([NTZ(B+256, 0, NTZ) || B <- lists:seq(0, 255)])]). + T = {8,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0, + 4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0, + 5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0, + 4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0, + 6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0, + 4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0, + 5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0, + 4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0, + 7,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0, + 4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0, + 5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0, + 4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0, + 6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0, + 4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0, + 5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0, + 4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0}, + element(Byte+1, T). + +extension_bitmap(_Val, Pos, Limit, Acc) when Pos >= Limit -> + Acc; +extension_bitmap(Val, Pos, Limit, Acc) -> + Bit = case element(Pos, Val) of + asn1_NOVALUE -> 0; + _ -> 1 + end, + extension_bitmap(Val, Pos+1, Limit, (Acc bsl 1) bor Bit). diff --git a/lib/asn1/src/asn1rtt_real_common.erl b/lib/asn1/src/asn1rtt_real_common.erl index 22a1f4c4dd..12ca165ecd 100644 --- a/lib/asn1/src/asn1rtt_real_common.erl +++ b/lib/asn1/src/asn1rtt_real_common.erl @@ -105,8 +105,7 @@ encode_real(_C, {Mantissa, Base, Exponent}) when Base =:= 2 -> true -> list_to_binary(real_mininum_octets(-(Man))) % signbit keeps track of sign end, %% ok = io:format("LenMask: ~w EOctets: ~w~nFirstOctet: ~w OctMantissa: ~w OctExpLen: ~w~n", [LenMask, EOctets, FirstOctet, OctMantissa, OctExpLen]), - Bin = <<FirstOctet/binary, EOctets/binary, OctMantissa/binary>>, - {Bin, size(Bin)}; + <<FirstOctet/binary, EOctets/binary, OctMantissa/binary>>; encode_real(C, {Mantissa,Base,Exponent}) when Base =:= 10, is_integer(Mantissa), is_integer(Exponent) -> %% always encode as NR3 due to DER on the format @@ -176,8 +175,7 @@ encode_real_as_string(_C, Mantissa, Exponent) end, ManBin = list_to_binary(TruncMant), NR3 = 3, - {<<NR3,ManBin/binary,$.,ExpBin/binary>>, - 2 + byte_size(ManBin) + byte_size(ExpBin)}. + <<NR3,ManBin/binary,$.,ExpBin/binary>>. remove_trailing_zeros(IntStr) -> case lists:dropwhile(fun($0)-> true; diff --git a/lib/asn1/src/asn1rtt_uper.erl b/lib/asn1/src/asn1rtt_uper.erl index a5035c6660..68a89c70e1 100644 --- a/lib/asn1/src/asn1rtt_uper.erl +++ b/lib/asn1/src/asn1rtt_uper.erl @@ -19,95 +19,8 @@ %% -module(asn1rtt_uper). --export([setext/1, fixoptionals/3, - fixextensions/2, - skipextensions/3]). --export([set_choice/3, encode_integer/2, encode_integer/3]). --export([encode_small_number/1, encode_constrained_number/2, - encode_boolean/1, - encode_length/1, encode_length/2, - encode_bit_string/3]). --export([encode_octet_string/1,encode_octet_string/2, - encode_relative_oid/1, - encode_object_identifier/1, - complete/1, complete_NFP/1]). - - -export([encode_open_type/1]). - - -export([encode_UniversalString/3, - encode_PrintableString/3, - encode_GeneralString/2, - encode_GraphicString/2, - encode_TeletexString/2, - encode_VideotexString/2, - encode_VisibleString/3, - encode_UTF8String/1, - encode_BMPString/3, - encode_IA5String/3, - encode_NumericString/3, - encode_ObjectDescriptor/2 - ]). - --define('16K',16384). --define('32K',32768). --define('64K',65536). - - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% setext(true|false) -> CompleteList -%% - -setext(false) -> - <<0:1>>; -setext(true) -> - <<1:1>>. - - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% This is the new fixoptionals/3 which is used by the new generates -%% -fixoptionals(OptList,OptLength,Val) when is_tuple(Val) -> - Bits = fixoptionals(OptList,Val,0), - {Val,<<Bits:OptLength>>}; - -fixoptionals([],_Val,Acc) -> - %% Optbits - Acc; -fixoptionals([{Pos,DefVal}|Ot],Val,Acc) -> - case element(Pos,Val) of - asn1_DEFAULT -> fixoptionals(Ot,Val,Acc bsl 1); - DefVal -> fixoptionals(Ot,Val,Acc bsl 1); - _ -> fixoptionals(Ot,Val,(Acc bsl 1) + 1) - end; -fixoptionals([Pos|Ot],Val,Acc) -> - case element(Pos,Val) of - asn1_NOVALUE -> fixoptionals(Ot,Val,Acc bsl 1); - asn1_DEFAULT -> fixoptionals(Ot,Val,Acc bsl 1); - _ -> fixoptionals(Ot,Val,(Acc bsl 1) + 1) - end. - - -fixextensions({ext,ExtPos,ExtNum},Val) -> - case fixextensions(ExtPos,ExtNum+ExtPos,Val,0) of - 0 -> []; - ExtBits -> - [encode_small_length(ExtNum),<<ExtBits:ExtNum>>] - end. - -fixextensions(Pos,MaxPos,_,Acc) when Pos >= MaxPos -> - Acc; -fixextensions(Pos,ExtPos,Val,Acc) -> - Bit = case catch(element(Pos+1,Val)) of - asn1_NOVALUE -> - 0; - asn1_NOEXTVALUE -> - 0; - {'EXIT',_} -> - 0; - _ -> - 1 - end, - fixextensions(Pos+1,ExtPos,Val,(Acc bsl 1)+Bit). +-export([skipextensions/3]). +-export([complete/1, complete_NFP/1]). skipextensions(Bytes0, Nr, ExtensionBitstr) when is_bitstring(ExtensionBitstr) -> Prev = Nr - 1, @@ -122,249 +35,6 @@ skipextensions(Bytes0, Nr, ExtensionBitstr) when is_bitstring(ExtensionBitstr) - Bytes0 end. - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% set_choice(Alt,Choices,Altnum) -> ListofBitSettings -%% Alt = atom() -%% Altnum = integer() | {integer(),integer()}% number of alternatives -%% Choices = [atom()] | {[atom()],[atom()]} -%% When Choices is a tuple the first list is the Rootset and the -%% second is the Extensions and then Altnum must also be a tuple with the -%% lengths of the 2 lists -%% -set_choice(Alt, {L1,L2}, {Len1,_Len2}) -> - case set_choice_tag(Alt, L1) of - N when is_integer(N), Len1 > 1 -> - [<<0:1>>, % the value is in the root set - encode_integer([{'ValueRange',{0,Len1-1}}],N)]; - N when is_integer(N) -> - <<0:1>>; % no encoding if only 0 or 1 alternative - false -> - [<<1:1>>, % extension value - case set_choice_tag(Alt,L2) of - N2 when is_integer(N2) -> - encode_small_number(N2); - false -> - unknown_choice_alt - end] - end; -set_choice(Alt,L,Len) -> - case set_choice_tag(Alt,L) of - N when is_integer(N), Len > 1 -> - encode_integer([{'ValueRange',{0,Len-1}}],N); - N when is_integer(N) -> - []; % no encoding if only 0 or 1 alternative - false -> - [unknown_choice_alt] - end. - -set_choice_tag(Alt,Choices) -> - set_choice_tag(Alt,Choices,0). - -set_choice_tag(Alt,[Alt|_Rest],Tag) -> - Tag; -set_choice_tag(Alt,[_H|Rest],Tag) -> - set_choice_tag(Alt,Rest,Tag+1); -set_choice_tag(_Alt,[],_Tag) -> - false. - - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% encode_open_type(Constraint, Value) -> CompleteList -%% Value = list of bytes of an already encoded value (the list must be flat) -%% | binary -%% Contraint = not used in this version -%% -encode_open_type(Val) -> - [encode_length(byte_size(Val)),Val]. - - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% encode_integer(Constraint,Value,NamedNumberList) -> CompleteList -%% encode_integer(Constraint,Value) -> CompleteList -%% encode_integer(Constraint,{Name,Value}) -> CompleteList -%% -%% -encode_integer(C, V, NamedNumberList) when is_atom(V) -> - case lists:keyfind(V, 1, NamedNumberList) of - {_,NewV} -> - encode_integer(C, NewV); - false -> - exit({error,{asn1,{namednumber,V}}}) - end; -encode_integer(C, V, _NamedNumberList) when is_integer(V) -> - encode_integer(C, V). - -encode_integer([{Rc,_Ec}],Val) when is_tuple(Rc) -> - try - [<<0:1>>,encode_integer([Rc], Val)] - catch - _:{error,{asn1,_}} -> - [<<1:1>>,encode_unconstrained_number(Val)] - end; -encode_integer(C, Val) when is_list(C) -> - case get_constraint(C, 'SingleValue') of - no -> - encode_integer1(C,Val); - V when is_integer(V), V =:= Val -> - []; % a type restricted to a single value encodes to nothing - V when is_list(V) -> - case lists:member(Val,V) of - true -> - encode_integer1(C,Val); - _ -> - exit({error,{asn1,{illegal_value,Val}}}) - end; - _ -> - exit({error,{asn1,{illegal_value,Val}}}) - end. - -encode_integer1(C, Val) -> - case VR = get_constraint(C, 'ValueRange') of - no -> - encode_unconstrained_number(Val); - {Lb,'MAX'} when Lb =< Val -> - encode_semi_constrained_number(Lb, Val); - %% positive with range - {Lb,Ub} when Val >= Lb, Ub >= Val -> - encode_constrained_number(VR,Val); - _ -> - exit({error,{asn1,{illegal_value,VR,Val}}}) - end. - -%% X.691:10.6 Encoding of a normally small non-negative whole number -%% Use this for encoding of CHOICE index if there is an extension marker in -%% the CHOICE -encode_small_number(Val) when Val < 64 -> - <<Val:7>>; -encode_small_number(Val) -> - [<<1:1>>|encode_semi_constrained_number(0, Val)]. - -%% X.691:10.7 Encoding of a semi-constrained whole number -encode_semi_constrained_number(Lb, Val) -> - %% encoding in minimum number of octets preceeded by a length - Val2 = Val - Lb, - Bin = eint_bin_positive(Val2), - Size = byte_size(Bin), - if - Size < 128 -> - [<<Size>>,Bin]; - Size < 16384 -> - [<<2:2,Size:14>>,Bin]; - true -> - [encode_length(Size),Bin] - end. - -encode_constrained_number({Lb,Ub}, Val) when Val >= Lb, Ub >= Val -> - Range = Ub - Lb + 1, - Val2 = Val - Lb, - NumBits = num_bits(Range), - <<Val2:NumBits>>; -encode_constrained_number(Range,Val) -> - exit({error,{asn1,{integer_range,Range,value,Val}}}). - -%% X.691:10.8 Encoding of an unconstrained whole number - -encode_unconstrained_number(Val) when Val >= 0 -> - Oct = eint_bin_2Cs(Val), - Len = byte_size(Oct), - if - Len < 128 -> - [<<Len>>,Oct]; % equiv with encode_length(undefined,Len) but faster - Len < 16384 -> - [<<2:2,Len:14>>,Oct]; - true -> - [encode_length(Len),<<Len:16>>,Oct] - end; -encode_unconstrained_number(Val) -> % negative - Oct = enint(Val,[]), - Len = byte_size(Oct), - if - Len < 128 -> - [<<Len>>,Oct]; % equiv with encode_length(undefined,Len) but faster - Len < 16384 -> - [<<2:2,Len:14>>,Oct]; - true -> - [encode_length(Len),Oct] - end. - - -eint_bin_2Cs(Int) -> - case eint_bin_positive(Int) of - <<B,_/binary>> = Bin when B > 16#7f -> - <<0,Bin/binary>>; - Bin -> Bin - end. - -%% returns the integer as a binary -eint_bin_positive(Val) when Val < 16#100 -> - <<Val>>; -eint_bin_positive(Val) when Val < 16#10000 -> - <<Val:16>>; -eint_bin_positive(Val) when Val < 16#1000000 -> - <<Val:24>>; -eint_bin_positive(Val) when Val < 16#100000000 -> - <<Val:32>>; -eint_bin_positive(Val) -> - list_to_binary([eint_bin_positive2(Val bsr 32),<<Val:32>>]). - -eint_bin_positive2(Val) when Val < 16#100 -> - <<Val>>; -eint_bin_positive2(Val) when Val < 16#10000 -> - <<Val:16>>; -eint_bin_positive2(Val) when Val < 16#1000000 -> - <<Val:24>>; -eint_bin_positive2(Val) when Val < 16#100000000 -> - <<Val:32>>; -eint_bin_positive2(Val) -> - [eint_bin_positive2(Val bsr 32),<<Val:32>>]. - - - - -enint(-1, [B1|T]) when B1 > 127 -> - list_to_binary([B1|T]); -enint(N, Acc) -> - enint(N bsr 8, [N band 16#ff|Acc]). - - -%% X.691:10.9 Encoding of a length determinant -%%encode_small_length(undefined,Len) -> % null means no UpperBound -%% encode_small_number(Len). - -%% X.691:10.9.3.5 -%% X.691:10.9.3.7 -encode_length(Len) -> % un-constrained - if - Len < 128 -> - <<Len>>; - Len < 16384 -> - <<2:2,Len:14>>; - true -> % should be able to endode length >= 16384 - error({error,{asn1,{encode_length,{nyi,above_16k}}}}) - end. - -encode_length({C,[]}, Len) -> - case C of - {Lb,Ub}=Vr when Lb =< Len, Len =< Ub -> - [<<0:1>>|encode_constrained_number(Vr, Len)]; - _ -> - [<<1:1>>|encode_length(Len)] - end; -encode_length(Len, Len) -> - []; -encode_length(Vr, Len) -> - encode_constrained_number(Vr, Len). - - -%% X.691 10.9.3.4 (only used for length of bitmap that prefixes extension -%% additions in a sequence or set -encode_small_length(Len) when Len =< 64 -> - <<(Len-1):7>>; -encode_small_length(Len) -> - [<<1:1>>,encode_length(Len)]. - - %% un-constrained decode_length(<<0:1,Oct:7,Rest/bitstring>>) -> {Oct,Rest}; @@ -373,575 +43,20 @@ decode_length(<<2:2,Val:14,Rest/bitstring>>) -> decode_length(<<3:2,_:14,_Rest/bitstring>>) -> exit({error,{asn1,{decode_length,{nyi,above_16k}}}}). - % X.691:11 -encode_boolean(true) -> - <<1:1>>; -encode_boolean(false) -> - <<0:1>>; -encode_boolean(Val) -> - exit({error,{asn1,{encode_boolean,Val}}}). - - -%%============================================================================ -%%============================================================================ -%% Bitstring value, ITU_T X.690 Chapter 8.5 -%%============================================================================ -%%============================================================================ - -%%============================================================================ -%% encode bitstring value -%%============================================================================ - - - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% bitstring NamedBitList -%% Val can be of: -%% - [identifiers] where only named identifers are set to one, -%% the Constraint must then have some information of the -%% bitlength. -%% - [list of ones and zeroes] all bits -%% - integer value representing the bitlist -%% C is constraint Len, only valid when identifiers are present - - -%% when the value is a list of {Unused,BinBits}, where -%% Unused = integer(), -%% BinBits = binary(). - -encode_bit_string(C, Bits, NamedBitList) when is_bitstring(Bits) -> - PadLen = (8 - (bit_size(Bits) band 7)) band 7, - Compact = {PadLen,<<Bits/bitstring,0:PadLen>>}, - encode_bit_string(C, Compact, NamedBitList); -encode_bit_string(C, {Unused,BinBits}=Bin, NamedBitList) - when is_integer(Unused), is_binary(BinBits) -> - encode_bin_bit_string(C, Bin, NamedBitList); - -encode_bit_string(C, BitListVal, NamedBitList) -> - encode_bit_string1(C, BitListVal, NamedBitList). - -%% when the value is a list of named bits -encode_bit_string1(C, [FirstVal|_RestVal]=LoNB, NamedBitList) - when is_atom(FirstVal) -> - ToSetPos = get_all_bitposes(LoNB, NamedBitList, []), - BitList = make_and_set_list(ToSetPos, 0), - encode_bit_string1(C, BitList, NamedBitList); -encode_bit_string1(C, [{bit,_No}|_RestVal]=BL, NamedBitList) -> - ToSetPos = get_all_bitposes(BL, NamedBitList, []), - BitList = make_and_set_list(ToSetPos, 0), - encode_bit_string1(C, BitList, NamedBitList); -%% when the value is a list of ones and zeroes -encode_bit_string1(Int, BitListValue, _) - when is_list(BitListValue), is_integer(Int) -> - %% The type is constrained by a single value size constraint - bit_list2bitstr(Int, BitListValue); -encode_bit_string1(no, BitListValue, []) - when is_list(BitListValue) -> - Len = length(BitListValue), - [encode_length(Len),bit_list2bitstr(Len,BitListValue)]; -encode_bit_string1(C, BitListValue,[]) - when is_list(BitListValue) -> - Len = length(BitListValue), - [encode_length(C, Len),bit_list2bitstr(Len,BitListValue)]; -encode_bit_string1(no, BitListValue,_NamedBitList) - when is_list(BitListValue) -> - NewBitLVal = lists:reverse(lists:dropwhile(fun(0)->true;(1)->false end, - lists:reverse(BitListValue))), - Len = length(NewBitLVal), - [encode_length(Len),bit_list2bitstr(Len,NewBitLVal)]; -encode_bit_string1(C, BitListValue, _NamedBitList) - when is_list(BitListValue) ->% C = {_,'MAX'} - NewBitStr = bitstr_trailing_zeros(BitListValue, C), - [encode_length(C, bit_size(NewBitStr)),NewBitStr]; - - -%% when the value is an integer -encode_bit_string1(C, IntegerVal, NamedBitList) when is_integer(IntegerVal)-> - BitList = int_to_bitlist(IntegerVal), - encode_bit_string1(C, BitList, NamedBitList). - -bit_list2bitstr(Len,BitListValue) -> - case length(BitListValue) of - Len -> - << <<B:1>> || B <- BitListValue>>; - L when L > Len -> % truncate - <<(<< <<B:1>> || B <- BitListValue>>):Len/bitstring>>; - L -> % Len > L -> pad - <<(<< <<B:1>> || B <- BitListValue>>)/bitstring,0:(Len-L)>> - end. - -adjust_trailing_zeros(Len, Bin) when Len =:= bit_size(Bin) -> - Bin; -adjust_trailing_zeros(Len, Bin) when Len > bit_size(Bin) -> - <<Bin/bitstring,0:(Len-bit_size(Bin))>>; -adjust_trailing_zeros(Len,Bin) -> - <<Bin:Len/bitstring>>. - -bitstr_trailing_zeros(BitList, C) when is_integer(C) -> - bitstr_trailing_zeros1(BitList, C, C); -bitstr_trailing_zeros(BitList, {Lb,Ub}) when is_integer(Lb) -> - bitstr_trailing_zeros1(BitList,Lb,Ub); -bitstr_trailing_zeros(BitList, {{Lb,Ub},_}) when is_integer(Lb) -> - bitstr_trailing_zeros1(BitList, Lb, Ub); -bitstr_trailing_zeros(BitList, _) -> - bit_list2bitstr(length(BitList), BitList). - -bitstr_trailing_zeros1(BitList, Lb, Ub) -> - case length(BitList) of - Lb -> bit_list2bitstr(Lb, BitList); - B when B < Lb -> bit_list2bitstr(Lb, BitList); - D -> F = fun(L,LB,LB,_,_)->bit_list2bitstr(LB,lists:reverse(L)); - ([0|R],L1,LB,UB,Fun)->Fun(R,L1-1,LB,UB,Fun); - (L,L1,_,UB,_)when L1 =< UB -> - bit_list2bitstr(L1,lists:reverse(L)); - (_,_L1,_,_,_) ->exit({error,{list_length_BIT_STRING, - BitList}}) end, - F(lists:reverse(BitList),D,Lb,Ub,F) - end. - -%% encode_bin_bit_string/3, when value is a tuple of Unused and BinBits. -%% Unused = integer(),i.e. number unused bits in least sign. byte of -%% BinBits = binary(). -encode_bin_bit_string(C, {_,BinBits}, _NamedBitList) - when is_integer(C), C =< 16 -> - adjust_trailing_zeros(C, BinBits); -encode_bin_bit_string(C, {_Unused,BinBits}, _NamedBitList) - when is_integer(C) -> - adjust_trailing_zeros(C, BinBits); -encode_bin_bit_string(C, {_,_}=UnusedAndBin, NamedBitList) -> - %% removes all trailing bits if NamedBitList is not empty - BitStr = remove_trailing_bin(NamedBitList, UnusedAndBin), - case C of - {Lb,Ub} when is_integer(Lb),is_integer(Ub) -> - [encode_length({Lb,Ub},bit_size(BitStr)),BitStr]; - no -> - [encode_length(bit_size(BitStr)),BitStr]; - Sc -> - [encode_length(Sc,bit_size(BitStr)),BitStr] - end. - - -remove_trailing_bin([], {Unused,Bin}) -> - BS = bit_size(Bin)-Unused, - <<BitStr:BS/bitstring,_:Unused>> = Bin, - BitStr; -remove_trailing_bin(_NamedNumberList, {_Unused,<<>>}) -> - <<>>; -remove_trailing_bin(NamedNumberList, {_Unused,Bin}) -> - Size = byte_size(Bin)-1, - <<Bfront:Size/binary, LastByte:8>> = Bin, - - %% clear the Unused bits to be sure - Unused1 = trailingZeroesInNibble(LastByte band 15), - Unused2 = - case Unused1 of - 4 -> - 4 + trailingZeroesInNibble(LastByte bsr 4); - _ -> Unused1 - end, - case Unused2 of - 8 -> - remove_trailing_bin(NamedNumberList,{0,Bfront}); - _ -> - BS = bit_size(Bin) - Unused2, - <<BitStr:BS/bitstring,_:Unused2>> = Bin, - BitStr - end. - -trailingZeroesInNibble(0) -> - 4; -trailingZeroesInNibble(1) -> - 0; -trailingZeroesInNibble(2) -> - 1; -trailingZeroesInNibble(3) -> - 0; -trailingZeroesInNibble(4) -> - 2; -trailingZeroesInNibble(5) -> - 0; -trailingZeroesInNibble(6) -> - 1; -trailingZeroesInNibble(7) -> - 0; -trailingZeroesInNibble(8) -> - 3; -trailingZeroesInNibble(9) -> - 0; -trailingZeroesInNibble(10) -> - 1; -trailingZeroesInNibble(11) -> - 0; -trailingZeroesInNibble(12) -> %#1100 - 2; -trailingZeroesInNibble(13) -> - 0; -trailingZeroesInNibble(14) -> - 1; -trailingZeroesInNibble(15) -> - 0. - - -%%%%%%%%%%%%%%% -%% - -int_to_bitlist(Int) when is_integer(Int), Int > 0 -> - [Int band 1 | int_to_bitlist(Int bsr 1)]; -int_to_bitlist(0) -> - []. - - -%%%%%%%%%%%%%%%%%% -%% get_all_bitposes([list of named bits to set], named_bit_db, []) -> -%% [sorted_list_of_bitpositions_to_set] - -get_all_bitposes([{bit,ValPos}|Rest], NamedBitList, Ack) -> - get_all_bitposes(Rest, NamedBitList, [ValPos | Ack ]); - -get_all_bitposes([Val | Rest], NamedBitList, Ack) -> - case lists:keyfind(Val, 1, NamedBitList) of - {_ValName, ValPos} -> - get_all_bitposes(Rest, NamedBitList, [ValPos | Ack]); - false -> - exit({error,{asn1, {bitstring_namedbit, Val}}}) - end; -get_all_bitposes([], _NamedBitList, Ack) -> - lists:sort(Ack). - -%%%%%%%%%%%%%%%%%% -%% make_and_set_list([list of positions to set to 1])-> -%% returns list with all in SetPos set. -%% in positioning in list the first element is 0, the second 1 etc.., but -%% - -make_and_set_list([XPos|SetPos], XPos) -> - [1 | make_and_set_list(SetPos, XPos + 1)]; -make_and_set_list([Pos|SetPos], XPos) -> - [0 | make_and_set_list([Pos | SetPos], XPos + 1)]; -make_and_set_list([], _) -> - []. - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% X.691:16 -%% encode_octet_string(Val) -%% encode_octet_string(Constraint, Val) -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -encode_octet_string(Val) -> - try - [encode_length(length(Val)),list_to_binary(Val)] - catch - error:{error,{asn1,{encode_length,_}}} -> - encode_fragmented_octet_string(Val) - end. - -encode_octet_string(C, Val) -> - case C of - {_,_}=VR -> - try - [encode_length(VR, length(Val)),list_to_binary(Val)] - catch - error:{error,{asn1,{encode_length,_}}} -> - encode_fragmented_octet_string(Val) - end; - Sv when is_integer(Sv), Sv =:= length(Val) -> % fixed length - list_to_binary(Val) - end. - - -encode_fragmented_octet_string(Val) -> - Bin = list_to_binary(Val), - efos_1(Bin). - -efos_1(<<B:16#10000/binary,T/binary>>) -> - [<<3:2,4:6>>,B|efos_1(T)]; -efos_1(<<B:16#C000/binary,T/binary>>) -> - [<<3:2,3:6>>,B|efos_1(T)]; -efos_1(<<B:16#8000/binary,T/binary>>) -> - [<<3:2,2:6>>,B|efos_1(T)]; -efos_1(<<B:16#4000/binary,T/binary>>) -> - [<<3:2,1:6>>,B|efos_1(T)]; -efos_1(<<B/bitstring>>) -> - Len = byte_size(B), - [encode_length(Len),B]. - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% Restricted char string types -%% (NumericString, PrintableString,VisibleString,IA5String,BMPString,UniversalString) -%% X.691:26 and X.680:34-36 -%%encode_restricted_string('BMPString',Constraints,Extension,Val) - - -encode_restricted_string(Val) when is_list(Val)-> - [encode_length(length(Val)),list_to_binary(Val)]. - -encode_known_multiplier_string(StringType, C, Pa, Val) -> - Result = chars_encode(Pa, StringType, Val), - case C of - Ub when is_integer(Ub) -> - Result; - {_,_}=Range -> - [encode_length(Range, length(Val)),Result]; - no -> - [encode_length(length(Val)),Result] - end. - -encode_NumericString(C, Pa, Val) -> - encode_known_multiplier_string('NumericString', C, Pa, Val). - -encode_PrintableString(C, Pa, Val) -> - encode_known_multiplier_string('PrintableString', C, Pa, Val). - -encode_VisibleString(C, Pa, Val) -> % equivalent with ISO646String - encode_known_multiplier_string('VisibleString', C, Pa, Val). - -encode_IA5String(C, Pa, Val) -> - encode_known_multiplier_string('IA5String', C, Pa, Val). - -encode_BMPString(C, Pa, Val) -> - encode_known_multiplier_string('BMPString', C, Pa, Val). - -encode_UniversalString(C, Pa, Val) -> - encode_known_multiplier_string('UniversalString', C, Pa, Val). - - -%% end of known-multiplier strings for which PER visible constraints are -%% applied - -encode_GeneralString(_C,Val) -> - encode_restricted_string(Val). - -encode_GraphicString(_C,Val) -> - encode_restricted_string(Val). - -encode_ObjectDescriptor(_C,Val) -> - encode_restricted_string(Val). - -encode_TeletexString(_C,Val) -> % equivalent with T61String - encode_restricted_string(Val). - -encode_VideotexString(_C,Val) -> - encode_restricted_string(Val). - - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% chars_encode(C,StringType,Value) -> ValueList -%% -%% encodes chars according to the per rules taking the constraint PermittedAlphabet -%% into account. -%% This function does only encode the value part and NOT the length - -chars_encode(Pa, StringType, Value) -> - case {StringType,Pa} of - {'UniversalString',{_,_Sv}} -> - exit({error,{asn1,{'not implemented',"UniversalString with PermittedAlphabet constraint"}}}); - {'BMPString',{_,_Sv}} -> - exit({error,{asn1,{'not implemented',"BMPString with PermittedAlphabet constraint"}}}); - _ -> - {NumBits,CharOutTab} = {get_NumBits(Pa, StringType), - get_CharOutTab(Pa, StringType)}, - chars_encode2(Value,NumBits,CharOutTab) - end. - -chars_encode2([H|T],NumBits,{Min,Max,notab}) when H =< Max, H >= Min -> - [<<(H-Min):NumBits>>|chars_encode2(T,NumBits,{Min,Max,notab})]; -chars_encode2([H|T],NumBits,{Min,Max,Tab}) when H =< Max, H >= Min -> - Ch = exit_if_false(H,element(H-Min+1,Tab)), - [<<Ch:NumBits>>|chars_encode2(T,NumBits,{Min,Max,Tab})]; -chars_encode2([{A,B,C,D}|T],NumBits,{Min,Max,notab}) -> - %% no value range check here (ought to be, but very expensive) - Ch = ((((((A bsl 8)+B) bsl 8)+C) bsl 8)+D)-Min, - [<<Ch:NumBits>>|chars_encode2(T,NumBits,{Min,Max,notab})]; -chars_encode2([{A,B,C,D}|T],NumBits,{Min,Max,Tab}) -> - %% no value range check here (ought to be, but very expensive) - Ch = exit_if_false({A,B,C,D},element(((((((A bsl 8)+B) bsl 8)+C) bsl 8)+D)-Min,Tab)), - [<<Ch:NumBits>>|chars_encode2(T,NumBits,{Min,Max,notab})]; -chars_encode2([H|_T],_,{_,_,_}) -> - exit({error,{asn1,{illegal_char_value,H}}}); -chars_encode2([],_,_) -> - []. - -exit_if_false(V,false)-> - exit({error,{asn1,{"illegal value according to Permitted alphabet constraint",V}}}); -exit_if_false(_,V) ->V. - - -get_NumBits(Pa, StringType) -> - case Pa of - {'SingleValue',Sv} -> - charbits(length(Sv)); - no -> - case StringType of - 'IA5String' -> - charbits(128); % 16#00..16#7F - 'VisibleString' -> - charbits(95); % 16#20..16#7E - 'PrintableString' -> - charbits(74); % [$\s,$',$(,$),$+,$,,$-,$.,$/,"0123456789",$:,$=,$?,$A..$Z,$a..$z - 'NumericString' -> - charbits(11); % $ ,"0123456789" - 'UniversalString' -> - 32; - 'BMPString' -> - 16 - end - end. - -get_CharOutTab(Pa, StringType) -> - case Pa of - {'SingleValue',Sv} -> - get_CharTab2(Pa, StringType, hd(Sv), lists:max(Sv), Sv); - no -> - case StringType of - 'IA5String' -> - {0,16#7F,notab}; - 'VisibleString' -> - get_CharTab2(Pa, StringType, 16#20, 16#7F, notab); - 'PrintableString' -> - Chars = lists:sort( - " '()+,-./0123456789:=?ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"), - get_CharTab2(Pa, StringType, hd(Chars), - lists:max(Chars), Chars); - 'NumericString' -> - get_CharTab2(Pa, StringType, 16#20, $9, " 0123456789"); - 'UniversalString' -> - {0,16#FFFFFFFF,notab}; - 'BMPString' -> - {0,16#FFFF,notab} - end - end. - -get_CharTab2(C,StringType,Min,Max,Chars) -> - BitValMax = (1 bsl get_NumBits(C,StringType))-1, - if - Max =< BitValMax -> - {0,Max,notab}; - true -> - {Min,Max,create_char_tab(Min,Chars)} - end. - -create_char_tab(Min,L) -> - list_to_tuple(create_char_tab(Min,L,0)). -create_char_tab(Min,[Min|T],V) -> - [V|create_char_tab(Min+1,T,V+1)]; -create_char_tab(_Min,[],_V) -> - []; -create_char_tab(Min,L,V) -> - [false|create_char_tab(Min+1,L,V)]. - -%% See Table 20.3 in Dubuisson -charbits(NumOfChars) when NumOfChars =< 2 -> 1; -charbits(NumOfChars) when NumOfChars =< 4 -> 2; -charbits(NumOfChars) when NumOfChars =< 8 -> 3; -charbits(NumOfChars) when NumOfChars =< 16 -> 4; -charbits(NumOfChars) when NumOfChars =< 32 -> 5; -charbits(NumOfChars) when NumOfChars =< 64 -> 6; -charbits(NumOfChars) when NumOfChars =< 128 -> 7; -charbits(NumOfChars) when NumOfChars =< 256 -> 8; -charbits(NumOfChars) when NumOfChars =< 512 -> 9; -charbits(NumOfChars) when NumOfChars =< 1024 -> 10; -charbits(NumOfChars) when NumOfChars =< 2048 -> 11; -charbits(NumOfChars) when NumOfChars =< 4096 -> 12; -charbits(NumOfChars) when NumOfChars =< 8192 -> 13; -charbits(NumOfChars) when NumOfChars =< 16384 -> 14; -charbits(NumOfChars) when NumOfChars =< 32768 -> 15; -charbits(NumOfChars) when NumOfChars =< 65536 -> 16; -charbits(NumOfChars) when is_integer(NumOfChars) -> - 16 + charbits1(NumOfChars bsr 16). - -charbits1(0) -> - 0; -charbits1(NumOfChars) -> - 1 + charbits1(NumOfChars bsr 1). - - -%% UTF8String -encode_UTF8String(Val) when is_binary(Val) -> - [encode_length(byte_size(Val)),Val]; -encode_UTF8String(Val) -> - Bin = list_to_binary(Val), - encode_UTF8String(Bin). - - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% encode_object_identifier(Val) -> CompleteList -%% encode_object_identifier({Name,Val}) -> CompleteList -%% Val -> {Int1,Int2,...,IntN} % N >= 2 -%% Name -> atom() -%% Int1 -> integer(0..2) -%% Int2 -> integer(0..39) when Int1 (0..1) else integer() -%% Int3-N -> integer() -%% CompleteList -> [binary()|bitstring()|list()] -%% -encode_object_identifier(Val) -> - OctetList = e_object_identifier(Val), - Octets = list_to_binary(OctetList), % performs a flatten at the same time - [encode_length(byte_size(Octets)),Octets]. - -%% This code is copied from asn1_encode.erl (BER) and corrected and modified - -e_object_identifier({'OBJECT IDENTIFIER',V}) -> - e_object_identifier(V); -e_object_identifier(V) when is_tuple(V) -> - e_object_identifier(tuple_to_list(V)); - -%% E1 = 0|1|2 and (E2 < 40 when E1 = 0|1) -e_object_identifier([E1,E2|Tail]) when E1 >= 0, E1 < 2, E2 < 40 ; E1==2 -> - Head = 40*E1 + E2, % weird - e_object_elements([Head|Tail],[]); -e_object_identifier(Oid=[_,_|_Tail]) -> - exit({error,{asn1,{'illegal_value',Oid}}}). - -e_object_elements([],Acc) -> - lists:reverse(Acc); -e_object_elements([H|T],Acc) -> - e_object_elements(T,[e_object_element(H)|Acc]). - -e_object_element(Num) when Num < 128 -> - [Num]; -e_object_element(Num) -> - [e_o_e(Num bsr 7)|[Num band 2#1111111]]. -e_o_e(Num) when Num < 128 -> - Num bor 2#10000000; -e_o_e(Num) -> - [e_o_e(Num bsr 7)|[(Num band 2#1111111) bor 2#10000000]]. - - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% encode_relative_oid(Val) -> CompleteList -%% encode_relative_oid({Name,Val}) -> CompleteList -encode_relative_oid(Val) when is_tuple(Val) -> - encode_relative_oid(tuple_to_list(Val)); -encode_relative_oid(Val) when is_list(Val) -> - Octets = list_to_binary([e_object_element(X)||X <- Val]), - [encode_length(byte_size(Octets)),Octets]. - - -get_constraint([{Key,V}],Key) -> - V; -get_constraint([],_Key) -> - no; -get_constraint(C,Key) -> - case lists:keyfind(Key, 1, C) of - false -> - no; - {_,V} -> - V - end. - %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% complete(InList) -> ByteList %% Takes a coded list with bits and bytes and converts it to a list of bytes %% Should be applied as the last step at encode of a complete ASN.1 type %% complete(InList) when is_list(InList) -> - case complete1(InList) of + case list_to_bitstring(InList) of <<>> -> <<0>>; Res -> - case bit_size(Res) band 7 of + Sz = bit_size(Res), + case Sz band 7 of 0 -> Res; - Bits -> <<Res/bitstring,0:(8-Bits)>> + Bits -> <<Res:Sz/bitstring,0:(8-Bits)>> end end; complete(Bin) when is_binary(Bin) -> @@ -950,24 +65,12 @@ complete(Bin) when is_binary(Bin) -> _ -> Bin end; complete(InList) when is_bitstring(InList) -> - PadLen = 8 - (bit_size(InList) band 7), - <<InList/bitstring,0:PadLen>>. - -complete1(L) when is_list(L) -> - list_to_bitstring(L). + Sz = bit_size(InList), + PadLen = 8 - (Sz band 7), + <<InList:Sz/bitstring,0:PadLen>>. %% Special version of complete that does not align the completed message. complete_NFP(InList) when is_list(InList) -> list_to_bitstring(InList); complete_NFP(InList) when is_bitstring(InList) -> InList. - -%% unaligned helpers - -%% 10.5.6 NOTE: If "range" satisfies the inequality 2^m < "range" =< -%% 2^(m+1) then the number of bits = m + 1 - -num_bits(N) -> num_bits(N, 1, 0). - -num_bits(N,T,B) when N =< T -> B; -num_bits(N,T,B) -> num_bits(N, T bsl 1, B+1). diff --git a/lib/asn1/test/Makefile b/lib/asn1/test/Makefile index 15b97df972..b1b08aa9f9 100644 --- a/lib/asn1/test/Makefile +++ b/lib/asn1/test/Makefile @@ -26,7 +26,6 @@ include $(ERL_TOP)/make/$(TARGET)/otp.mk MODULES= \ h323test \ - choice_extension \ ber_decode_error \ testPrim \ testPrimStrings \ @@ -36,7 +35,6 @@ MODULES= \ testChoExtension \ testChoExternal \ testChoOptional \ - testChoOptionalImplicitTag \ testChoRecursive \ testChoTypeRefCho \ testChoTypeRefPrim \ @@ -51,12 +49,12 @@ MODULES= \ testSeqOptional \ testSeq2738 \ testSeqPrim \ + testSeqSetIndefinite \ testSeqTag \ testSeqTypeRefCho \ testSeqTypeRefPrim \ testSeqTypeRefSeq \ testSeqTypeRefSet \ - testSeqIndefinite \ testSeqOf \ testSeqOfIndefinite \ testSeqOfCho \ @@ -72,7 +70,6 @@ MODULES= \ testSetTypeRefPrim \ testSetTypeRefSeq \ testSetTypeRefSet \ - testSetIndefinite \ testChoiceIndefinite \ testSetOf \ testSetOfCho \ @@ -82,6 +79,7 @@ MODULES= \ testInfObjectClass \ testInfObj \ testParameterizedInfObj \ + testFragmented \ testMergeCompile \ testMultipleLevels \ testDeepTConstr \ @@ -99,7 +97,6 @@ MODULES= \ test_special_decode_performance \ testTCAP \ testSSLspecs \ - test_driver_load \ testSelectionTypes \ test_undecoded_rest \ testTcapsystem \ @@ -113,12 +110,9 @@ MODULES= \ asn1_test_lib \ asn1_app_test \ asn1_appup_test \ - asn1_wrapper \ asn1_SUITE \ error_SUITE -SUITE= asn1_SUITE.erl - ERL_FILES= $(MODULES:%=%.erl) HRL_FILES= External.hrl @@ -143,7 +137,7 @@ EBIN = . $(EMAKEFILE): $(ERL_FILES) $(HRL_FILES) $(ERL_TOP)/make/make_emakefile $(ERL_COMPILE_FLAGS) -o$(EBIN) $(MODULES) $(ERL_FILES) >$(EMAKEFILE) -tests debug opt: $(SUITE) $(SUITE_BIN) $(SUITE_BIN_V2) $(EMAKEFILE) +tests debug opt: $(EMAKEFILE) clean: rm -f core @@ -160,7 +154,7 @@ release_spec: opt release_tests_spec: opt $(INSTALL_DIR) "$(RELSYSDIR)" $(INSTALL_DIR) "$(RELSYSDIR)/asn1_SUITE_data" - $(INSTALL_DATA) $(ERL_FILES) $(HRL_FILES) "$(RELSYSDIR)" + $(INSTALL_DATA) $(EMAKEFILE) $(ERL_FILES) $(HRL_FILES) "$(RELSYSDIR)" $(INSTALL_DATA) asn1.spec asn1.cover $(INSTALL_PROGS) "$(RELSYSDIR)" chmod -R u+w "$(RELSYSDIR)" cd asn1_SUITE_data; tar cfh "$(RELSYSDIR)/asn1_SUITE_data.tar" * diff --git a/lib/asn1/test/asn1_SUITE.erl b/lib/asn1/test/asn1_SUITE.erl index f00b23a8b2..61b360ddf2 100644 --- a/lib/asn1/test/asn1_SUITE.erl +++ b/lib/asn1/test/asn1_SUITE.erl @@ -67,10 +67,10 @@ groups() -> {parallel, parallel([]), [cover, + xref, {group, ber}, % Uses 'P-Record', 'Constraints', 'MEDIA-GATEWAY-CONTROL'... {group, [], [parse, - test_driver_load, test_undecoded_rest, specialized_decodes, special_decode_performance, @@ -83,16 +83,13 @@ groups() -> {group, [], [testPrim, rtUI, testPrimStrings, - testInvokeMod, per, ber_other, der, - h323test, - per_GeneralString]}, + h323test]}, testChoPrim, testChoExtension, testChoOptional, - testChoOptionalImplicitTag, testChoRecursive, testChoTypeRefCho, testChoTypeRefPrim, @@ -103,18 +100,8 @@ groups() -> testOpt, testSeqDefault, % Uses 'External' - {group, [], [testChoExternal, - testPrimExternal, - testSeqExtension, - testSeqExternal, - testSeqOfExternal, - testSeqOfTag, - testSeqTag, - testSetExtension, - testSetExternal, - testSetOfExternal, - testSetOfTag, - testSetTag]}, + {group, [], [testExternal, + testSeqExtension]}, testSeqOptional, testSeqPrim, testSeqTypeRefCho, @@ -143,13 +130,12 @@ groups() -> % Uses 'Constructed' {group, [], [constructed, ber_decode_error]}, - % Uses 'SeqSetIndefinite' - {group, [], [testSeqIndefinite, - testSetIndefinite]}, + testSeqSetIndefinite, testChoiceIndefinite, per_open_type, testInfObjectClass, testParameterizedInfObj, + testFragmented, testMergeCompile, testobj, testDeepTConstr, @@ -186,8 +172,7 @@ groups() -> {performance, [], [testTimer_ber, testTimer_per, - testTimer_uper, - smp]}]. + testTimer_uper]}]. parallel(Options) -> case erlang:system_info(smp_support) andalso @@ -284,13 +269,6 @@ replace_path(PathA, PathB) -> join(Rule, Opts) -> string:join([atom_to_list(Rule)|lists:map(fun atom_to_list/1, Opts)], "_"). -case_dir([], _Dir) -> - exit(no_case_dir); -case_dir([{case_dir, _}|Config], Dir) -> - [{case_dir, Dir}|Config]; -case_dir([C|Config], Opt) -> - [C|case_dir(Config, Opt)]. - %%------------------------------------------------------------------------------ %% Test cases %%------------------------------------------------------------------------------ @@ -319,7 +297,15 @@ cover(_) -> testPrim(Config) -> test(Config, fun testPrim/3). testPrim(Config, Rule, Opts) -> - asn1_test_lib:compile_all(["Prim", "Real"], Config, [Rule|Opts]), + Files = ["Prim","Real"], + asn1_test_lib:compile_all(Files, Config, [Rule|Opts]), + do_test_prim(Rule, false), + asn1_test_lib:compile_all(Files, Config, [no_ok_wrapper,Rule|Opts]), + do_test_prim(Rule, true). + +do_test_prim(Rule, NoOkWrapper) -> + io:format("No ok wrapper: ~p\n", [NoOkWrapper]), + put(no_ok_wrapper, NoOkWrapper), testPrim:bool(Rule), testPrim:int(Rule), testPrim:enum(Rule), @@ -360,17 +346,36 @@ testPrimStrings_cases(Rule) -> testPrimStrings:universal_string(Rule), testPrimStrings:bmp_string(Rule), testPrimStrings:times(Rule), - testPrimStrings:utf8_string(Rule). + testPrimStrings:utf8_string(Rule), + testPrimStrings:fragmented(Rule). -testPrimExternal(Config) -> test(Config, fun testPrimExternal/3). -testPrimExternal(Config, Rule, Opts) -> - asn1_test_lib:compile_all(["External", "PrimExternal"], Config, - [Rule|Opts]), +testExternal(Config) -> test(Config, fun testExternal/3). +testExternal(Config, Rule, Opts) -> + asn1_test_lib:compile_all(["External", + "ChoExternal", + "PrimExternal", + "SeqExternal", + "SeqOfExternal", + "SeqOfTag", + "SeqTag", + "SetExtension", + "SetExternal", + "SetOfExternal", + "SetOfTag", + "SetTag"], + Config, [Rule|Opts]), + testChoExternal:external(Rule), testPrimExternal:external(Rule), - asn1_test_lib:compile_all(["PrimStrings", "BitStr"], Config, - [Rule|Opts]), - testPrimStrings_cases(Rule), - testPrimStrings:more_strings(Rule). + testSeqExternal:main(Rule), + testSeqOfExternal:main(Rule), + testSeqOfTag:main(Rule), + testSeqTag:main(Rule), + testSetExtension:main(Rule), + testSetExternal:main(Rule), + testSetOfExternal:main(Rule), + testSetOfTag:main(Rule), + testSetTag:main(Rule). + testChoPrim(Config) -> test(Config, fun testChoPrim/3). testChoPrim(Config, Rule, Opts) -> @@ -383,23 +388,11 @@ testChoExtension(Config, Rule, Opts) -> asn1_test_lib:compile("ChoExtension", Config, [Rule|Opts]), testChoExtension:extension(Rule). -testChoExternal(Config) -> test(Config, fun testChoExternal/3). -testChoExternal(Config, Rule, Opts) -> - asn1_test_lib:compile_all(["External", "ChoExternal"], Config, [Rule|Opts]), - testChoExternal:external(Rule). - testChoOptional(Config) -> test(Config, fun testChoOptional/3). testChoOptional(Config, Rule, Opts) -> - asn1_test_lib:compile("ChoOptional", Config, [Rule|Opts]), - testChoOptional:optional(Rule). - -testChoOptionalImplicitTag(Config) -> - test(Config, fun testChoOptionalImplicitTag/3, - [ber]). -testChoOptionalImplicitTag(Config, Rule, Opts) -> - %% Only meaningful for ber & co - asn1_test_lib:compile("ChoOptionalImplicitTag", Config, [Rule|Opts]), - testChoOptionalImplicitTag:optional(Rule). + asn1_test_lib:compile_all(["ChoOptional", + "ChoOptionalImplicitTag"], Config, [Rule|Opts]), + testChoOptional:run(). testChoRecursive(Config) -> test(Config, fun testChoRecursive/3). testChoRecursive(Config, Rule, Opts) -> @@ -452,7 +445,7 @@ testSeqDefault(Config, Rule, Opts) -> asn1_test_lib:compile("SeqDefault", Config, [Rule|Opts]), testSeqDefault:main(Rule). -testSeqExtension(Config) -> test(Config, fun testSeqExtension/3). +testSeqExtension(Config) -> test(Config, fun testSeqExtension/3, [ber,uper]). testSeqExtension(Config, Rule, Opts) -> asn1_test_lib:compile_all(["External", "SeqExtension", @@ -462,11 +455,6 @@ testSeqExtension(Config, Rule, Opts) -> DataDir = ?config(data_dir, Config), testSeqExtension:main(Rule, DataDir, [Rule|Opts]). -testSeqExternal(Config) -> test(Config, fun testSeqExternal/3). -testSeqExternal(Config, Rule, Opts) -> - asn1_test_lib:compile_all(["External", "SeqExternal"], Config, [Rule|Opts]), - testSeqExternal:main(Rule). - testSeqOptional(Config) -> test(Config, fun testSeqOptional/3). testSeqOptional(Config, Rule, Opts) -> asn1_test_lib:compile("SeqOptional", Config, [Rule|Opts]), @@ -483,11 +471,6 @@ testSeq2738(Config, Rule, Opts) -> asn1_test_lib:compile("Seq2738", Config, [Rule|Opts]), testSeq2738:main(Rule). -testSeqTag(Config) -> test(Config, fun testSeqTag/3). -testSeqTag(Config, Rule, Opts) -> - asn1_test_lib:compile_all(["External", "SeqTag"], Config, [Rule|Opts]), - testSeqTag:main(Rule). - testSeqTypeRefCho(Config) -> test(Config, fun testSeqTypeRefCho/3). testSeqTypeRefCho(Config, Rule, Opts) -> asn1_test_lib:compile("SeqTypeRefCho", Config, [Rule|Opts]), @@ -528,17 +511,6 @@ testSeqOfIndefinite(Config, Rule, Opts) -> asn1_test_lib:compile_all(Files, Config, [Rule|Opts]), testSeqOfIndefinite:main(). -testSeqOfExternal(Config) -> test(Config, fun testSeqOfExternal/3). -testSeqOfExternal(Config, Rule, Opts) -> - asn1_test_lib:compile_all(["External", "SeqOfExternal"], Config, - [Rule|Opts]), - testSeqOfExternal:main(Rule). - -testSeqOfTag(Config) -> test(Config, fun testSeqOfTag/3). -testSeqOfTag(Config, Rule, Opts) -> - asn1_test_lib:compile_all(["External", "SeqOfTag"], Config, [Rule|Opts]), - testSeqOfTag:main(Rule). - testSetDefault(Config) -> test(Config, fun testSetDefault/3). testSetDefault(Config, Rule, Opts) -> asn1_test_lib:compile("SetDefault", Config, [Rule|Opts]), @@ -549,17 +521,6 @@ testParamBasic(Config, Rule, Opts) -> asn1_test_lib:compile("ParamBasic", Config, [Rule|Opts]), testParamBasic:main(Rule). -testSetExtension(Config) -> test(Config, fun testSetExtension/3). -testSetExtension(Config, Rule, Opts) -> - asn1_test_lib:compile_all(["External", "SetExtension"], Config, - [Rule|Opts]), - testSetExtension:main(Rule). - -testSetExternal(Config) -> test(Config, fun testSetExternal/3). -testSetExternal(Config, Rule, Opts) -> - asn1_test_lib:compile_all(["External", "SetExternal"], Config, [Rule|Opts]), - testSetExternal:main(Rule). - testSetOptional(Config) -> test(Config, fun testSetOptional/3). testSetOptional(Config, Rule, Opts) -> asn1_test_lib:compile("SetOptional", Config, [Rule|Opts]), @@ -571,11 +532,6 @@ testSetPrim(Config, Rule, Opts) -> asn1_test_lib:compile("SetPrim", Config, [Rule|Opts]), testSetPrim:main(Rule). -testSetTag(Config) -> test(Config, fun testSetTag/3). -testSetTag(Config, Rule, Opts) -> - asn1_test_lib:compile_all(["External", "SetTag"], Config, [Rule|Opts]), - testSetTag:main(Rule). - testSetTypeRefCho(Config) -> test(Config, fun testSetTypeRefCho/3). testSetTypeRefCho(Config, Rule, Opts) -> asn1_test_lib:compile("SetTypeRefCho", Config, [Rule|Opts]), @@ -606,17 +562,6 @@ testSetOfCho(Config, Rule, Opts) -> asn1_test_lib:compile("SetOfCho", Config, [Rule|Opts]), testSetOfCho:main(Rule). -testSetOfExternal(Config) -> test(Config, fun testSetOfExternal/3). -testSetOfExternal(Config, Rule, Opts) -> - asn1_test_lib:compile_all(["External", "SetOfExternal"], Config, - [Rule|Opts]), - testSetOfExternal:main(Rule). - -testSetOfTag(Config) -> test(Config, fun testSetOfTag/3). -testSetOfTag(Config, Rule, Opts) -> - asn1_test_lib:compile_all(["External", "SetOfTag"], Config, [Rule|Opts]), - testSetOfTag:main(Rule). - c_syntax(Config) -> DataDir = ?config(data_dir, Config), [{error, _} = asn1ct:compile(filename:join(DataDir, F)) @@ -714,10 +659,7 @@ ber_optional(Config, Rule, Opts) -> V = {'S', {'A', 10, asn1_NOVALUE, asn1_NOVALUE}, {'B', asn1_NOVALUE, asn1_NOVALUE, asn1_NOVALUE}, {'C', asn1_NOVALUE, 111, asn1_NOVALUE}}, - {ok, B} = asn1_wrapper:encode('SOpttest', 'S', V), - Bytes = lists:flatten(B), - V2 = asn1_wrapper:decode('SOpttest', 'S', Bytes), - V = element(2, V2). + asn1_test_lib:roundtrip('SOpttest', 'S', V). %% records used by test-case default -record('Def1', {bool0, @@ -728,14 +670,16 @@ ber_optional(Config, Rule, Opts) -> default(Config) -> test(Config, fun default/3). default(Config, Rule, Opts) -> asn1_test_lib:compile("Def", Config, [Rule|Opts]), - {ok, Bytes1} = asn1_wrapper:encode('Def', 'Def1', #'Def1'{bool0 = true}), - {ok, {'Def1', true, false, false, false}} = - asn1_wrapper:decode('Def', 'Def1', lists:flatten(Bytes1)), - - {ok, Bytes2} = asn1_wrapper:encode('Def', 'Def1', #'Def1'{bool0 = true, - bool2 = false}), - {ok, {'Def1', true, false, false, false}} = - asn1_wrapper:decode('Def', 'Def1', lists:flatten(Bytes2)). + asn1_test_lib:roundtrip('Def', + 'Def1', + #'Def1'{bool0=true}, + #'Def1'{bool0=true,bool1=false, + bool2=false,bool3=false}), + asn1_test_lib:roundtrip('Def', + 'Def1', + #'Def1'{bool0=true,bool2=false}, + #'Def1'{bool0=true,bool1=false, + bool2=false,bool3=false}). value_test(Config) -> test(Config, fun value_test/3). value_test(Config, Rule, Opts) -> @@ -747,12 +691,13 @@ constructed(Config) -> test(Config, fun constructed/3, [ber]). constructed(Config, Rule, Opts) -> asn1_test_lib:compile("Constructed", Config, [Rule|Opts]), - {ok, B} = asn1_wrapper:encode('Constructed', 'S', {'S', false}), - [40, 3, 1, 1, 0] = lists:flatten(B), - {ok, B1} = asn1_wrapper:encode('Constructed', 'S2', {'S2', false}), - [40, 5, 48, 3, 1, 1, 0] = lists:flatten(B1), - {ok, B2} = asn1_wrapper:encode('Constructed', 'I', 10), - [136, 1, 10] = lists:flatten(B2). + <<40,3,1,1,0>> = + asn1_test_lib:roundtrip_enc('Constructed', 'S', {'S',false}), + <<40,5,48,3,1,1,0>> = + asn1_test_lib:roundtrip_enc('Constructed', 'S2', {'S2',false}), + <<136,1,10>> = + asn1_test_lib:roundtrip_enc('Constructed', 'I', 10), + ok. ber_decode_error(Config) -> test(Config, fun ber_decode_error/3, [ber]). @@ -767,14 +712,6 @@ h323test(Config, Rule, Opts) -> asn1_test_lib:compile_all(Files, Config, [Rule|Opts]), h323test:run(Rule). -per_GeneralString(Config) -> - test(Config, fun per_GeneralString/3, [per]). -per_GeneralString(Config, Rule, Opts) -> - asn1_test_lib:compile("MULTIMEDIA-SYSTEM-CONTROL", Config, [Rule|Opts]), - UI = [109, 64, 1, 57], - {ok, _V} = asn1_wrapper:decode('MULTIMEDIA-SYSTEM-CONTROL', - 'MultimediaSystemControlMessage', UI). - per_open_type(Config) -> test(Config, fun per_open_type/3, [per]). per_open_type(Config, Rule, Opts) -> asn1_test_lib:compile("OpenType", Config, [Rule|Opts]), @@ -784,24 +721,17 @@ testConstraints(Config) -> test(Config, fun testConstraints/3). testConstraints(Config, Rule, Opts) -> asn1_test_lib:compile("Constraints", Config, [Rule|Opts]), asn1_test_lib:compile("LargeConstraints", Config, [Rule|Opts]), - testConstraints:int_constraints(Rule). - - -testSeqIndefinite(Config) -> - test(Config, fun testSeqIndefinite/3, [ber]). - -testSeqIndefinite(Config, Rule, Opts) -> - asn1_test_lib:compile("SeqSetIndefinite", Config, [Rule|Opts]), - testSeqIndefinite:main(Rule). - - -testSetIndefinite(Config) -> - test(Config, fun testSetIndefinite/3, [ber]). + testConstraints:int_constraints(Rule), + case Rule of + ber -> ok; + _ -> testConstraints:refed_NNL_name(Rule) + end. -testSetIndefinite(Config, Rule, Opts) -> +testSeqSetIndefinite(Config) -> + test(Config, fun testSeqSetIndefinite/3, [ber]). +testSeqSetIndefinite(Config, Rule, Opts) -> asn1_test_lib:compile("SeqSetIndefinite", Config, [Rule|Opts]), - testSetIndefinite:main(Rule). - + testSeqSetIndefinite:main(). testChoiceIndefinite(Config) -> test(Config, fun testChoiceIndefinite/3, [ber]). @@ -830,6 +760,12 @@ testParameterizedInfObj(Config, Rule, Opts) -> asn1_test_lib:compile_all(Files, Config, [Rule|Opts]), testParameterizedInfObj:main(Config, Rule). +testFragmented(Config) -> + test(Config, fun testFragmented/3). +testFragmented(Config, Rule, Opts) -> + asn1_test_lib:compile("Fragmented", Config, [Rule|Opts]), + testFragmented:main(Rule). + testMergeCompile(Config) -> test(Config, fun testMergeCompile/3). testMergeCompile(Config, Rule, Opts) -> Files = ["MS.set.asn", "RANAPSET.set.asn1", "Mvrasn4.set.asn", @@ -851,11 +787,6 @@ testDeepTConstr(Config, Rule, Opts) -> [Rule|Opts]), testDeepTConstr:main(Rule). -testInvokeMod(Config) -> test(Config, fun testInvokeMod/3). -testInvokeMod(Config, Rule, Opts) -> - asn1_test_lib:compile("PrimStrings", Config, [Rule|Opts]), - {ok, _Result2} = 'PrimStrings':encode('Bs1', [1, 0, 1, 0]). - testExport(Config) -> {error, _} = asn1ct:compile(filename:join(?config(data_dir, Config), @@ -911,7 +842,10 @@ duplicate_tags(Config) -> rtUI(Config) -> test(Config, fun rtUI/3). rtUI(Config, Rule, Opts) -> asn1_test_lib:compile("Prim", Config, [Rule|Opts]), - {ok, _} = asn1rt:info('Prim'). + {ok, _} = asn1rt:info('Prim'), + Rule = 'Prim':encoding_rule(), + io:format("Default BIT STRING format: ~p\n", + ['Prim':bit_string_format()]). testROSE(Config) -> test(Config, fun testROSE/3). testROSE(Config, Rule, Opts) -> @@ -965,13 +899,6 @@ special_decode_performance(Config, Rule, Opts) -> asn1_test_lib:compile_all(Files, Config, [Rule, asn1config|Opts]), test_special_decode_performance:go(all). - -test_driver_load(Config) -> - test(Config, fun test_driver_load/3, [per]). -test_driver_load(Config, Rule, Opts) -> - asn1_test_lib:compile("P-Record", Config, [Rule|Opts]), - test_driver_load:test(5). - test_ParamTypeInfObj(Config) -> asn1_test_lib:compile("IN-CS-1-Datatypes", Config, [ber]). @@ -989,7 +916,7 @@ test_Defed_ObjectIdentifier(Config, Rule, Opts) -> testSelectionType(Config) -> test(Config, fun testSelectionType/3). testSelectionType(Config, Rule, Opts) -> asn1_test_lib:compile("SelectionType", Config, [Rule|Opts]), - {ok, _} = testSelectionTypes:test(). + testSelectionTypes:test(). testSSLspecs(Config) -> test(Config, fun testSSLspecs/3, [ber]). @@ -1006,10 +933,14 @@ testNortel(Config, Rule, Opts) -> test_undecoded_rest(Config) -> test(Config, fun test_undecoded_rest/3). test_undecoded_rest(Config, Rule, Opts) -> + do_test_undecoded_rest(Config, Rule, Opts), + do_test_undecoded_rest(Config, Rule, [no_ok_wrapper|Opts]), + do_test_undecoded_rest(Config, Rule, [undec_rest|Opts]), + do_test_undecoded_rest(Config, Rule, [no_ok_wrapper,undec_rest|Opts]). + +do_test_undecoded_rest(Config, Rule, Opts) -> asn1_test_lib:compile("P-Record", Config, [Rule|Opts]), - ok = test_undecoded_rest:test([], Config), - asn1_test_lib:compile("P-Record", Config, [Rule,undec_rest|Opts]), - test_undecoded_rest:test(undec_rest, Config). + test_undecoded_rest:test(Opts, Config). testTcapsystem(Config) -> test(Config, fun testTcapsystem/3). @@ -1029,7 +960,20 @@ testS1AP(Config, Rule, Opts) -> "S1AP-IEs", "S1AP-PDU-Contents", "S1AP-PDU-Descriptions"], - asn1_test_lib:compile_all(S1AP, Config, [Rule|Opts]). + asn1_test_lib:compile_all(S1AP, Config, [Rule|Opts]), + + %% OTP-7876. + case Rule of + per -> + Enc = <<0,2,64,49,0,0,5,0,0,0,4,128,106,56,197,0,8,0,3,64,2,134,0, + 100,64,8,0,66,240,153,0,7,192,16,0,67,64,6,0,66,240,153,70, + 1,0,107,64,5,0,0,0,0,0>>, + {ok,{initiatingMessage,_}} = 'S1AP-PDU-Descriptions':decode('S1AP-PDU', Enc); + uper -> + ok; + ber -> + ok + end. test_compile_options(Config) -> ok = test_compile_options:wrong_path(Config), @@ -1061,24 +1005,38 @@ testX420(Config) -> "sparc-sun-solaris2.10" -> {skip,"Too slow for an old Sparc"}; _ -> - test(Config, fun testX420/3, [ber]) + Rule = ber, + testX420:compile(Rule, [der], Config), + ok = testX420:ticket7759(Rule, Config) end. -testX420(Config, Rule, Opts) -> - testX420:compile(Rule, [der|Opts], Config), - ok = testX420:ticket7759(Rule, Config), - testX420:compile(Rule, Opts, Config). test_x691(Config) -> test(Config, fun test_x691/3, [per, uper]). test_x691(Config, Rule, Opts) -> Files = ["P-RecordA1", "P-RecordA2", "P-RecordA3"], asn1_test_lib:compile_all(Files, Config, [Rule|Opts]), - test_x691:cases(Rule, case Rule of - uper -> unaligned; - _ -> aligned - end), - asn1_test_lib:ticket_7708(Config, []), - asn1_test_lib:ticket_7763(Config). + test_x691:cases(Rule), + + %% OTP-7708. + asn1_test_lib:compile("EUTRA-extract-55", Config, [Rule|Opts]), + + %% OTP-7763. + Val = {'Seq',15,lists:duplicate(8, 0),[0],lists:duplicate(28, 0),15,true}, + CompactVal = {'Seq',15,{0,<<0>>},{7,<<0>>},{4,<<0,0,0,0>>},15,true}, + {ok,Bin} = 'EUTRA-extract-55':encode('Seq', Val), + {ok,Bin} = 'EUTRA-extract-55':encode('Seq', CompactVal), + + %% OTP-7678. + asn1_test_lib:compile("UPERDefault", Config, [Rule|Opts]), + DefVal = 'UPERDefault':seq(), + {ok,DefBin} = 'UPERDefault':encode('Seq', DefVal), + {ok,DefVal} = 'UPERDefault':decode('Seq', DefBin), + case Rule of + uper -> <<0,6,0>> = DefBin; + _ -> ok + end, + + ok. ticket_6143(Config) -> ok = test_compile_options:ticket_6143(Config). @@ -1186,9 +1144,7 @@ testTimer_uper(Config) -> testComment(suite) -> []; testComment(Config) -> asn1_test_lib:compile("Comment", Config, []), - {ok,Enc} = asn1_wrapper:encode('Comment','Seq',{'Seq',12,true}), - {ok,{'Seq',12,true}} = asn1_wrapper:decode('Comment','Seq',Enc), - ok. + asn1_test_lib:roundtrip('Comment', 'Seq', {'Seq',12,true}). testName2Number(suite) -> []; testName2Number(Config) -> @@ -1224,76 +1180,67 @@ testName2Number(Config) -> ticket_7407(Config) -> asn1_test_lib:compile("EUTRA-extract-7407", Config, [uper]), - asn1_test_lib:ticket_7407_code(true), - - asn1_test_lib:compile("EUTRA-extract-7407", Config, - [uper, no_final_padding]), - asn1_test_lib:ticket_7407_code(false). - -smp(suite) -> []; -smp(Config) -> - case erlang:system_info(smp_support) of - true -> - NumOfProcs = erlang:system_info(schedulers), - io:format("smp starting ~p workers\n",[NumOfProcs]), - - Msg = {initiatingMessage, testNBAPsystem:cell_setup_req_msg()}, - ok = testNBAPsystem:compile(Config, [per]), - - enc_dec(NumOfProcs,Msg,2), - - N = 10000, - - {Time1,ok} = timer:tc(?MODULE,enc_dec,[NumOfProcs,Msg, N]), - {Time1S,ok} = timer:tc(?MODULE,enc_dec,[1, Msg, NumOfProcs * N]), - - ok = testNBAPsystem:compile(Config, [ber]), - {Time3,ok} = timer:tc(?MODULE,enc_dec,[NumOfProcs,Msg, N]), - - {Time3S,ok} = timer:tc(?MODULE,enc_dec,[1, Msg, NumOfProcs * N]), - - {comment,lists:flatten( - io_lib:format( - "Encode/decode time parallell with ~p cores: ~p [microsecs]~n" - "Encode/decode time sequential: ~p [microsecs]", - [NumOfProcs,Time1+Time3,Time1S+Time3S]))}; - false -> - {skipped,"No smp support"} - end. - -enc_dec(1, Msg, N) -> - worker_loop(N, Msg); -enc_dec(NumOfProcs,Msg, N) -> - pforeach(fun(_) -> - worker_loop(N, Msg) - end, [I || I <- lists:seq(1,NumOfProcs)]). - -worker_loop(0, _Msg) -> - ok; -worker_loop(N, Msg) -> - {ok,B}=asn1_wrapper:encode('NBAP-PDU-Discriptions', - 'NBAP-PDU', - Msg), - {ok,_Msg}=asn1_wrapper:decode('NBAP-PDU-Discriptions', - 'NBAP-PDU', - B), - worker_loop(N - 1, Msg). - - -pforeach(Fun, List) -> - pforeach(Fun, List, []). -pforeach(Fun, [], [{Pid,Ref}|Pids]) -> - receive - {'DOWN', Ref, process, Pid, normal} -> - pforeach(Fun, [], Pids) - end; -pforeach(Fun, [H|T], Pids) -> - Pid = spawn(fun() -> Fun(H) end), - Ref = erlang:monitor(process, Pid), - pforeach(Fun, T, [{Pid, Ref}|Pids]); -pforeach(_Fun,[],[]) -> + ticket_7407_code(true), + asn1_test_lib:compile("EUTRA-extract-7407", Config, [uper,no_final_padding]), + ticket_7407_code(false). + +ticket_7407_code(FinalPadding) -> + Msg1 = {Type1,_} = eutra1(msg), + {ok,B1} = 'EUTRA-extract-7407':encode(Type1, Msg1), + B1 = eutra1(result, FinalPadding), + + Msg2 = {Type2,_} = eutra2(msg), + {ok,B2} = 'EUTRA-extract-7407':encode(Type2, Msg2), + B2 = eutra2(result, FinalPadding), ok. +eutra1(msg) -> + {'BCCH-BCH-Message', + {'MasterInformationBlock',[0,1,0,1],[1,0,1,0], + {'PHICH-Configuration',short,ffs},[1,0,1,0,0,0,0,0]}}. + +eutra1(result, true) -> + <<90,80,0>>; +eutra1(result, false) -> + <<90,80,0:1>>. + +eutra2(msg) -> + {'BCCH-DL-SCH-Message', + {c1, + {systemInformation1, + {'SystemInformationBlockType1', + {'SystemInformationBlockType1_cellAccessRelatedInformation', + [{'SystemInformationBlockType1_cellAccessRelatedInformation_plmn-IdentityList_SEQOF', + {'PLMN-Identity'},true}, + {'SystemInformationBlockType1_cellAccessRelatedInformation_plmn-IdentityList_SEQOF', + {'PLMN-Identity'},false}, + {'SystemInformationBlockType1_cellAccessRelatedInformation_plmn-IdentityList_SEQOF', + {'PLMN-Identity'},true}], + {'TrackingAreaCode'}, + {'CellIdentity'}, + false, + true, + true, + true + }, + {'SystemInformationBlockType1_cellSelectionInfo',-50}, + 24, + [{'SystemInformationBlockType1_schedulinInformation_SEQOF', + {'SystemInformationBlockType1_schedulinInformation_SEQOF_si-MessageType'}, + ms320, + {'SystemInformationBlockType1_schedulinInformation_SEQOF_sib-MappingInfo'}}], + 0 + } + } + } + }. + +eutra2(result, true) -> +%% 55 5C A5 E0 + <<85,92,165,224>>; +eutra2(result, false) -> + <<85,92,165,14:4>>. + -record('InitiatingMessage',{procedureCode,criticality,value}). -record('Iu-ReleaseCommand',{first,second}). @@ -1308,3 +1255,17 @@ ticket7904(Config) -> {ok,_} = 'RANAPextract1':encode('InitiatingMessage', Val1), {ok,_} = 'RANAPextract1':encode('InitiatingMessage', Val1). + +xref(_Config) -> + xref:start(s), + xref:set_default(s, [{verbose,false},{warnings,false},{builtins,true}]), + Test = filename:dirname(code:which(?MODULE)), + {ok,_PMs} = xref:add_directory(s, Test), + UnusedExports = "X - XU - asn1_appup_test - asn1_app_test - \".*_SUITE\" : Mod", + case xref:q(s, UnusedExports) of + {ok,[]} -> + ok; + {ok,[_|_]=Res} -> + io:format("Exported, but unused: ~p\n", [Res]), + ?t:fail() + end. diff --git a/lib/asn1/test/asn1_SUITE_data/Fragmented.asn1 b/lib/asn1/test/asn1_SUITE_data/Fragmented.asn1 new file mode 100644 index 0000000000..bfc939737f --- /dev/null +++ b/lib/asn1/test/asn1_SUITE_data/Fragmented.asn1 @@ -0,0 +1,24 @@ +Fragmented DEFINITIONS AUTOMATIC TAGS ::= +BEGIN + +FUNCTION ::= CLASS { + &code INTEGER UNIQUE, + &b BOOLEAN, + &ArgumentType +} + +SS ::= SEQUENCE OF OCTET STRING + +val1 FUNCTION ::= { + &code 1, &b FALSE, &ArgumentType SS +} + +ObjSet FUNCTION ::= { val1 } + +PDU ::= SEQUENCE { + code FUNCTION.&code ({ObjSet}), + b FUNCTION.&b ({ObjSet}{@code}), + arg FUNCTION.&ArgumentType ({ObjSet}{@code}) +} + +END diff --git a/lib/asn1/test/asn1_SUITE_data/InfObj.asn b/lib/asn1/test/asn1_SUITE_data/InfObj.asn index 53e5043cb7..880e81c3b1 100644 --- a/lib/asn1/test/asn1_SUITE_data/InfObj.asn +++ b/lib/asn1/test/asn1_SUITE_data/InfObj.asn @@ -202,7 +202,11 @@ constructed2 CONSTRUCTED-DEFAULT ::= { &id 2, &ok false } ConstructedDefaultSet CONSTRUCTED-DEFAULT ::= { constructed1 | constructed2 | - { &id 3, &Type BOOLEAN } + { &id 3, &Type BOOLEAN } | + { &id 4, &Type SET { a INTEGER, b BIT STRING } } | + { &id 5, &Type CHOICE { i INTEGER, b BIT STRING } } | + { &id 6, &Type SEQUENCE OF INTEGER (1..16) } | + { &id 7, &Type SET OF INTEGER (1..64) } } ConstructedPdu ::= SEQUENCE { @@ -210,6 +214,47 @@ ConstructedPdu ::= SEQUENCE { content CONSTRUCTED-DEFAULT.&Type ({ConstructedDefaultSet}{@id}) } +ConstructedSet ::= SET { + id [0] CONSTRUCTED-DEFAULT.&id ({ConstructedDefaultSet}), + content [1] CONSTRUCTED-DEFAULT.&Type ({ConstructedDefaultSet}{@id}) +} + +-- Test OPTIONAL and DEFAULT + +OptionalInSeq ::= SEQUENCE { + id CONSTRUCTED-DEFAULT.&id ({ConstructedDefaultSet}), + content CONSTRUCTED-DEFAULT.&Type ({ConstructedDefaultSet}{@id}) OPTIONAL +} + +DefaultInSeq ::= SEQUENCE { + id CONSTRUCTED-DEFAULT.&id ({ConstructedDefaultSet}), + content CONSTRUCTED-DEFAULT.&Type ({ConstructedDefaultSet}{@id}) + DEFAULT BOOLEAN:TRUE +} + +-- Test more than one optional typefield table constraint in a SEQUENCE. + +MULTIPLE-OPTIONALS ::= CLASS { + &id INTEGER UNIQUE, + &T1, + &T2, + &T3 +} + +multiple-optionals-1 MULTIPLE-OPTIONALS ::= + {&id 1, &T1 INTEGER, &T2 BOOLEAN, &T3 OCTET STRING} + +Multiple-Optionals-Set MULTIPLE-OPTIONALS ::= { + multiple-optionals-1 +} + +Multiple-Optionals ::= SEQUENCE { + id MULTIPLE-OPTIONALS.&id ({Multiple-Optionals-Set}), + t1 [0] MULTIPLE-OPTIONALS.&T1 ({Multiple-Optionals-Set}{@id}) OPTIONAL, + t2 [1] MULTIPLE-OPTIONALS.&T2 ({Multiple-Optionals-Set}{@id}) OPTIONAL, + t3 [2] MULTIPLE-OPTIONALS.&T3 ({Multiple-Optionals-Set}{@id}) OPTIONAL +} + END diff --git a/lib/asn1/test/asn1_SUITE_data/Param.asn1 b/lib/asn1/test/asn1_SUITE_data/Param.asn1 index b2987a7885..4eff0da781 100644 --- a/lib/asn1/test/asn1_SUITE_data/Param.asn1 +++ b/lib/asn1/test/asn1_SUITE_data/Param.asn1 @@ -88,6 +88,28 @@ POS2 {CONFIG-DATA:obj} ::= OCTET STRING (SIZE(obj.&minLevel .. obj.&maxLevel)) OS2 ::= POS2 {config-data} +-- +-- Test a CLASS without the user-friendly syntax. +-- + +CL ::= CLASS { + &code INTEGER UNIQUE, + &Data +} + +P{T} ::= CHOICE { a INTEGER, b T } + +o1 CL ::= { + &code 42, + &Data P{BOOLEAN} +} + +SetCL CL ::= { o1 } + +Scl ::= SEQUENCE { + code CL.&code ({SetCL}), + data CL.&Data ({SetCL}{@code}) +} END diff --git a/lib/asn1/test/asn1_SUITE_data/SeqOf.asn1 b/lib/asn1/test/asn1_SUITE_data/SeqOf.asn1 index 888dbe5dd7..670f827f5e 100644 --- a/lib/asn1/test/asn1_SUITE_data/SeqOf.asn1 +++ b/lib/asn1/test/asn1_SUITE_data/SeqOf.asn1 @@ -31,7 +31,43 @@ Seq4 ::= SEQUENCE seq43 [43] SEQUENCE OF SeqIn DEFAULT {} } +Seq5 ::= SEQUENCE { + b BOOLEAN, + s SEQUENCE SIZE (0..3) OF OCTET STRING (SIZE (0..3)), + -- If 's' is empty, 'magic' should not be aligned. + magic INTEGER (0..127) +} + +Seq6 ::= SEQUENCE { + a SEQUENCE OF INTEGER (0..7), + b SEQUENCE (SIZE (0..7)) OF INTEGER (0..7), + -- 'magic' should never be aligned. + magic INTEGER (0..127) +} +Seq7 ::= SEQUENCE { + a SEQUENCE OF INTEGER (1..512), + b SEQUENCE (SIZE (0..255)) OF INTEGER (1..512), + i INTEGER +} + +Seq8 ::= SEQUENCE { + sof SEQUENCE (SIZE (0..3)) OF OCTET STRING (SIZE (3)), + -- Not aligned here if the size of 'sof' is zero. + i INTEGER (0..127) +} + +Seq9 ::= SEQUENCE { + b BOOLEAN, + s SEQUENCE SIZE (0..3) OF OCTET STRING (SIZE (0..3)), + magic INTEGER (0..127) +} + +Seq10 ::= SEQUENCE { + b BOOLEAN, + s SEQUENCE SIZE (1..3) OF OCTET STRING (SIZE (0..3)), + magic INTEGER (0..127) +} SeqIn ::= SEQUENCE { @@ -50,9 +86,6 @@ SeqCho ::= SEQUENCE OF CHOICE {bool BOOLEAN, SeqOfInt ::= SEQUENCE OF INTEGER - - - SeqEmp ::= SEQUENCE { seq1 SEQUENCE OF Empty DEFAULT {} diff --git a/lib/asn1/test/asn1_SUITE_data/TConstr.asn1 b/lib/asn1/test/asn1_SUITE_data/TConstr.asn1 index e2e0a11dc4..b2b2de2f56 100644 --- a/lib/asn1/test/asn1_SUITE_data/TConstr.asn1 +++ b/lib/asn1/test/asn1_SUITE_data/TConstr.asn1 @@ -58,6 +58,40 @@ Deeper ::= SEQUENCE { b SEQUENCE {ba INTEGER, bb MYCLASS.&Type ({ObjectSet}{@a.s.ab})} } +Seq3 ::= SEQUENCE { + a SEQUENCE { + aa INTEGER, + ab MYCLASS.&id ({ObjectSet}) + }, + -- Multiple references from the same SEQUENCE... + b SEQUENCE { + ba MYCLASS.&Type ({ObjectSet}{@a.ab}), + bb MYCLASS.&Result ({ObjectSet}{@a.ab}), + -- ... and references from multiple SEQUENCEs... + bc SEQUENCE { + bca MYCLASS.&Result ({ObjectSet}{@a.ab}), + bcb MYCLASS.&Type ({ObjectSet}{@a.ab}) + } + } +} + +Seq3-Opt ::= SEQUENCE { + a SEQUENCE { + aa INTEGER, + ab MYCLASS.&id ({ObjectSet}) + }, + -- Multiple references from the same SEQUENCE... + b SEQUENCE { + ba MYCLASS.&Type ({ObjectSet}{@a.ab}) OPTIONAL, + bb MYCLASS.&Result ({ObjectSet}{@a.ab}) OPTIONAL, + -- ... and references from multiple SEQUENCEs... + bc SEQUENCE { + bca MYCLASS.&Result ({ObjectSet}{@a.ab}), + bcb MYCLASS.&Type ({ObjectSet}{@a.ab}) + } OPTIONAL + } +} + -- following from Peter's definitions diff --git a/lib/asn1/test/asn1_SUITE_data/UPERDefault.asn b/lib/asn1/test/asn1_SUITE_data/UPERDefault.asn new file mode 100644 index 0000000000..7b81a0e09f --- /dev/null +++ b/lib/asn1/test/asn1_SUITE_data/UPERDefault.asn @@ -0,0 +1,18 @@ +UPERDefault DEFINITIONS AUTOMATIC TAGS ::= + +BEGIN + +-- OTP-7681 +Int ::= INTEGER (0..32767) + +Seq ::= SEQUENCE { + a Int, + b INTEGER (-27..27) DEFAULT 0, -- OTP-7678 + c INTEGER OPTIONAL +} + +seq Seq ::= +{a 12, + b 0} + +END
\ No newline at end of file diff --git a/lib/asn1/test/asn1_test_lib.erl b/lib/asn1/test/asn1_test_lib.erl index 60b2b2b42e..417380159e 100644 --- a/lib/asn1/test/asn1_test_lib.erl +++ b/lib/asn1/test/asn1_test_lib.erl @@ -19,13 +19,9 @@ %% -module(asn1_test_lib). --export([compile/3]). --export([compile_all/3]). --export([compile_erlang/3]). --export([hex_to_bin/1]). - --export([ticket_7407_compile/2,ticket_7407_code/1, ticket_7678/2, - ticket_7708/2, ticket_7763/1, ticket_7876/3]). +-export([compile/3,compile_all/3,compile_erlang/3, + hex_to_bin/1, + roundtrip/3,roundtrip/4,roundtrip_enc/3,roundtrip_enc/4]). -include_lib("test_server/include/test_server.hrl"). @@ -40,15 +36,7 @@ compile_all(Files, Config, Options) -> compile_file(File, Options) -> try - ok = asn1ct:compile(File, [warnings_as_errors|Options]), - case should_load(File, Options) of - false -> - ok; - {module, Module} -> - code:purge(Module), - {module, Module} = code:load_file(Module), - code:purge(Module) - end + ok = asn1ct:compile(File, [warnings_as_errors|Options]) catch Class:Reason -> ct:print("Failed to compile ~s\n", [File]), @@ -65,153 +53,26 @@ compile_erlang(Mod, Config, Options) -> hex_to_bin(S) -> << <<(hex2num(C)):4>> || C <- S, C =/= $\s >>. -%%% -%%% Internal functions. -%%% +roundtrip(Mod, Type, Value) -> + roundtrip(Mod, Type, Value, Value). -should_load(File, Options) -> - case lists:member(abs, Options) of - true -> - false; - false -> - {module,list_to_atom(strip_extension(filename:basename(File)))} - end. +roundtrip(Mod, Type, Value, ExpectedValue) -> + {ok,Encoded} = Mod:encode(Type, Value), + {ok,ExpectedValue} = Mod:decode(Type, Encoded), + ok. -strip_extension(File) -> - strip_extension(File, filename:extension(File)). +roundtrip_enc(Mod, Type, Value) -> + roundtrip_enc(Mod, Type, Value, Value). -strip_extension(File, "") -> - File; -strip_extension(File, Ext) when Ext == ".asn"; Ext == ".set"; Ext == ".asn1"-> - strip_extension(filename:rootname(File)); -strip_extension(File, _Ext) -> - File. +roundtrip_enc(Mod, Type, Value, ExpectedValue) -> + {ok,Encoded} = Mod:encode(Type, Value), + {ok,ExpectedValue} = Mod:decode(Type, Encoded), + Encoded. + +%%% +%%% Internal functions. +%%% hex2num(C) when $0 =< C, C =< $9 -> C - $0; hex2num(C) when $A =< C, C =< $F -> C - $A + 10; hex2num(C) when $a =< C, C =< $f -> C - $a + 10. - -ticket_7407_compile(Config,Option) -> - - ?line DataDir = ?config(data_dir,Config), - ?line OutDir = ?config(priv_dir,Config), - - ?line ok = asn1ct:compile(DataDir ++ "EUTRA-extract-7407", - [uper, {outdir,OutDir}]++Option). - -ticket_7708(Config,Option) -> - ?line DataDir = ?config(data_dir,Config), - ?line OutDir = ?config(priv_dir,Config), - - ?line ok = asn1ct:compile(DataDir ++ "EUTRA-extract-55", - [uper, {outdir,OutDir}]++Option). - - -ticket_7407_code(FinalPadding) -> - Msg1 = {Type1,_} = eutra1(msg), - ?line {ok,B1} = 'EUTRA-extract-7407':encode(Type1,Msg1), - ?line B1 = eutra1(result,FinalPadding), - - Msg2 = {Type2,_} = eutra2(msg), - ?line {ok,B2} = 'EUTRA-extract-7407':encode(Type2,Msg2), - ?line B2 = eutra2(result,FinalPadding), - ok. - -eutra1(msg) -> - {'BCCH-BCH-Message',{'MasterInformationBlock',[0,1,0,1],[1,0,1,0],{'PHICH-Configuration',short,ffs},[1,0,1,0,0,0,0,0]}}. -eutra1(result,true) -> - <<90,80,0>>; -eutra1(result,false) -> - <<90,80,0:1>>. - -eutra2(msg) -> - {'BCCH-DL-SCH-Message', - {c1, - {systemInformation1, - {'SystemInformationBlockType1', - {'SystemInformationBlockType1_cellAccessRelatedInformation', - [{'SystemInformationBlockType1_cellAccessRelatedInformation_plmn-IdentityList_SEQOF',{'PLMN-Identity'},true}, - {'SystemInformationBlockType1_cellAccessRelatedInformation_plmn-IdentityList_SEQOF',{'PLMN-Identity'},false}, - {'SystemInformationBlockType1_cellAccessRelatedInformation_plmn-IdentityList_SEQOF',{'PLMN-Identity'},true}], - {'TrackingAreaCode'}, - {'CellIdentity'}, - false, - true, - true, - true - }, - {'SystemInformationBlockType1_cellSelectionInfo',-50}, - 24, - [{'SystemInformationBlockType1_schedulinInformation_SEQOF', - {'SystemInformationBlockType1_schedulinInformation_SEQOF_si-MessageType'}, - ms320, - {'SystemInformationBlockType1_schedulinInformation_SEQOF_sib-MappingInfo'}}], - 0 - } - } - } - }. -eutra2(result,true) -> -%% 55 5C A5 E0 - <<85,92,165,224>>; -eutra2(result,false) -> - <<85,92,165,14:4>>. - - - -ticket_7678(Config, Option) -> - ?line DataDir = ?config(data_dir,Config), - ?line OutDir = ?config(priv_dir,Config), - - ?line ok = asn1ct:compile(DataDir ++ "UPERDefault", - [uper, {outdir,OutDir}]++Option), - - ?line Val = 'UPERDefault':seq(), - ?line {ok,<<0,6,0>>} = 'UPERDefault':encode('Seq',Val), - ?line {ok,Val} = 'UPERDefault':decode('Seq',<<0,6,0>>), - ok. - - -ticket_7763(Config) -> - ?line DataDir = ?config(data_dir,Config), - ?line OutDir = ?config(priv_dir,Config), - - ?line ok = asn1ct:compile(DataDir ++ "EUTRA-extract-55", - [uper, {outdir,OutDir}]), - Val = {'Seq',15,lists:duplicate(8,0),[0],lists:duplicate(28,0),15,true}, - ?line {ok,Bin} = 'EUTRA-extract-55':encode('Seq',Val), - - ?line ok = asn1ct:compile(DataDir ++ "EUTRA-extract-55", - [uper,compact_bit_string,{outdir,OutDir}]), - CompactVal = {'Seq',15,{0,<<0>>},{7,<<0>>},{4,<<0,0,0,0>>},15,true}, - {ok,CompactBin} = 'EUTRA-extract-55':encode('Seq',CompactVal), - - ?line Bin = CompactBin, - - io:format("CompactBin:~n~p~nBin:~n~p~nCompactBin == Bin is ~p~n",[CompactBin,Bin,CompactBin == Bin]). - - -ticket_7876(Config,Erule,Options) -> - ?line DataDir = ?config(data_dir,Config), - ?line OutDir = ?config(priv_dir,Config), - - ?line ok = asn1ct:compile(DataDir ++ "S1AP-CommonDataTypes", - [Erule,{outdir,OutDir}|Options]), - ?line ok = asn1ct:compile(DataDir ++ "S1AP-Constants", - [Erule,{outdir,OutDir}|Options]), -?line ok = asn1ct:compile(DataDir ++ "S1AP-Containers", - [Erule,{outdir,OutDir}|Options]), -?line ok = asn1ct:compile(DataDir ++ "S1AP-IEs", - [Erule,{outdir,OutDir}|Options]), -?line ok = asn1ct:compile(DataDir ++ "S1AP-PDU-Contents", - [Erule,{outdir,OutDir}|Options]), -?line ok = asn1ct:compile(DataDir ++ "S1AP-PDU-Descriptions", - [Erule,{outdir,OutDir}|Options]), - - ticket_7876_encdec(Erule), - ok. - -ticket_7876_encdec(per) -> - ?line {ok,{initiatingMessage,_}} = 'S1AP-PDU-Descriptions':decode('S1AP-PDU', [0,2,64,49,0,0,5,0,0,0,4,128,106,56,197,0,8,0,3,64,2,134,0,100,64,8,0,66,240,153,0,7,192,16,0,67,64,6,0,66,240,153,70,1,0,107,64,5,0,0,0,0,0]); -ticket_7876_encdec(_) -> - ?line {ok,{initiatingMessage,_}} = 'S1AP-PDU-Descriptions':decode('S1AP-PDU', <<0,2,64,49,0,0,5,0,0,0,4,128,106,56,197,0,8,0,3,64,2,134,0,100,64,8,0,66,240,153,0,7,192,16,0,67,64,6,0,66,240,153,70,1,0,107,64,5,0,0,0,0,0>>). diff --git a/lib/asn1/test/asn1_wrapper.erl b/lib/asn1/test/asn1_wrapper.erl deleted file mode 100644 index ac194fe38b..0000000000 --- a/lib/asn1/test/asn1_wrapper.erl +++ /dev/null @@ -1,49 +0,0 @@ -%% -%% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2001-2013. All Rights Reserved. -%% -%% The contents of this file are subject to the Erlang Public License, -%% Version 1.1, (the "License"); you may not use this file except in -%% compliance with the License. You should have received a copy of the -%% Erlang Public License along with this software. If not, it can be -%% retrieved online at http://www.erlang.org/. -%% -%% Software distributed under the License is distributed on an "AS IS" -%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See -%% the License for the specific language governing rights and limitations -%% under the License. -%% -%% %CopyrightEnd% -%% -%% --module(asn1_wrapper). --author('kenneth@bilbo'). - --compile(export_all). -%%-export([Function/Arity, ...]). - - -encode(Module,Type,Value) -> - case asn1rt:encode(Module,Type,Value) of - {ok,X} when is_binary(X) -> - {ok, binary_to_list(X)}; - {ok,X} -> - {ok, binary_to_list(list_to_binary(X))}; - Error -> - Error - end. - -decode(Module, Type, Bytes) when is_binary(Bytes) -> - asn1rt:decode(Module, Type, Bytes); -decode(Module, Type, Bytes) when is_list(Bytes) -> - asn1rt:decode(Module, Type, list_to_binary(Bytes)). - -erule(ber) -> - ber; -erule(per) -> - per; -erule(uper) -> - per. - - diff --git a/lib/asn1/test/ber_decode_error.erl b/lib/asn1/test/ber_decode_error.erl index 1c4b4c6894..8be92292ee 100644 --- a/lib/asn1/test/ber_decode_error.erl +++ b/lib/asn1/test/ber_decode_error.erl @@ -22,15 +22,15 @@ -export([run/1]). run([]) -> - {ok,B} = asn1_wrapper:encode('Constructed','S3',{'S3',17}), - [T,L|V] = lists:flatten(B), - Bytes = [T,L+3|V] ++ [2,1,3], - case asn1_wrapper:decode('Constructed','S3',Bytes) of + {ok,B} = 'Constructed':encode('S3', {'S3',17}), + [T,L|V] = binary_to_list(B), + Bytes = list_to_binary([T,L+3|V] ++ [2,1,3]), + case 'Constructed':decode('S3', Bytes) of {error,{asn1,{unexpected,_}}} -> ok end, %% Unexpected bytes must be accepted if there is an extensionmark - {ok,{'S3ext',17}} = asn1_wrapper:decode('Constructed','S3ext',Bytes), + {ok,{'S3ext',17}} = 'Constructed':decode('S3ext', Bytes), %% Truncated tag. {error,{asn1,{invalid_tag,_}}} = diff --git a/lib/asn1/test/choice_extension.erl b/lib/asn1/test/choice_extension.erl deleted file mode 100644 index 85e0936ebf..0000000000 --- a/lib/asn1/test/choice_extension.erl +++ /dev/null @@ -1,37 +0,0 @@ -%% -%% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1999-2010. All Rights Reserved. -%% -%% The contents of this file are subject to the Erlang Public License, -%% Version 1.1, (the "License"); you may not use this file except in -%% compliance with the License. You should have received a copy of the -%% Erlang Public License along with this software. If not, it can be -%% retrieved online at http://www.erlang.org/. -%% -%% Software distributed under the License is distributed on an "AS IS" -%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See -%% the License for the specific language governing rights and limitations -%% under the License. -%% -%% %CopyrightEnd% -%% -%% --module(choice_extension). - --export([run/0, compile/3]). - --include_lib("test_server/include/test_server.hrl"). - -compile(Config,Rules,Options) -> - - ?line DataDir = ?config(data_dir,Config), - ?line OutDir = ?config(priv_dir,Config), - ?line true = code:add_patha(?config(priv_dir,Config)), - ?line ok = asn1ct:compile(DataDir ++ "ChoExtension",[Rules,{outdir,OutDir}]++Options). - -run() -> - Val = {str,"abc"}, - ?line {ok,B} = asn1_wrapper:encode('ChoExtension','ChoExt4',Val), - ?line {ok,Val} = asn1_wrapper:decode('ChoExtension','ChoExt4',lists:flatten(B)), - ok. diff --git a/lib/asn1/test/error_SUITE.erl b/lib/asn1/test/error_SUITE.erl index a94a6d95a0..6451f81c01 100644 --- a/lib/asn1/test/error_SUITE.erl +++ b/lib/asn1/test/error_SUITE.erl @@ -19,7 +19,7 @@ -module(error_SUITE). -export([suite/0,all/0,groups/0, - already_defined/1,enumerated/1]). + already_defined/1,enumerated/1,objects/1]). -include_lib("test_server/include/test_server.hrl"). @@ -30,7 +30,8 @@ all() -> groups() -> [{p,parallel(),[already_defined, - enumerated]}]. + enumerated, + objects]}]. parallel() -> case erlang:system_info(schedulers) > 1 of @@ -95,6 +96,48 @@ enumerated(Config) -> } = run(P, Config), ok. +objects(Config) -> + M = 'Objects', + P = {M, + <<"Objects DEFINITIONS AUTOMATIC TAGS ::= BEGIN\n" + " obj1 CL ::= { &wrong 42 }\n" + " obj2 CL ::= { &wrong 1, &Wrong INTEGER }\n" + " obj3 CL ::= { &Data OCTET STRING }\n" + " obj4 SMALL ::= { &code 42 }\n" + " InvalidSet CL ::= { obj1 }\n" + + " CL ::= CLASS {\n" + " &code INTEGER UNIQUE,\n" + " &enum ENUMERATED { a, b, c},\n" + " &Data,\n" + " &object CL,\n" + " &Set CL,\n" + " &vartypevalue &Data,\n" + " &VarTypeValue &Data\n" + " }\n" + + " SMALL ::= CLASS {\n" + " &code INTEGER UNIQUE,\n" + " &i INTEGER\n" + " }\n" + "END\n">>}, + {error, + [ + {structured_error,{M,2},asn1ct_check, + {invalid_fields,[wrong],obj1}}, + {structured_error,{M,3},asn1ct_check, + {invalid_fields,['Wrong',wrong],obj2}}, + {structured_error,{M,4},asn1ct_check, + {missing_mandatory_fields,['Set','VarTypeValue',code, + enum,object,vartypevalue],obj3}}, + {structured_error,{M,5},asn1ct_check, + {missing_mandatory_fields,[i],obj4}}, + {structured_error,{M,6},asn1ct_check, + {invalid_fields,[wrong],'InvalidSet'}} + ] + } = run(P, Config), + ok. + run({Mod,Spec}, Config) -> diff --git a/lib/asn1/test/h323test.erl b/lib/asn1/test/h323test.erl index 426ae16994..3baaa994ea 100644 --- a/lib/asn1/test/h323test.erl +++ b/lib/asn1/test/h323test.erl @@ -26,44 +26,62 @@ run(per) -> run(); run(_Rules) -> ok. run() -> - alerting(), - connect(), + roundtrip('H323-UserInformation', alerting_val(), alerting_enc()), + roundtrip('H323-UserInformation', connect_val(), connect_enc()), + general_string(), ok. -dec_alerting() -> - Cs = "0380060008914a0002020120110000000000000000000000000000000000", - ByteList = hexstr2bytes(Cs), - asn1_wrapper:decode('H323-MESSAGES','H323-UserInformation',ByteList). +alerting_val() -> + {'H323-UserInformation', + {'H323-UU-PDU', + {alerting, + {'Alerting-UUIE', + {0,0,8,2250,0,2}, + {'EndpointType',asn1_NOVALUE,asn1_NOVALUE,asn1_NOVALUE, + asn1_NOVALUE,asn1_NOVALUE, + {'TerminalInfo',asn1_NOVALUE}, + false,false}, + asn1_NOVALUE, + {'CallIdentifier',[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}, + asn1_NOVALUE,asn1_NOVALUE,asn1_NOVALUE,asn1_NOVALUE}}, + asn1_NOVALUE,asn1_NOVALUE,asn1_NOVALUE,asn1_NOVALUE,asn1_NOVALUE}, + asn1_NOVALUE}. -enc_alerting(V) -> - asn1_wrapper:encode('H323-MESSAGES','H323-UserInformation',V). +alerting_enc() -> + "0380060008914a0002020120110000000000000000000000000000000000". -alerting() -> - {ok,V} = dec_alerting(), - {ok,B} = enc_alerting(V), - ByteList = lists:flatten(B), - {ok,V} = asn1_wrapper:decode('H323-MESSAGES','H323-UserInformation',ByteList). +connect_val() -> + {'H323-UserInformation', + {'H323-UU-PDU', + {connect, + {'Connect-UUIE', + {0,0,8,2250,0,2}, + {ipAddress, + {'TransportAddress_ipAddress',[136,225,41,58],1187}}, + {'EndpointType',asn1_NOVALUE, + {'VendorIdentifier', + {'H221NonStandard',181,0,21324}, + [77,105,99,114,111,115,111,102,116,174,32,78,101,116, + 77,101,100,116,105,110,103,174,0], + [51,46,48,0]}, + asn1_NOVALUE,asn1_NOVALUE,asn1_NOVALUE, + {'TerminalInfo',asn1_NOVALUE}, + false,false}, + [22,137,237,197,191,35,211,17,140,45,0,192,79,75,28,208], + {'CallIdentifier',[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}, + asn1_NOVALUE,asn1_NOVALUE,asn1_NOVALUE,asn1_NOVALUE}}, + asn1_NOVALUE,asn1_NOVALUE,asn1_NOVALUE,asn1_NOVALUE,asn1_NOVALUE}, + asn1_NOVALUE}. +connect_enc() -> + "02c0060008914a00020088e1293a04a322c0b500534c164d6963726f736f6674ae204e65744d656474696e67ae0003332e3000001689edc5bf23d3118c2d00c04f4b1cd00900110000000000000000000000000000000000". -dec_connect() -> - Cs = "02c0060008914a00020088e1293a04a322c0b500534c164d6963726f736f6674ae204e65744d656474696e67ae0003332e3000001689edc5bf23d3118c2d00c04f4b1cd00900110000000000000000000000000000000000", - ByteList = hexstr2bytes(Cs), - asn1_wrapper:decode('H323-MESSAGES','H323-UserInformation',ByteList). +general_string() -> + Type = 'MultimediaSystemControlMessage', + UI = <<109,64,1,57>>, + {ok, _V} = 'MULTIMEDIA-SYSTEM-CONTROL':decode(Type, UI). -enc_connect(V) -> - asn1_wrapper:encode('H323-MESSAGES','H323-UserInformation',V). - -connect() -> - {ok,V} = dec_connect(), - {ok,B} = enc_connect(V), - ByteList = lists:flatten(B), - {ok,V} = asn1_wrapper:decode('H323-MESSAGES','H323-UserInformation',ByteList). - -hexstr2bytes([D1,D2|T]) -> - [dig2num(D1)*16+dig2num(D2)|hexstr2bytes(T)]; -hexstr2bytes([]) -> - []. - -dig2num(D) when D >= $0, D =< $9 -> D - $0; -dig2num(D) when D >= $a, D =< $f -> 10 + D - $a; -dig2num(D) when D >= $A, D =< $F -> 10 + D - $A. +roundtrip(T, V, HexString) -> + Enc = asn1_test_lib:hex_to_bin(HexString), + Enc = asn1_test_lib:roundtrip_enc('H323-MESSAGES', T, V), + ok. diff --git a/lib/asn1/test/pem_performance.erl b/lib/asn1/test/pem_performance.erl deleted file mode 100644 index 87b8cbd61d..0000000000 --- a/lib/asn1/test/pem_performance.erl +++ /dev/null @@ -1,37 +0,0 @@ -%% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2012. All Rights Reserved. -%% -%% The contents of this file are subject to the Erlang Public License, -%% Version 1.1, (the "License"); you may not use this file except in -%% compliance with the License. You should have received a copy of the -%% Erlang Public License along with this software. If not, it can be -%% retrieved online at http://www.erlang.org/. -%% -%% Software distributed under the License is distributed on an "AS IS" -%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See -%% the License for the specific language governing rights and limitations -%% under the License. -%% -%% %CopyrightEnd% - --module([cert_pem/0]). --module([dsa_pem/0]). - -cert_pem() -> - 'OTP-PUB-KEY':decode('Certificate',<<48,130,3,184,48,130,3,33,160,3,2,1,2,2,1,1,48,13,6,9,42,134,72,134,247,13,1,1,5,5,0,48,129,131,49,14,48,12,6,3,85,4,3,19,5,111,116,112,67,65,49,19,48,17,6,3,85,4,11,19,10,69,114,108,97,110,103,32,79,84,80,49,20,48,18,6,3,85,4,10,19,11,69,114,105,99,115,115,111,110,32,65,66,49,11,48,9,6,3,85,4,6,19,2,83,69,49,18,48,16,6,3,85,4,7,19,9,83,116,111,99,107,104,111,108,109,49,37,48,35,6,9,42,134,72,134,247,13,1,9,1,22,22,112,101,116,101,114,64,101,114,105,120,46,101,114,105,99,115,115,111,110,46,115,101,48,30,23,13,48,56,48,49,48,57,48,56,50,57,51,48,90,23,13,49,55,49,49,49,55,48,56,50,57,51,48,90,48,129,132,49,15,48,13,6,3,85,4,3,19,6,99,108,105,101,110,116,49,19,48,17,6,3,85,4,11,19,10,69,114,108,97,110,103,32,79,84,80,49,20,48,18,6,3,85,4,10,19,11,69,114,105,99,115,115,111,110,32,65,66,49,11,48,9,6,3,85,4,6,19,2,83,69,49,18,48,16,6,3,85,4,7,19,9,83,116,111,99,107,104,111,108,109,49,37,48,35,6,9,42,134,72,134,247,13,1,9,1,22,22,112,101,116,101,114,64,101,114,105,120,46,101,114,105,99,115,115,111,110,46,115,101,48,129,159,48,13,6,9,42,134,72,134,247,13,1,1,1,5,0,3,129,141,0,48,129,137,2,129,129,0,245,56,68,254,220,239,193,190,63,221,182,60,67,77,121,163,214,136,137,183,139,8,166,30,100,27,45,17,126,58,15,173,151,218,75,224,148,14,22,164,10,100,186,183,104,175,197,97,96,182,146,150,106,129,140,100,194,106,90,62,133,233,155,46,155,33,101,220,83,193,182,232,240,99,253,249,114,8,159,172,143,77,179,132,229,205,29,110,185,233,224,52,25,149,249,100,80,229,199,125,23,106,146,233,159,26,13,8,161,206,221,43,240,149,42,45,194,190,85,6,235,152,220,219,160,32,144,67,2,3,1,0,1,163,130,1,55,48,130,1,51,48,9,6,3,85,29,19,4,2,48,0,48,11,6,3,85,29,15,4,4,3,2,5,224,48,29,6,3,85,29,14,4,22,4,20,26,59,44,5,72,211,158,214,23,34,30,241,125,27,123,115,93,163,231,120,48,129,179,6,3,85,29,35,4,129,171,48,129,168,128,20,6,171,128,52,58,164,184,118,178,189,157,46,40,229,109,145,222,125,1,155,161,129,140,164,129,137,48,129,134,49,17,48,15,6,3,85,4,3,19,8,101,114,108,97,110,103,67,65,49,19,48,17,6,3,85,4,11,19,10,69,114,108,97,110,103,32,79,84,80,49,20,48,18,6,3,85,4,10,19,11,69,114,105,99,115,115,111,110,32,65,66,49,18,48,16,6,3,85,4,7,19,9,83,116,111,99,107,104,111,108,109,49,11,48,9,6,3,85,4,6,19,2,83,69,49,37,48,35,6,9,42,134,72,134,247,13,1,9,1,22,22,112,101,116,101,114,64,101,114,105,120,46,101,114,105,99,115,115,111,110,46,115,101,130,1,1,48,33,6,3,85,29,17,4,26,48,24,129,22,112,101,116,101,114,64,101,114,105,120,46,101,114,105,99,115,115,111,110,46,115,101,48,33,6,3,85,29,18,4,26,48,24,129,22,112,101,116,101,114,64,101,114,105,120,46,101,114,105,99,115,115,111,110,46,115,101,48,13,6,9,42,134,72,134,247,13,1,1,5,5,0,3,129,129,0,93,11,112,227,121,15,121,179,247,135,110,216,17,197,84,18,149,166,147,142,190,178,0,209,190,0,142,233,144,100,194,205,220,182,73,204,108,42,95,23,48,63,4,120,239,42,194,25,184,35,117,107,96,229,18,45,76,122,125,40,171,210,132,50,146,178,160,55,17,35,255,208,114,30,47,55,185,154,155,165,204,180,14,143,20,234,6,234,201,225,72,235,5,87,61,255,250,23,217,1,144,246,98,221,223,102,49,168,177,13,70,241,26,27,254,251,217,14,244,18,242,197,151,50,186,214,15,42>>). - -dsa_pem() -> - 'OTP-PUB-KEY':decode('DSAPrivateKey',<<48,130,1,187,2,1,0,2,129,129,0,183,179,230,217,37,99,144,157,21,228,204,162,207,61,246,144,58,139,139,184,184,43,108,206,0,115,173,208,100,233,201,121,21,90,179,119,53,140,25,52,34,202,121,211,164,107,43,56,68,162,159,51,244,232,138,126,164,109,121,89,237,142,57,28,32,188,44,67,253,111,121,104,40,141,211,255,140,118,37,234,150,201,155,160,16,17,51,59,26,249,41,129,16,211,119,128,95,254,182,235,132,0,92,206,93,77,106,217,201,132,203,4,75,201,246,204,216,162,1,84,79,211,10,21,152,195,103,145,2,21,0,213,30,184,86,247,16,247,69,192,241,35,138,84,57,140,3,71,65,206,233,2,129,129,0,148,179,24,63,74,91,128,25,96,29,5,78,223,246,175,0,121,86,54,178,42,231,98,241,147,180,157,60,149,160,50,243,227,76,175,89,234,203,252,242,76,108,9,204,157,182,59,206,227,127,99,215,42,156,194,78,116,25,7,62,243,169,45,5,101,179,247,127,199,144,135,103,23,42,154,125,231,248,154,101,175,155,101,42,232,41,80,41,47,128,208,11,31,106,63,12,202,207,135,80,200,136,250,171,31,118,52,91,200,138,112,111,179,23,214,123,21,118,194,179,0,185,217,52,197,182,236,13,2,129,128,124,66,0,111,121,139,142,209,95,136,95,237,177,150,248,252,49,135,117,100,155,232,138,244,132,89,40,5,70,125,202,96,78,239,76,37,125,149,82,64,107,54,227,73,25,180,227,41,0,234,73,47,80,242,242,129,250,61,68,62,39,38,156,193,146,40,241,247,106,215,223,202,194,110,130,62,186,90,18,28,196,174,99,47,193,61,130,100,150,25,248,115,164,231,153,99,46,69,66,139,33,187,51,49,35,219,234,29,44,172,166,247,42,16,177,187,9,162,81,243,33,26,100,46,78,57,203,135,2,20,89,128,159,14,187,249,182,172,15,88,162,110,211,71,179,209,29,125,217,38>>), - 'OTP-PUB-KEY':decode('SubjectPublicKeyInfo',<<48,130,1,183,48,130,1,44,6,7,42,134,72,206,56,4,1,48,130,1,31,2,129,129,0,183,179,230,217,37,99,144,157,21,228,204,162,207,61,246,144,58,139,139,184,184,43,108,206,0,115,173,208,100,233,201,121,21,90,179,119,53,140,25,52,34,202,121,211,164,107,43,56,68,162,159,51,244,232,138,126,164,109,121,89,237,142,57,28,32,188,44,67,253,111,121,104,40,141,211,255,140,118,37,234,150,201,155,160,16,17,51,59,26,249,41,129,16,211,119,128,95,254,182,235,132,0,92,206,93,77,106,217,201,132,203,4,75,201,246,204,216,162,1,84,79,211,10,21,152,195,103,145,2,21,0,213,30,184,86,247,16,247,69,192,241,35,138,84,57,140,3,71,65,206,233,2,129,129,0,148,179,24,63,74,91,128,25,96,29,5,78,223,246,175,0,121,86,54,178,42,231,98,241,147,180,157,60,149,160,50,243,227,76,175,89,234,203,252,242,76,108,9,204,157,182,59,206,227,127,99,215,42,156,194,78,116,25,7,62,243,169,45,5,101,179,247,127,199,144,135,103,23,42,154,125,231,248,154,101,175,155,101,42,232,41,80,41,47,128,208,11,31,106,63,12,202,207,135,80,200,136,250,171,31,118,52,91,200,138,112,111,179,23,214,123,21,118,194,179,0,185,217,52,197,182,236,13,3,129,132,0,2,129,128,124,66,0,111,121,139,142,209,95,136,95,237,177,150,248,252,49,135,117,100,155,232,138,244,132,89,40,5,70,125,202,96,78,239,76,37,125,149,82,64,107,54,227,73,25,180,227,41,0,234,73,47,80,242,242,129,250,61,68,62,39,38,156,193,146,40,241,247,106,215,223,202,194,110,130,62,186,90,18,28,196,174,99,47,193,61,130,100,150,25,248,115,164,231,153,99,46,69,66,139,33,187,51,49,35,219,234,29,44,172,166,247,42,16,177,187,9,162,81,243,33,26,100,46,78,57,203,135>>), - 'OTP-PUB-KEY':decode('DSAParams',<<48,130,1,31,2,129,129,0,183,179,230,217,37,99,144,157,21,228,204,162,207,61,246,144,58,139,139,184,184,43,108,206,0,115,173,208,100,233,201,121,21,90,179,119,53,140,25,52,34,202,121,211,164,107,43,56,68,162,159,51,244,232,138,126,164,109,121,89,237,142,57,28,32,188,44,67,253,111,121,104,40,141,211,255,140,118,37,234,150,201,155,160,16,17,51,59,26,249,41,129,16,211,119,128,95,254,182,235,132,0,92,206,93,77,106,217,201,132,203,4,75,201,246,204,216,162,1,84,79,211,10,21,152,195,103,145,2,21,0,213,30,184,86,247,16,247,69,192,241,35,138,84,57,140,3,71,65,206,233,2,129,129,0,148,179,24,63,74,91,128,25,96,29,5,78,223,246,175,0,121,86,54,178,42,231,98,241,147,180,157,60,149,160,50,243,227,76,175,89,234,203,252,242,76,108,9,204,157,182,59,206,227,127,99,215,42,156,194,78,116,25,7,62,243,169,45,5,101,179,247,127,199,144,135,103,23,42,154,125,231,248,154,101,175,155,101,42,232,41,80,41,47,128,208,11,31,106,63,12,202,207,135,80,200,136,250,171,31,118,52,91,200,138,112,111,179,23,214,123,21,118,194,179,0,185,217,52,197,182,236,13>>), - 'OTP-PUB-KEY':decode('DSAPublicKey',<<2,129,128,124,66,0,111,121,139,142,209,95,136,95,237,177,150,248,252,49,135,117,100,155,232,138,244,132,89,40,5,70,125,202,96,78,239,76,37,125,149,82,64,107,54,227,73,25,180,227,41,0,234,73,47,80,242,242,129,250,61,68,62,39,38,156,193,146,40,241,247,106,215,223,202,194,110,130,62,186,90,18,28,196,174,99,47,193,61,130,100,150,25,248,115,164,231,153,99,46,69,66,139,33,187,51,49,35,219,234,29,44,172,166,247,42,16,177,187,9,162,81,243,33,26,100,46,78,57,203,135>>), - 'OTP-PUB-KEY':encode('DSAParams',{params,{'Dss-Parms',129000451850199666185842362389296595317127259539517666765336291347244303954511451744518587442120964433734460998523119938005801396466878889993179871123036311260456172022864663021425348874648247531097042575063545128239655736096045972718934778583429973433661785691086624069991876932064334822608460064613803976593,1216700114794736143432235288305776850295620488937,104420402274523493329542694749036577763086597934731674202966304958550599470165597750883637440049774107540742087494301536297571301945349213110548764383811017178451900599240379681904765817950545426764751538502808499880604633364255316249231153053427235538288687666086821781456733226598288985591031656134573747213}}), - 'OTP-PUB-KEY':encode( - 'SubjectPublicKeyInfo', - {'SubjectPublicKeyInfo', - {'AlgorithmIdentifier', - {1,2,840,10040,4,1}, - <<48,130,1,31,2,129,129,0,183,179,230,217,37,99,144,157,21,228,204,162,207,61,246,144,58,139,139,184,184,43,108,206,0,115,173,208,100,233,201,121,21,90,179,119,53,140,25,52,34,202,121,211,164,107,43,56,68,162,159,51,244,232,138,126,164,109,121,89,237,142,57,28,32,188,44,67,253,111,121,104,40,141,211,255,140,118,37,234,150,201,155,160,16,17,51,59,26,249,41,129,16,211,119,128,95,254,182,235,132,0,92,206,93,77,106,217,201,132,203,4,75,201,246,204,216,162,1,84,79,211,10,21,152,195,103,145,2,21,0,213,30,184,86,247,16,247,69,192,241,35,138,84,57,140,3,71,65,206,233,2,129,129,0,148,179,24,63,74,91,128,25,96,29,5,78,223,246,175,0,121,86,54,178,42,231,98,241,147,180,157,60,149,160,50,243,227,76,175,89,234,203,252,242,76,108,9,204,157,182,59,206,227,127,99,215,42,156,194,78,116,25,7,62,243,169,45,5,101,179,247,127,199,144,135,103,23,42,154,125,231,248,154,101,175,155,101,42,232,41,80,41,47,128,208,11,31,106,63,12,202,207,135,80,200,136,250,171,31,118,52,91,200,138,112,111,179,23,214,123,21,118,194,179,0,185,217,52,197,182,236,13>>}, - {0, - <<2,129,128,124,66,0,111,121,139,142,209,95,136,95,237,177,150,248,252,49,135,117,100,155,232,138,244,132,89,40,5,70,125,202,96,78,239,76,37,125,149,82,64,107,54,227,73,25,180,227,41,0,234,73,47,80,242,242,129,250,61,68,62,39,38,156,193,146,40,241,247,106,215,223,202,194,110,130,62,186,90,18,28,196,174,99,47,193,61,130,100,150,25,248,115,164,231,153,99,46,69,66,139,33,187,51,49,35,219,234,29,44,172,166,247,42,16,177,187,9,162,81,243,33,26,100,46,78,57,203,135>>}}). diff --git a/lib/asn1/test/testChoExtension.erl b/lib/asn1/test/testChoExtension.erl index c6a07646c2..e54cbe825b 100644 --- a/lib/asn1/test/testChoExtension.erl +++ b/lib/asn1/test/testChoExtension.erl @@ -31,10 +31,7 @@ extension(_Rules) -> %% A trick to encode with another compatible CHOICE type to test reception %% extension alternative - {ok,Bytes2x} = asn1_wrapper:encode('ChoExtension','ChoExt1x',{str,"abc"}), - {ok,Val2x} = - asn1_wrapper:decode('ChoExtension','ChoExt1',lists:flatten(Bytes2x)), - io:format("Choice extension alternative = ~p~n",[Val2x]), + roundtrip('ChoExt1x', {str,"abc"}), roundtrip('ChoExt2', {bool,true}), roundtrip('ChoExt2', {int,33}), @@ -51,6 +48,4 @@ extension(_Rules) -> roundtrip(Type, Value) -> - {ok,Encoded} = 'ChoExtension':encode(Type, Value), - {ok,Value} = 'ChoExtension':decode(Type, Encoded), - ok. + asn1_test_lib:roundtrip('ChoExtension', Type, Value). diff --git a/lib/asn1/test/testChoExternal.erl b/lib/asn1/test/testChoExternal.erl index 5fdee48add..12abdbb2bc 100644 --- a/lib/asn1/test/testChoExternal.erl +++ b/lib/asn1/test/testChoExternal.erl @@ -18,25 +18,11 @@ %% %% -module(testChoExternal). - - --export([compile/3]). -export([external/1]). -include_lib("test_server/include/test_server.hrl"). -include("External.hrl"). - - -compile(Config, Rules, Optimize) -> - DataDir = ?config(data_dir, Config), - CaseDir = ?config(case_dir, Config), - true = code:add_patha(CaseDir), - ok = asn1ct:compile(DataDir ++ "ChoExternal", - [Rules, {outdir, CaseDir}] ++ Optimize). - - - external(_Rules) -> roundtrip('ChoXCho', {boolCho,true}), roundtrip('ChoXCho', {intCho,77}), @@ -59,6 +45,4 @@ external(_Rules) -> ok. roundtrip(Type, Value) -> - {ok,Encoded} = 'ChoExternal':encode(Type, Value), - {ok,Value} = 'ChoExternal':decode(Type, Encoded), - ok. + asn1_test_lib:roundtrip('ChoExternal', Type, Value). diff --git a/lib/asn1/test/testChoOptional.erl b/lib/asn1/test/testChoOptional.erl index cbb8134e51..f5e77cb721 100644 --- a/lib/asn1/test/testChoOptional.erl +++ b/lib/asn1/test/testChoOptional.erl @@ -18,83 +18,30 @@ %% %% -module(testChoOptional). +-export([run/0]). --export([optional/1]). +-record('Seq1', {bool, int = asn1_NOVALUE, cho = asn1_NOVALUE}). +-record('Seq2', {int = asn1_NOVALUE, cho = asn1_NOVALUE, bool}). +-record('Seq3', {cho = asn1_NOVALUE, int = asn1_NOVALUE, bool}). -%-include("ChoOptional.hrl"). --include_lib("test_server/include/test_server.hrl"). --include("External.hrl"). +run() -> + roundtrip('Seq1', #'Seq1'{bool=true,int=asn1_NOVALUE,cho=asn1_NOVALUE}), + roundtrip('Seq1', #'Seq1'{bool=true,int=233,cho=asn1_NOVALUE}), + roundtrip('Seq1', #'Seq1'{bool=true,int=asn1_NOVALUE,cho={vsCho,"Vs Str"}}), + roundtrip('Seq1', #'Seq1'{bool=true,int=asn1_NOVALUE,cho={ocStrCho,"Oct Str"}}), + roundtrip('Seq2', #'Seq2'{int=asn1_NOVALUE,cho=asn1_NOVALUE,bool=true}), + roundtrip('Seq2', #'Seq2'{int=233,cho=asn1_NOVALUE,bool=true}), + roundtrip('Seq2', #'Seq2'{int=asn1_NOVALUE,cho={vsCho,"Vs Str"},bool=true}), + roundtrip('Seq2', #'Seq2'{int=asn1_NOVALUE,cho={ocStrCho,"Oct Str"},bool=true}), + roundtrip('Seq3', #'Seq3'{cho=asn1_NOVALUE,int=asn1_NOVALUE,bool=true}), + roundtrip('Seq3', #'Seq3'{cho=asn1_NOVALUE,int=233,bool=true}), + roundtrip('Seq3', #'Seq3'{cho={vsCho,"Vs Str"},int=asn1_NOVALUE,bool=true}), + roundtrip('Seq3', #'Seq3'{cho={ocStrCho,"Oct Str"},int=asn1_NOVALUE,bool=true}), + ok. --record('Seq1',{bool, int = asn1_NOVALUE, cho = asn1_NOVALUE}). --record('Seq2',{int = asn1_NOVALUE, cho = asn1_NOVALUE, bool}). --record('Seq3',{cho = asn1_NOVALUE, int = asn1_NOVALUE, bool}). +roundtrip(Type, Value) -> + roundtrip('ChoOptional', Type, Value), + roundtrip('ChoOptionalImplicitTag', Type, Value). -optional(_Rules) -> - - ?line {ok,Bytes11} = asn1_wrapper:encode('ChoOptional','Seq1',#'Seq1'{bool = true}), - ?line {ok,{'Seq1',true,asn1_NOVALUE,asn1_NOVALUE}} = - asn1_wrapper:decode('ChoOptional','Seq1',lists:flatten(Bytes11)), - - ?line {ok,Bytes12} = asn1_wrapper:encode('ChoOptional','Seq1',#'Seq1'{bool = true, - int = 233}), - ?line {ok,{'Seq1',true,233,asn1_NOVALUE}} = - asn1_wrapper:decode('ChoOptional','Seq1',lists:flatten(Bytes12)), - - ?line {ok,Bytes13} = asn1_wrapper:encode('ChoOptional','Seq1',#'Seq1'{bool = true, - cho = {vsCho,"Vs Str"}}), - ?line {ok,{'Seq1',true,asn1_NOVALUE,{vsCho,"Vs Str"}}} = - asn1_wrapper:decode('ChoOptional','Seq1',lists:flatten(Bytes13)), - - ?line {ok,Bytes14} = - asn1_wrapper:encode('ChoOptional','Seq1',#'Seq1'{bool = true, - cho = {ocStrCho,"Oct Str"}}), - ?line {ok,{'Seq1',true,asn1_NOVALUE,{ocStrCho,"Oct Str"}}} = - asn1_wrapper:decode('ChoOptional','Seq1',lists:flatten(Bytes14)), - - - - ?line {ok,Bytes21} = asn1_wrapper:encode('ChoOptional','Seq2',#'Seq2'{bool = true}), - ?line {ok,{'Seq2',asn1_NOVALUE,asn1_NOVALUE,true}} = - asn1_wrapper:decode('ChoOptional','Seq2',lists:flatten(Bytes21)), - - ?line {ok,Bytes22} = asn1_wrapper:encode('ChoOptional','Seq2',#'Seq2'{bool = true, - int = 233}), - ?line {ok,{'Seq2',233,asn1_NOVALUE,true}} = - asn1_wrapper:decode('ChoOptional','Seq2',lists:flatten(Bytes22)), - - ?line {ok,Bytes23} = asn1_wrapper:encode('ChoOptional','Seq2',#'Seq2'{bool = true, - cho = {vsCho,"Vs Str"}}), - ?line {ok,{'Seq2',asn1_NOVALUE,{vsCho,"Vs Str"},true}} = - asn1_wrapper:decode('ChoOptional','Seq2',lists:flatten(Bytes23)), - - ?line {ok,Bytes24} = - asn1_wrapper:encode('ChoOptional','Seq2',#'Seq2'{bool = true, - cho = {ocStrCho,"Oct Str"}}), - ?line {ok,{'Seq2',asn1_NOVALUE,{ocStrCho,"Oct Str"},true}} = - asn1_wrapper:decode('ChoOptional','Seq2',lists:flatten(Bytes24)), - - - - ?line {ok,Bytes31} = asn1_wrapper:encode('ChoOptional','Seq3',#'Seq3'{bool = true}), - ?line {ok,{'Seq3',asn1_NOVALUE,asn1_NOVALUE,true}} = - asn1_wrapper:decode('ChoOptional','Seq3',lists:flatten(Bytes31)), - - ?line {ok,Bytes32} = asn1_wrapper:encode('ChoOptional','Seq3',#'Seq3'{bool = true, - int = 233}), - ?line {ok,{'Seq3',asn1_NOVALUE,233,true}} = - asn1_wrapper:decode('ChoOptional','Seq3',lists:flatten(Bytes32)), - - ?line {ok,Bytes33} = asn1_wrapper:encode('ChoOptional','Seq3',#'Seq3'{bool = true, - cho = {vsCho,"Vs Str"}}), - ?line {ok,{'Seq3',{vsCho,"Vs Str"},asn1_NOVALUE,true}} = - asn1_wrapper:decode('ChoOptional','Seq3',lists:flatten(Bytes33)), - - ?line {ok,Bytes34} = - asn1_wrapper:encode('ChoOptional','Seq3',#'Seq3'{bool = true, - cho = {ocStrCho,"Oct Str"}}), - ?line {ok,{'Seq3',{ocStrCho,"Oct Str"},asn1_NOVALUE,true}} = - asn1_wrapper:decode('ChoOptional','Seq3',lists:flatten(Bytes34)), - - - - ok. +roundtrip(Mod, Type, Value) -> + asn1_test_lib:roundtrip(Mod, Type, Value). diff --git a/lib/asn1/test/testChoOptionalImplicitTag.erl b/lib/asn1/test/testChoOptionalImplicitTag.erl deleted file mode 100644 index efe335cabd..0000000000 --- a/lib/asn1/test/testChoOptionalImplicitTag.erl +++ /dev/null @@ -1,101 +0,0 @@ -%% -%% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1999-2012. All Rights Reserved. -%% -%% The contents of this file are subject to the Erlang Public License, -%% Version 1.1, (the "License"); you may not use this file except in -%% compliance with the License. You should have received a copy of the -%% Erlang Public License along with this software. If not, it can be -%% retrieved online at http://www.erlang.org/. -%% -%% Software distributed under the License is distributed on an "AS IS" -%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See -%% the License for the specific language governing rights and limitations -%% under the License. -%% -%% %CopyrightEnd% -%% -%% --module(testChoOptionalImplicitTag). - - --export([optional/1]). - -%-include("ChoOptional.hrl"). --include_lib("test_server/include/test_server.hrl"). --include("External.hrl"). - --record('Seq1',{bool, int = asn1_NOVALUE, cho = asn1_NOVALUE}). --record('Seq2',{int = asn1_NOVALUE, cho = asn1_NOVALUE, bool}). --record('Seq3',{cho = asn1_NOVALUE, int = asn1_NOVALUE, bool}). - -optional(_Rules) -> - - ?line {ok,Bytes11} = asn1_wrapper:encode('ChoOptionalImplicitTag','Seq1',#'Seq1'{bool = true}), - ?line {ok,{'Seq1',true,asn1_NOVALUE,asn1_NOVALUE}} = - asn1_wrapper:decode('ChoOptionalImplicitTag','Seq1',lists:flatten(Bytes11)), - - ?line {ok,Bytes12} = asn1_wrapper:encode('ChoOptionalImplicitTag','Seq1',#'Seq1'{bool = true, - int = 233}), - ?line {ok,{'Seq1',true,233,asn1_NOVALUE}} = - asn1_wrapper:decode('ChoOptionalImplicitTag','Seq1',lists:flatten(Bytes12)), - - ?line {ok,Bytes13} = asn1_wrapper:encode('ChoOptionalImplicitTag','Seq1',#'Seq1'{bool = true, - cho = {vsCho,"Vs Str"}}), - ?line {ok,{'Seq1',true,asn1_NOVALUE,{vsCho,"Vs Str"}}} = - asn1_wrapper:decode('ChoOptionalImplicitTag','Seq1',lists:flatten(Bytes13)), - - ?line {ok,Bytes14} = - asn1_wrapper:encode('ChoOptionalImplicitTag','Seq1',#'Seq1'{bool = true, - cho = {ocStrCho,"Oct Str"}}), - ?line {ok,{'Seq1',true,asn1_NOVALUE,{ocStrCho,"Oct Str"}}} = - asn1_wrapper:decode('ChoOptionalImplicitTag','Seq1',lists:flatten(Bytes14)), - - - - ?line {ok,Bytes21} = asn1_wrapper:encode('ChoOptionalImplicitTag','Seq2',#'Seq2'{bool = true}), - ?line {ok,{'Seq2',asn1_NOVALUE,asn1_NOVALUE,true}} = - asn1_wrapper:decode('ChoOptionalImplicitTag','Seq2',lists:flatten(Bytes21)), - - ?line {ok,Bytes22} = asn1_wrapper:encode('ChoOptionalImplicitTag','Seq2',#'Seq2'{bool = true, - int = 233}), - ?line {ok,{'Seq2',233,asn1_NOVALUE,true}} = - asn1_wrapper:decode('ChoOptionalImplicitTag','Seq2',lists:flatten(Bytes22)), - - ?line {ok,Bytes23} = asn1_wrapper:encode('ChoOptionalImplicitTag','Seq2',#'Seq2'{bool = true, - cho = {vsCho,"Vs Str"}}), - ?line {ok,{'Seq2',asn1_NOVALUE,{vsCho,"Vs Str"},true}} = - asn1_wrapper:decode('ChoOptionalImplicitTag','Seq2',lists:flatten(Bytes23)), - - ?line {ok,Bytes24} = - asn1_wrapper:encode('ChoOptionalImplicitTag','Seq2',#'Seq2'{bool = true, - cho = {ocStrCho,"Oct Str"}}), - ?line {ok,{'Seq2',asn1_NOVALUE,{ocStrCho,"Oct Str"},true}} = - asn1_wrapper:decode('ChoOptionalImplicitTag','Seq2',lists:flatten(Bytes24)), - - - - ?line {ok,Bytes31} = asn1_wrapper:encode('ChoOptionalImplicitTag','Seq3',#'Seq3'{bool = true}), - ?line {ok,{'Seq3',asn1_NOVALUE,asn1_NOVALUE,true}} = - asn1_wrapper:decode('ChoOptionalImplicitTag','Seq3',lists:flatten(Bytes31)), - - ?line {ok,Bytes32} = asn1_wrapper:encode('ChoOptionalImplicitTag','Seq3',#'Seq3'{bool = true, - int = 233}), - ?line {ok,{'Seq3',asn1_NOVALUE,233,true}} = - asn1_wrapper:decode('ChoOptionalImplicitTag','Seq3',lists:flatten(Bytes32)), - - ?line {ok,Bytes33} = asn1_wrapper:encode('ChoOptionalImplicitTag','Seq3',#'Seq3'{bool = true, - cho = {vsCho,"Vs Str"}}), - ?line {ok,{'Seq3',{vsCho,"Vs Str"},asn1_NOVALUE,true}} = - asn1_wrapper:decode('ChoOptionalImplicitTag','Seq3',lists:flatten(Bytes33)), - - ?line {ok,Bytes34} = - asn1_wrapper:encode('ChoOptionalImplicitTag','Seq3',#'Seq3'{bool = true, - cho = {ocStrCho,"Oct Str"}}), - ?line {ok,{'Seq3',{ocStrCho,"Oct Str"},asn1_NOVALUE,true}} = - asn1_wrapper:decode('ChoOptionalImplicitTag','Seq3',lists:flatten(Bytes34)), - - - - ok. diff --git a/lib/asn1/test/testChoPrim.erl b/lib/asn1/test/testChoPrim.erl index 936a38f76c..4665de6989 100644 --- a/lib/asn1/test/testChoPrim.erl +++ b/lib/asn1/test/testChoPrim.erl @@ -25,80 +25,44 @@ -include_lib("test_server/include/test_server.hrl"). bool(Rules) -> - - ?line {ok,Bytes11} = asn1_wrapper:encode('ChoPrim','ChoCon',{bool0,true}), - ?line {ok,{bool0,true}} = asn1_wrapper:decode('ChoPrim','ChoCon',lists:flatten(Bytes11)), - - ?line {ok,Bytes12} = asn1_wrapper:encode('ChoPrim','ChoCon',{bool1,true}), - ?line {ok,{bool1,true}} = asn1_wrapper:decode('ChoPrim','ChoCon',lists:flatten(Bytes12)), - - ?line {ok,Bytes13} = asn1_wrapper:encode('ChoPrim','ChoCon',{int2,233}), - ?line {ok,{int2,233}} = asn1_wrapper:decode('ChoPrim','ChoCon',lists:flatten(Bytes13)), - - ?line case asn1_wrapper:erule(Rules) of - ber -> - ?line {error,{asn1,{invalid_choice_type,wrong}}} = - case catch asn1_wrapper:encode('ChoPrim','ChoCon',{wrong,233}) of - X1 -> X1 end, - ?line {error,{asn1,{invalid_choice_tag,_WrongTag}}} = - case catch asn1_wrapper:decode('ChoPrim','ChoCon',[131,2,0,233]) of - X2 -> X2 end, - ok; - - per -> - ok - end, - + roundtrip('ChoCon', {bool0,true}), + roundtrip('ChoCon', {bool1,true}), + roundtrip('ChoCon', {int2,233}), + case Rules of + ber -> + {error,{asn1,{invalid_choice_type,wrong}}} = + (catch 'ChoPrim':encode('ChoCon', {wrong,233})), + {error,{asn1,{invalid_choice_tag,_WrongTag}}} = + (catch 'ChoPrim':decode('ChoCon', <<131,2,0,233>>)); + per -> + ok; + uper -> + ok + end, ok. - - int(Rules) -> - - ?line {ok,Bytes21} = asn1_wrapper:encode('ChoPrim','ChoExp',{int10,1}), - ?line {ok,{int10,first}} = asn1_wrapper:decode('ChoPrim','ChoExp',lists:flatten(Bytes21)), - - ?line {ok,Bytes22} = asn1_wrapper:encode('ChoPrim','ChoExp',{int10,first}), - ?line {ok,{int10,first}} = asn1_wrapper:decode('ChoPrim','ChoExp',lists:flatten(Bytes22)), - - ?line {ok,Bytes23} = asn1_wrapper:encode('ChoPrim','ChoExp',{int10,last}), - ?line {ok,{int10,last}} = asn1_wrapper:decode('ChoPrim','ChoExp',lists:flatten(Bytes23)), - - ?line {ok,Bytes24} = asn1_wrapper:encode('ChoPrim','ChoExp',{bool11,true}), - ?line {ok,{bool11,true}} = asn1_wrapper:decode('ChoPrim','ChoExp',lists:flatten(Bytes24)), - - - ?line {ok,Bytes26} = asn1_wrapper:encode('ChoPrim','ChoExp',{enum12,one}), - ?line {ok,{enum12,one}} = asn1_wrapper:decode('ChoPrim','ChoExp',lists:flatten(Bytes26)), - - ?line {ok,Bytes25} = asn1_wrapper:encode('ChoPrim','ChoExp',{bool11,true}), - ?line {ok,{bool11,true}} = - asn1_wrapper:decode('ChoPrim','ChoExp',lists:flatten(Bytes25)), - - ?line {error,{asn1,_}} = - case catch asn1_wrapper:encode('ChoPrim','ChoExp',{enum12,four}) of - X3 -> X3 end, - - ?line {error,{asn1,_}} = - case catch asn1_wrapper:encode('ChoPrim','ChoExp',{wrong,233}) of - X4 -> io:format("error reason = ~p~n",[X4]), X4 end, - - ?line case asn1_wrapper:erule(Rules) of - ber -> - ?line {error,{asn1,_}} = - case catch asn1_wrapper:decode('ChoPrim','ChoExp',[107,3,2,1,1]) of - X5 -> X5 end, - ok; - - per -> - ok - end, + roundtrip('ChoExp', {int10,1}, {int10,first}), + roundtrip('ChoExp', {int10,first}), + roundtrip('ChoExp', {int10,last}), + roundtrip('ChoExp', {bool11,true}), + roundtrip('ChoExp', {enum12,one}), + roundtrip('ChoExp', {bool11,true}), + + {error,{asn1,_}} = (catch 'ChoPrim':encode('ChoExp', {enum12,four})), + {error,{asn1,_}} = (catch 'ChoPrim':encode('ChoExp', {wrong,233})), + case Rules of + ber -> + {error,{asn1,_}} = (catch 'ChoPrim':decode('ChoExp', <<107,3,2,1,1>>)); + per -> + ok; + uper -> + ok + end, ok. +roundtrip(Type, Value) -> + roundtrip(Type, Value, Value). - - - - - - +roundtrip(Type, Value, ExpectedValue) -> + asn1_test_lib:roundtrip('ChoPrim', Type, Value, ExpectedValue). diff --git a/lib/asn1/test/testChoRecursive.erl b/lib/asn1/test/testChoRecursive.erl index ee26d124a9..593b845949 100644 --- a/lib/asn1/test/testChoRecursive.erl +++ b/lib/asn1/test/testChoRecursive.erl @@ -43,6 +43,4 @@ recursive(_Rules) -> ok. roundtrip(Type, Value) -> - {ok,Encoded} = 'ChoRecursive':encode(Type, Value), - {ok,Value} = 'ChoRecursive':decode(Type, Encoded), - ok. + asn1_test_lib:roundtrip('ChoRecursive', Type, Value). diff --git a/lib/asn1/test/testChoTypeRefCho.erl b/lib/asn1/test/testChoTypeRefCho.erl index 9bd732f462..cd2672add0 100644 --- a/lib/asn1/test/testChoTypeRefCho.erl +++ b/lib/asn1/test/testChoTypeRefCho.erl @@ -24,43 +24,15 @@ -include_lib("test_server/include/test_server.hrl"). choice(_Rules) -> - - ?line {ok,Bytes11} = asn1_wrapper:encode('ChoTypeRefCho','ChoTRcho',{choCho,{choInt,88}}), - ?line {ok,{choCho,{choInt,88}}} = - asn1_wrapper:decode('ChoTypeRefCho','ChoTRcho',lists:flatten(Bytes11)), - - ?line {ok,Bytes12} = asn1_wrapper:encode('ChoTypeRefCho','ChoTRcho',{choChoE,{choInt,88}}), - ?line {ok,{choChoE,{choInt,88}}} = - asn1_wrapper:decode('ChoTypeRefCho','ChoTRcho',lists:flatten(Bytes12)), - - ?line {ok,Bytes13} = asn1_wrapper:encode('ChoTypeRefCho','ChoTRcho',{'choCho-E',{choInt,88}}), - ?line {ok,{'choCho-E',{choInt,88}}} = - asn1_wrapper:decode('ChoTypeRefCho','ChoTRcho',lists:flatten(Bytes13)), - - ?line {ok,Bytes14} = asn1_wrapper:encode('ChoTypeRefCho','ChoTRcho',{'choChoE-E',{choInt,88}}), - ?line {ok,{'choChoE-E',{choInt,88}}} = - asn1_wrapper:decode('ChoTypeRefCho','ChoTRcho',lists:flatten(Bytes14)), - - - - ?line {ok,Bytes21} = asn1_wrapper:encode('ChoTypeRefCho','ChoChoInline',{bool1,true}), - ?line {ok,{bool1,true}} = - asn1_wrapper:decode('ChoTypeRefCho','ChoChoInline',lists:flatten(Bytes21)), - - ?line {ok,Bytes22} = asn1_wrapper:encode('ChoTypeRefCho','ChoChoInline',{'choCho',{bool,true}}), - ?line {ok,{'choCho',{bool,true}}} = - asn1_wrapper:decode('ChoTypeRefCho','ChoChoInline',lists:flatten(Bytes22)), - - ?line {ok,Bytes23} = asn1_wrapper:encode('ChoTypeRefCho','ChoChoInline',{'choCho',{octStr,"kk"}}), - ?line {ok,{'choCho',{octStr,"kk"}}} = - asn1_wrapper:decode('ChoTypeRefCho','ChoChoInline',lists:flatten(Bytes23)), - - ?line {ok,Bytes24} = asn1_wrapper:encode('ChoTypeRefCho','ChoChoInline',{'choCho',{int,55}}), - ?line {ok,{'choCho',{int,55}}} = - asn1_wrapper:decode('ChoTypeRefCho','ChoChoInline',lists:flatten(Bytes24)), - - - - - + roundtrip('ChoTRcho', {choCho,{choInt,88}}), + roundtrip('ChoTRcho', {choChoE,{choInt,88}}), + roundtrip('ChoTRcho', {'choCho-E',{choInt,88}}), + roundtrip('ChoTRcho', {'choChoE-E',{choInt,88}}), + roundtrip('ChoChoInline', {bool1,true}), + roundtrip('ChoChoInline', {choCho,{bool,true}}), + roundtrip('ChoChoInline', {choCho,{octStr,"kk"}}), + roundtrip('ChoChoInline', {choCho,{int,55}}), ok. + +roundtrip(Type, Value) -> + asn1_test_lib:roundtrip('ChoTypeRefCho', Type, Value). diff --git a/lib/asn1/test/testChoTypeRefPrim.erl b/lib/asn1/test/testChoTypeRefPrim.erl index edef6192fe..8a2bc7bd8e 100644 --- a/lib/asn1/test/testChoTypeRefPrim.erl +++ b/lib/asn1/test/testChoTypeRefPrim.erl @@ -24,60 +24,20 @@ -include_lib("test_server/include/test_server.hrl"). prim(_Rules) -> - - ?line {ok,Bytes11} = asn1_wrapper:encode('ChoTypeRefPrim','ChoTR',{bool,true}), - ?line {ok,{bool,true}} = asn1_wrapper:decode('ChoTypeRefPrim','ChoTR',lists:flatten(Bytes11)), - - ?line {ok,Bytes12} = - asn1_wrapper:encode('ChoTypeRefPrim','ChoTR',{octStr,[11,12,13,14,15,16,17]}), - ?line {ok,{octStr,[11,12,13,14,15,16,17]}} = - asn1_wrapper:decode('ChoTypeRefPrim','ChoTR',lists:flatten(Bytes12)), - - ?line {ok,Bytes13} = asn1_wrapper:encode('ChoTypeRefPrim','ChoTR',{int,233}), - ?line {ok,{int,233}} = asn1_wrapper:decode('ChoTypeRefPrim','ChoTR',lists:flatten(Bytes13)), - - ?line {ok,Bytes14} = - asn1_wrapper:encode('ChoTypeRefPrim','ChoTR',{octStr,"Stringing in the rain"}), - ?line {ok,{octStr,"Stringing in the rain"}} = - asn1_wrapper:decode('ChoTypeRefPrim','ChoTR',lists:flatten(Bytes14)), - - - - ?line {ok,Bytes21} = asn1_wrapper:encode('ChoTypeRefPrim','ChoTR2',{'octStr',"A string"}), - ?line {ok,{'octStr',"A string"}} = - asn1_wrapper:decode('ChoTypeRefPrim','ChoTR2',lists:flatten(Bytes21)), - - ?line {ok,Bytes22} = asn1_wrapper:encode('ChoTypeRefPrim','ChoTR2',{'octStrI',"A string"}), - ?line {ok,{'octStrI',"A string"}} = - asn1_wrapper:decode('ChoTypeRefPrim','ChoTR2',lists:flatten(Bytes22)), - - ?line {ok,Bytes23} = asn1_wrapper:encode('ChoTypeRefPrim','ChoTR2',{'octStrE',"A string"}), - ?line {ok,{'octStrE',"A string"}} = - asn1_wrapper:decode('ChoTypeRefPrim','ChoTR2',lists:flatten(Bytes23)), - - ?line {ok,Bytes24} = asn1_wrapper:encode('ChoTypeRefPrim','ChoTR2',{'octStr-I',"A string"}), - ?line {ok,{'octStr-I',"A string"}} = - asn1_wrapper:decode('ChoTypeRefPrim','ChoTR2',lists:flatten(Bytes24)), - - ?line {ok,Bytes25} = asn1_wrapper:encode('ChoTypeRefPrim','ChoTR2',{'octStrI-I',"A string"}), - ?line {ok,{'octStrI-I',"A string"}} = - asn1_wrapper:decode('ChoTypeRefPrim','ChoTR2',lists:flatten(Bytes25)), - - ?line {ok,Bytes26} = asn1_wrapper:encode('ChoTypeRefPrim','ChoTR2',{'octStrE-I',"A string"}), - ?line {ok,{'octStrE-I',"A string"}} = - asn1_wrapper:decode('ChoTypeRefPrim','ChoTR2',lists:flatten(Bytes26)), - - ?line {ok,Bytes27} = asn1_wrapper:encode('ChoTypeRefPrim','ChoTR2',{'octStr-E',"A string"}), - ?line {ok,{'octStr-E',"A string"}} = - asn1_wrapper:decode('ChoTypeRefPrim','ChoTR2',lists:flatten(Bytes27)), - - ?line {ok,Bytes28} = asn1_wrapper:encode('ChoTypeRefPrim','ChoTR2',{'octStrI-E',"A string"}), - ?line {ok,{'octStrI-E',"A string"}} = - asn1_wrapper:decode('ChoTypeRefPrim','ChoTR2',lists:flatten(Bytes28)), - - ?line {ok,Bytes29} = asn1_wrapper:encode('ChoTypeRefPrim','ChoTR2',{'octStrE-E',"A string"}), - ?line {ok,{'octStrE-E',"A string"}} = - asn1_wrapper:decode('ChoTypeRefPrim','ChoTR2',lists:flatten(Bytes29)), - - + roundtrip('ChoTR', {bool,true}), + roundtrip('ChoTR', {octStr,[11,12,13,14,15,16,17]}), + roundtrip('ChoTR', {int,233}), + roundtrip('ChoTR', {octStr,"Stringing in the rain"}), + roundtrip('ChoTR2', {octStr,"A string"}), + roundtrip('ChoTR2', {octStrI,"A string"}), + roundtrip('ChoTR2', {octStrE,"A string"}), + roundtrip('ChoTR2', {'octStr-I',"A string"}), + roundtrip('ChoTR2', {'octStrI-I',"A string"}), + roundtrip('ChoTR2', {'octStrE-I',"A string"}), + roundtrip('ChoTR2', {'octStr-E',"A string"}), + roundtrip('ChoTR2', {'octStrI-E',"A string"}), + roundtrip('ChoTR2', {'octStrE-E',"A string"}), ok. + +roundtrip(Type, Value) -> + asn1_test_lib:roundtrip('ChoTypeRefPrim', Type, Value). diff --git a/lib/asn1/test/testChoTypeRefSeq.erl b/lib/asn1/test/testChoTypeRefSeq.erl index bf2b66c73e..86c22619aa 100644 --- a/lib/asn1/test/testChoTypeRefSeq.erl +++ b/lib/asn1/test/testChoTypeRefSeq.erl @@ -23,82 +23,21 @@ -include_lib("test_server/include/test_server.hrl"). --record('ChoSeq',{seqInt, seqOs}). --record('ChoSeqImp',{seqInt, seqOs}). --record('ChoSeqExp',{seqInt, seqOs}). +-record('ChoSeq', {seqInt, seqOs}). +-record('ChoSeqImp', {seqInt, seqOs}). +-record('ChoSeqExp', {seqInt, seqOs}). seq(_Rules) -> - - ?line {ok,Bytes1} = - asn1_wrapper:encode('ChoTypeRefSeq','ChoTRseq', - {choSeq,#'ChoSeq'{seqInt = 88, - seqOs = "A string"}}), - ?line {ok,{choSeq,{'ChoSeq',88,"A string"}}} = - asn1_wrapper:decode('ChoTypeRefSeq','ChoTRseq',lists:flatten(Bytes1)), - - - ?line {ok,Bytes2} = - asn1_wrapper:encode('ChoTypeRefSeq','ChoTRseq', - {choSeqI,#'ChoSeq'{seqInt = 88, - seqOs = "A string"}}), - ?line {ok,{choSeqI,{'ChoSeq',88,"A string"}}} = - asn1_wrapper:decode('ChoTypeRefSeq','ChoTRseq',lists:flatten(Bytes2)), - - - ?line {ok,Bytes3} = - asn1_wrapper:encode('ChoTypeRefSeq','ChoTRseq', - {choSeqE,#'ChoSeq'{seqInt = 88, - seqOs = "A string"}}), - ?line {ok,{choSeqE,{'ChoSeq',88,"A string"}}} = - asn1_wrapper:decode('ChoTypeRefSeq','ChoTRseq',lists:flatten(Bytes3)), - - - ?line {ok,Bytes4} = - asn1_wrapper:encode('ChoTypeRefSeq','ChoTRseq', - {'choSeq-I',#'ChoSeqImp'{seqInt = 88, - seqOs = "A string"}}), - ?line {ok,{'choSeq-I',{'ChoSeqImp',88,"A string"}}} = - asn1_wrapper:decode('ChoTypeRefSeq','ChoTRseq',lists:flatten(Bytes4)), - - - ?line {ok,Bytes5} = - asn1_wrapper:encode('ChoTypeRefSeq','ChoTRseq', - {'choSeqI-I',#'ChoSeqImp'{seqInt = 88, - seqOs = "A string"}}), - ?line {ok,{'choSeqI-I',{'ChoSeqImp',88,"A string"}}} = - asn1_wrapper:decode('ChoTypeRefSeq','ChoTRseq',lists:flatten(Bytes5)), - - - ?line {ok,Bytes6} = - asn1_wrapper:encode('ChoTypeRefSeq','ChoTRseq', - {'choSeqE-I',#'ChoSeqImp'{seqInt = 88, - seqOs = "A string"}}), - ?line {ok,{'choSeqE-I',{'ChoSeqImp',88,"A string"}}} = - asn1_wrapper:decode('ChoTypeRefSeq','ChoTRseq',lists:flatten(Bytes6)), - - - ?line {ok,Bytes7} = - asn1_wrapper:encode('ChoTypeRefSeq','ChoTRseq', - {'choSeq-E',#'ChoSeqExp'{seqInt = 88, - seqOs = "A string"}}), - ?line {ok,{'choSeq-E',{'ChoSeqExp',88,"A string"}}} = - asn1_wrapper:decode('ChoTypeRefSeq','ChoTRseq',lists:flatten(Bytes7)), - - - ?line {ok,Bytes8} = - asn1_wrapper:encode('ChoTypeRefSeq','ChoTRseq', - {'choSeqI-E',#'ChoSeqExp'{seqInt = 88, - seqOs = "A string"}}), - ?line {ok,{'choSeqI-E',{'ChoSeqExp',88,"A string"}}} = - asn1_wrapper:decode('ChoTypeRefSeq','ChoTRseq',lists:flatten(Bytes8)), - - - ?line {ok,Bytes9} = - asn1_wrapper:encode('ChoTypeRefSeq','ChoTRseq', - {'choSeqE-E',#'ChoSeqExp'{seqInt = 88, - seqOs = "A string"}}), - ?line {ok,{'choSeqE-E',{'ChoSeqExp',88,"A string"}}} = - asn1_wrapper:decode('ChoTypeRefSeq','ChoTRseq',lists:flatten(Bytes9)), - - + roundtrip('ChoTRseq', {choSeq,#'ChoSeq'{seqInt=88,seqOs="A string"}}), + roundtrip('ChoTRseq', {choSeqI,#'ChoSeq'{seqInt=88,seqOs="A string"}}), + roundtrip('ChoTRseq', {choSeqE,#'ChoSeq'{seqInt=88,seqOs="A string"}}), + roundtrip('ChoTRseq', {'choSeq-I',#'ChoSeqImp'{seqInt=88,seqOs="A string"}}), + roundtrip('ChoTRseq', {'choSeqI-I',#'ChoSeqImp'{seqInt=88,seqOs="A string"}}), + roundtrip('ChoTRseq', {'choSeqE-I',#'ChoSeqImp'{seqInt=88,seqOs="A string"}}), + roundtrip('ChoTRseq', {'choSeq-E',#'ChoSeqExp'{seqInt=88,seqOs="A string"}}), + roundtrip('ChoTRseq', {'choSeqI-E',#'ChoSeqExp'{seqInt=88,seqOs="A string"}}), + roundtrip('ChoTRseq', {'choSeqE-E',#'ChoSeqExp'{seqInt=88,seqOs="A string"}}), ok. + +roundtrip(Type, Value) -> + asn1_test_lib:roundtrip('ChoTypeRefSeq', Type, Value). diff --git a/lib/asn1/test/testChoTypeRefSet.erl b/lib/asn1/test/testChoTypeRefSet.erl index 8a3e8bdbb0..fd3d75cbcb 100644 --- a/lib/asn1/test/testChoTypeRefSet.erl +++ b/lib/asn1/test/testChoTypeRefSet.erl @@ -23,83 +23,21 @@ -include_lib("test_server/include/test_server.hrl"). --record('ChoSet',{setInt, setOs}). --record('ChoSetImp',{setInt, setOs}). --record('ChoSetExp',{setInt, setOs}). +-record('ChoSet', {setInt, setOs}). +-record('ChoSetImp', {setInt, setOs}). +-record('ChoSetExp', {setInt, setOs}). set(_Rules) -> - - ?line {ok,Bytes1} = - asn1_wrapper:encode('ChoTypeRefSet','ChoTRset', - {choSet,#'ChoSet'{setInt = 88, - setOs = "A string"}}), - ?line {ok,{choSet,{'ChoSet',88,"A string"}}} = - asn1_wrapper:decode('ChoTypeRefSet','ChoTRset',lists:flatten(Bytes1)), - - - ?line {ok,Bytes2} = - asn1_wrapper:encode('ChoTypeRefSet','ChoTRset', - {choSetI,#'ChoSet'{setInt = 88, - setOs = "A string"}}), - ?line {ok,{choSetI,{'ChoSet',88,"A string"}}} = - asn1_wrapper:decode('ChoTypeRefSet','ChoTRset',lists:flatten(Bytes2)), - - - ?line {ok,Bytes3} = - asn1_wrapper:encode('ChoTypeRefSet','ChoTRset', - {choSetE,#'ChoSet'{setInt = 88, - setOs = "A string"}}), - ?line {ok,{choSetE,{'ChoSet',88,"A string"}}} = - asn1_wrapper:decode('ChoTypeRefSet','ChoTRset',lists:flatten(Bytes3)), - - - ?line {ok,Bytes4} = - asn1_wrapper:encode('ChoTypeRefSet','ChoTRset', - {'choSet-I',#'ChoSetImp'{setInt = 88, - setOs = "A string"}}), - ?line {ok,{'choSet-I',{'ChoSetImp',88,"A string"}}} = - asn1_wrapper:decode('ChoTypeRefSet','ChoTRset',lists:flatten(Bytes4)), - - - ?line {ok,Bytes5} = - asn1_wrapper:encode('ChoTypeRefSet','ChoTRset', - {'choSetI-I',#'ChoSetImp'{setInt = 88, - setOs = "A string"}}), - ?line {ok,{'choSetI-I',{'ChoSetImp',88,"A string"}}} = - asn1_wrapper:decode('ChoTypeRefSet','ChoTRset',lists:flatten(Bytes5)), - - - ?line {ok,Bytes6} = - asn1_wrapper:encode('ChoTypeRefSet','ChoTRset', - {'choSetE-I',#'ChoSetImp'{setInt = 88, - setOs = "A string"}}), - ?line {ok,{'choSetE-I',{'ChoSetImp',88,"A string"}}} = - asn1_wrapper:decode('ChoTypeRefSet','ChoTRset',lists:flatten(Bytes6)), - - - ?line {ok,Bytes7} = - asn1_wrapper:encode('ChoTypeRefSet','ChoTRset', - {'choSet-E',#'ChoSetExp'{setInt = 88, - setOs = "A string"}}), - ?line {ok,{'choSet-E',{'ChoSetExp',88,"A string"}}} = - asn1_wrapper:decode('ChoTypeRefSet','ChoTRset',lists:flatten(Bytes7)), - - - ?line {ok,Bytes8} = - asn1_wrapper:encode('ChoTypeRefSet','ChoTRset', - {'choSetI-E',#'ChoSetExp'{setInt = 88, - setOs = "A string"}}), - ?line {ok,{'choSetI-E',{'ChoSetExp',88,"A string"}}} = - asn1_wrapper:decode('ChoTypeRefSet','ChoTRset',lists:flatten(Bytes8)), - - - ?line {ok,Bytes9} = - asn1_wrapper:encode('ChoTypeRefSet','ChoTRset', - {'choSetE-E',#'ChoSetExp'{setInt = 88, - setOs = "A string"}}), - ?line {ok,{'choSetE-E',{'ChoSetExp',88,"A string"}}} = - asn1_wrapper:decode('ChoTypeRefSet','ChoTRset',lists:flatten(Bytes9)), - - - + roundtrip('ChoTRset', {choSet,#'ChoSet'{setInt=88,setOs="A string"}}), + roundtrip('ChoTRset', {choSetI,#'ChoSet'{setInt=88,setOs="A string"}}), + roundtrip('ChoTRset', {choSetE,#'ChoSet'{setInt=88,setOs="A string"}}), + roundtrip('ChoTRset', {'choSet-I',#'ChoSetImp'{setInt=88,setOs="A string"}}), + roundtrip('ChoTRset', {'choSetI-I',#'ChoSetImp'{setInt=88,setOs="A string"}}), + roundtrip('ChoTRset', {'choSetE-I',#'ChoSetImp'{setInt=88,setOs="A string"}}), + roundtrip('ChoTRset', {'choSet-E',#'ChoSetExp'{setInt=88,setOs="A string"}}), + roundtrip('ChoTRset', {'choSetI-E',#'ChoSetExp'{setInt=88,setOs="A string"}}), + roundtrip('ChoTRset', {'choSetE-E',#'ChoSetExp'{setInt=88,setOs="A string"}}), ok. + +roundtrip(Type, Value) -> + asn1_test_lib:roundtrip('ChoTypeRefSet', Type, Value). diff --git a/lib/asn1/test/testChoiceIndefinite.erl b/lib/asn1/test/testChoiceIndefinite.erl index b5832c985a..87910cf6ec 100644 --- a/lib/asn1/test/testChoiceIndefinite.erl +++ b/lib/asn1/test/testChoiceIndefinite.erl @@ -32,6 +32,6 @@ main(ber) -> Bi = [48,128,160,128,128,1,11,0,0,129,1,12,0,0], %% the value which is encoded V = {'Seq',{ca,11},12}, - ?line {ok,V} = asn1_wrapper:decode('ChoiceIndef','Seq',B), - ?line {ok,V} = asn1_wrapper:decode('ChoiceIndef','Seq',Bi), + {ok,V} = 'ChoiceIndef':decode('Seq', B), + {ok,V} = 'ChoiceIndef':decode('Seq', Bi), ok. diff --git a/lib/asn1/test/testConstraints.erl b/lib/asn1/test/testConstraints.erl index 03a09492af..9a1d62993d 100644 --- a/lib/asn1/test/testConstraints.erl +++ b/lib/asn1/test/testConstraints.erl @@ -204,9 +204,8 @@ shorter_ext(uper, "a") -> <<16#80,16#E1>>; shorter_ext(ber, _) -> none. refed_NNL_name(_Erule) -> - ?line {ok,_} = asn1_wrapper:encode('Constraints','AnotherThing',fred), - ?line {error,_Reason} = - asn1_wrapper:encode('Constraints','AnotherThing',fred3). + roundtrip('AnotherThing', fred), + {error,_Reason} = 'Constraints':encode('AnotherThing', fred3). v_roundtrip(Erule, Type, Value) -> Encoded = asn1_test_lib:hex_to_bin(v(Erule, Type, Value)), @@ -216,14 +215,10 @@ roundtrip(Type, Value) -> roundtrip('Constraints', Type, Value). roundtrip(Module, Type, Value) -> - {ok,Encoded} = Module:encode(Type, Value), - {ok,Value} = Module:decode(Type, Encoded), - Encoded. + asn1_test_lib:roundtrip_enc(Module, Type, Value). roundtrip_enc(Type, Value, Enc) -> - Module = 'Constraints', - {ok,Encoded} = Module:encode(Type, Value), - {ok,Value} = Module:decode(Type, Encoded), + Encoded = asn1_test_lib:roundtrip_enc('Constraints', Type, Value), case Enc of none -> ok; Encoded -> ok diff --git a/lib/asn1/test/testContextSwitchingTypes.erl b/lib/asn1/test/testContextSwitchingTypes.erl index 40dbe25015..bdd6883dac 100644 --- a/lib/asn1/test/testContextSwitchingTypes.erl +++ b/lib/asn1/test/testContextSwitchingTypes.erl @@ -24,31 +24,21 @@ -include_lib("test_server/include/test_server.hrl"). test(Config) -> - ?line ValT = 'ContextSwitchingTypes':'val1-T'(), - ?line {ok,Bytes1} = - asn1_wrapper:encode('ContextSwitchingTypes','T',ValT), - ?line {ok,Result1} = - asn1_wrapper:decode('ContextSwitchingTypes','T',Bytes1), - ?line ok = check_EXTERNAL(Result1), - ?line {ok,ValT2} = asn1ct:value('ContextSwitchingTypes','T', - [{i, ?config(case_dir, Config)}]), - ?line {ok,Bytes1_2} = - asn1_wrapper:encode('ContextSwitchingTypes','T',ValT2), - ?line {ok,Result1_2} = - asn1_wrapper:decode('ContextSwitchingTypes','T',Bytes1_2), - ?line ok = check_EXTERNAL(Result1_2), + ValT = 'ContextSwitchingTypes':'val1-T'(), + check_EXTERNAL(enc_dec('T', ValT)), - ?line ValEP = 'ContextSwitchingTypes':'val1-EP'(), - ?line {ok,Bytes2} = - asn1_wrapper:encode('ContextSwitchingTypes','EP',ValEP), - ?line {ok,_Result2} = - asn1_wrapper:decode('ContextSwitchingTypes','EP',Bytes2), + {ok,ValT2} = asn1ct:value('ContextSwitchingTypes', 'T', + [{i,?config(case_dir, Config)}]), + check_EXTERNAL(enc_dec('T', ValT2)), - ?line ValCS = 'ContextSwitchingTypes':'val1-CS'(), - ?line {ok,Bytes3} = - asn1_wrapper:encode('ContextSwitchingTypes','CS',ValCS), - ?line {ok,_Result3} = - asn1_wrapper:decode('ContextSwitchingTypes','CS',Bytes3). + ValEP = 'ContextSwitchingTypes':'val1-EP'(), + ValEPDec = enc_dec('EP', ValEP), + io:format("~p\n~p\n", [ValEP,ValEPDec]), + + ValCS = 'ContextSwitchingTypes':'val1-CS'(), + ValCSDec = enc_dec('EP', ValCS), + io:format("~p\n~p\n", [ValCS,ValCSDec]), + ok. check_EXTERNAL({'EXTERNAL',Identif,DVD,DV})-> @@ -85,3 +75,9 @@ check_object_identifier(Tuple) when is_tuple(Tuple) -> not is_integer(E)] of [] -> ok end. + +enc_dec(T, V0) -> + M = 'ContextSwitchingTypes', + {ok,Enc} = M:encode(T, V0), + {ok,V} = M:decode(T, Enc), + V. diff --git a/lib/asn1/test/testDER.erl b/lib/asn1/test/testDER.erl index 395116bd34..3f74a16797 100644 --- a/lib/asn1/test/testDER.erl +++ b/lib/asn1/test/testDER.erl @@ -25,26 +25,24 @@ test() -> Val = {'Set',12,{version,214},true}, - ?line {ok,Bin}=asn1_wrapper:encode('DERSpec','Set',Val), - ?line ok = match_value('Set',Bin), - ?line {ok,{'Set',12,{version,214},true}} = - asn1_wrapper:decode('DERSpec','Set',Bin), + roundtrip_enc('Set', Val, <<49,12,1,1,255,2,2,0,214,161,3,2,1,12>>), - ValSof = [{version,12},{message,"PrintableString"},{message,"Print"},{version,11}], - ?line {ok,BSof} = asn1_wrapper:encode('DERSpec','SetOf',ValSof), - ?line ok = match_value('SetOf',BSof), - ?line {ok,[{version,11},{version,12},{message,"Print"},{message,"PrintableString"}]} = asn1_wrapper:decode('DERSpec','SetOf',BSof), + ValSof = [{version,12},{message,"PrintableString"}, + {message,"Print"},{version,11}], + ValSofSorted = [{version,11},{version,12}, + {message,"Print"},{message,"PrintableString"}], + roundtrip_enc('SetOf', ValSof, ValSofSorted, + <<49,30,2,1,11,2,1,12,19,5,80,114,105,110,116,19,15,80, + 114,105,110,116,97,98,108,101,83,116,114,105,110,103>>), ValSO = [{'Seq2',1,true},{'Seq2',120000,false},{'Seq2',3,true}], - ?line {ok,SOB} = asn1_wrapper:encode('DERSpec','SO',ValSO), - ?line {ok,ValSO} = asn1_wrapper:decode('DERSpec','SO',SOB). + roundtrip('SO', ValSO). +roundtrip(T, V) -> + asn1_test_lib:roundtrip('DERSpec', T, V). -match_value('Set',<<49,12,1,1,255,2,2,0,214,161,3,2,1,12>>) -> - ok; -match_value('Set',[49,12,1,1,255,2,2,0,214,161,3,2,1,12]) -> - ok; -match_value('SetOf',<<49,30,2,1,11,2,1,12,19,5,80,114,105,110,116,19,15,80,114,105,110,116,97,98,108,101,83,116,114,105,110,103>>) -> ok; -match_value('SetOf',[49,30,2,1,11,2,1,12,19,5,80,114,105,110,116,19,15,80,114,105,110,116,97,98,108,101,83,116,114,105,110,103]) -> ok; -match_value(_,B) -> - {error,B}. +roundtrip_enc(T, V, Enc) -> + Enc = asn1_test_lib:roundtrip_enc('DERSpec', T, V). + +roundtrip_enc(T, V, Expected, Enc) -> + Enc = asn1_test_lib:roundtrip_enc('DERSpec', T, V, Expected). diff --git a/lib/asn1/test/testDeepTConstr.erl b/lib/asn1/test/testDeepTConstr.erl index f17dedc043..880f15e91a 100644 --- a/lib/asn1/test/testDeepTConstr.erl +++ b/lib/asn1/test/testDeepTConstr.erl @@ -40,8 +40,7 @@ main(_Erule) -> {any,"DK"}, {final,"NO"}]}}, - {ok,Bytes1} = 'TConstrChoice':encode('FilterItem', Val1), - {error,Reason} = asn1_wrapper:decode('TConstrChoice','FilterItem',Bytes1), + Reason = must_fail('TConstrChoice', 'FilterItem', Val1), io:format("Reason: ~p~n~n",[Reason]), {ok,Bytes2} = 'TConstrChoice':encode('FilterItem', Val2), {ok,Res} = 'TConstrChoice':decode('FilterItem', Bytes2), @@ -70,10 +69,33 @@ main(_Erule) -> {'Deeper_a',12, {'Deeper_a_s',{2,4},42}}, {'Deeper_b',13,{'Type-object1',14,true}}}), + + roundtrip('TConstr', 'Seq3', + {'Seq3', + {'Seq3_a',42,'TConstr':'id-object1'()}, + {'Seq3_b', + {'Type-object1',-777,true}, + 12345, + {'Seq3_b_bc',12345789,{'Type-object1',-999,true}}}}), + roundtrip('TConstr', 'Seq3-Opt', + {'Seq3-Opt', + {'Seq3-Opt_a',42,'TConstr':'id-object1'()}, + {'Seq3-Opt_b', + {'Type-object1',-777,true}, + 12345, + {'Seq3-Opt_b_bc',12345789,{'Type-object1',-999,true}}}}), ok. roundtrip(M, T, V) -> - {ok,E} = M:encode(T, V), - {ok,V} = M:decode(T, E), - ok. + asn1_test_lib:roundtrip(M, T, V). + +%% Either encoding or decoding must fail. +must_fail(M, T, V) -> + case M:encode(T, V) of + {ok,E} -> + {error,Reason} = M:decode(T, E), + Reason; + {error,Reason} -> + Reason + end. diff --git a/lib/asn1/test/testDef.erl b/lib/asn1/test/testDef.erl index 48f0015008..b8df3c4f8b 100644 --- a/lib/asn1/test/testDef.erl +++ b/lib/asn1/test/testDef.erl @@ -37,81 +37,45 @@ bool33 = asn1_DEFAULT}). main(_Rules) -> - - ?line {ok,Bytes11} = asn1_wrapper:encode('Def','Def1',#'Def1'{bool0 = true, - bool1 = true, - bool2 = true, - bool3 = true}), - ?line {ok,{'Def1',true,true,true,true}} = - asn1_wrapper:decode('Def','Def1',lists:flatten(Bytes11)), - - ?line {ok,Bytes12} = asn1_wrapper:encode('Def','Def1',#'Def1'{bool0 = true}), - ?line {ok,{'Def1',true,false,false,false}} = - asn1_wrapper:decode('Def','Def1',lists:flatten(Bytes12)), - - ?line {ok,Bytes13} = asn1_wrapper:encode('Def','Def1',#'Def1'{bool0 = true, - bool2 = false}), - ?line {ok,{'Def1',true,false,false,false}} = - asn1_wrapper:decode('Def','Def1',lists:flatten(Bytes13)), - - ?line {ok,Bytes14} = asn1_wrapper:encode('Def','Def1',#'Def1'{bool0 = false, - bool3 = false}), - ?line {ok,{'Def1',false,false,false,false}} = - asn1_wrapper:decode('Def','Def1',lists:flatten(Bytes14)), - - - - - ?line {ok,Bytes21} = asn1_wrapper:encode('Def','Def2',#'Def2'{bool10 = false, - bool11 = false, - bool12 = false, - bool13 = false}), - ?line {ok,{'Def2',false,false,false,false}} = - asn1_wrapper:decode('Def','Def2',lists:flatten(Bytes21)), - - ?line {ok,Bytes22} = asn1_wrapper:encode('Def','Def2',#'Def2'{bool10 = true, - bool13 = false}), - ?line {ok,{'Def2',true,false,false,false}} = - asn1_wrapper:decode('Def','Def2',lists:flatten(Bytes22)), - - ?line {ok,Bytes23} = asn1_wrapper:encode('Def','Def2',#'Def2'{bool10 = true, - bool11 = false, - bool13 = false}), - ?line {ok,{'Def2',true,false,false,false}} = - asn1_wrapper:decode('Def','Def2',lists:flatten(Bytes23)), - - ?line {ok,Bytes24} = asn1_wrapper:encode('Def','Def2',#'Def2'{bool10 = false, - bool12 = false, - bool13 = false}), - ?line {ok,{'Def2',false,false,false,false}} = - asn1_wrapper:decode('Def','Def2',lists:flatten(Bytes24)), - - - - - ?line {ok,Bytes31} = asn1_wrapper:encode('Def','Def3',#'Def3'{bool30 = false, - bool31 = false, - bool32 = false, - bool33 = false}), - ?line {ok,{'Def3',false,false,false,false}} = - asn1_wrapper:decode('Def','Def3',lists:flatten(Bytes31)), - - ?line {ok,Bytes32} = asn1_wrapper:encode('Def','Def3',#'Def3'{}), - ?line {ok,{'Def3',false,false,false,false}} = - asn1_wrapper:decode('Def','Def3',lists:flatten(Bytes32)), - - ?line {ok,Bytes33} = asn1_wrapper:encode('Def','Def3',#'Def3'{bool30 = true}), - ?line {ok,{'Def3',true,false,false,false}} = - asn1_wrapper:decode('Def','Def3',lists:flatten(Bytes33)), - - ?line {ok,Bytes34} = asn1_wrapper:encode('Def','Def3',#'Def3'{bool32 = false}), - ?line {ok,{'Def3',false,false,false,false}} = - asn1_wrapper:decode('Def','Def3',lists:flatten(Bytes34)), - - ?line {ok,Bytes35} = asn1_wrapper:encode('Def','Def3',#'Def3'{bool33 = false}), - ?line {ok,{'Def3',false,false,false,false}} = - asn1_wrapper:decode('Def','Def3',lists:flatten(Bytes35)), - - - + roundtrip('Def1', #'Def1'{bool0=true,bool1=true,bool2=true,bool3=true}), + roundtrip('Def1', + #'Def1'{bool0=true}, + #'Def1'{bool0=true,bool1=false,bool2=false,bool3=false}), + roundtrip('Def1', + #'Def1'{bool0=true,bool2=false}, + #'Def1'{bool0=true,bool1=false,bool2=false,bool3=false}), + roundtrip('Def1', + #'Def1'{bool0=false,bool3=false}, + #'Def1'{bool0=false,bool1=false,bool2=false,bool3=false}), + + roundtrip('Def2', #'Def2'{bool10=false,bool11=false,bool12=false,bool13=false}), + roundtrip('Def2', + #'Def2'{bool10=true,bool13=false}, + #'Def2'{bool10=true,bool11=false,bool12=false,bool13=false}), + roundtrip('Def2', + #'Def2'{bool10=true,bool11=false,bool13=false}, + #'Def2'{bool10=true,bool11=false,bool12=false,bool13=false}), + roundtrip('Def2', + #'Def2'{bool10=false,bool12=false,bool13=false}, + #'Def2'{bool10=false,bool11=false,bool12=false,bool13=false}), + + roundtrip('Def3', #'Def3'{bool30=false,bool31=false,bool32=false,bool33=false}), + roundtrip('Def3', + #'Def3'{}, + #'Def3'{bool30=false,bool31=false,bool32=false,bool33=false}), + roundtrip('Def3', + #'Def3'{bool30=true}, + #'Def3'{bool30=true,bool31=false,bool32=false,bool33=false}), + roundtrip('Def3', + #'Def3'{bool32=false}, + #'Def3'{bool30=false,bool31=false,bool32=false,bool33=false}), + roundtrip('Def3', + #'Def3'{bool33=false}, + #'Def3'{bool30=false,bool31=false,bool32=false,bool33=false}), ok. + +roundtrip(Type, Value) -> + roundtrip(Type, Value, Value). + +roundtrip(Type, Value, ExpectedValue) -> + asn1_test_lib:roundtrip('Def', Type, Value, ExpectedValue). diff --git a/lib/asn1/test/testDoubleEllipses.erl b/lib/asn1/test/testDoubleEllipses.erl index 1032156b91..4e8972cdfc 100644 --- a/lib/asn1/test/testDoubleEllipses.erl +++ b/lib/asn1/test/testDoubleEllipses.erl @@ -34,67 +34,27 @@ -record('SetAltV2',{a,d,b,e,h,i,c,f,g}). main(_Rules) -> - %% SEQUENCE - ?line {ok,Bytes} = - asn1_wrapper:encode('DoubleEllipses','Seq',#'Seq'{a = 10,c = true}), - ?line {ok,#'SeqV2'{a=10,b = asn1_NOVALUE, c = true}} = - asn1_wrapper:decode('DoubleEllipses','SeqV2',Bytes), - ?line {ok,Bytes2} = - asn1_wrapper:encode('DoubleEllipses','SeqV2', - #'SeqV2'{a=10,b = false, c = true}), - ?line {ok,#'Seq'{a = 10, c = true}} = - asn1_wrapper:decode('DoubleEllipses','Seq',Bytes2), + roundtrip('Seq', #'Seq'{a=10,c=true}), + roundtrip('SeqV2', #'SeqV2'{a=10,b=false,c=true}), + roundtrip('SeqAlt', + #'SeqAlt'{a=10,d=12,b = <<2#1010:4>>, + e=true,c=false,f=14,g=16}), + roundtrip('SeqAltV2', + #'SeqAltV2'{a=10,d=12, + b = <<2#1010:4>>, + e=true,h="PS",i=13,c=false,f=14,g=16}), - ?line {ok,Bytes3} = - asn1_wrapper:encode('DoubleEllipses','SeqAlt', - #'SeqAlt'{a = 10, d = 12, - b = [1,0,1,0], e = true, - c = false, f = 14, g = 16}), - ?line {ok,#'SeqAltV2'{a = 10, d = 12, - b = <<2#1010:4>>, e = true, - h = asn1_NOVALUE, i = asn1_NOVALUE, - c = false, f = 14, g = 16}} = - asn1_wrapper:decode('DoubleEllipses','SeqAltV2',Bytes3), - ?line {ok,Bytes4} = - asn1_wrapper:encode('DoubleEllipses','SeqAltV2', - #'SeqAltV2'{a = 10, d = 12, - b = [1,0,1,0], e = true, - h = "PS", i = 13, - c = false, f = 14, g = 16}), - ?line {ok,#'SeqAlt'{a = 10, d = 12, - b = <<2#1010:4>>, e = true, - c = false, f = 14, g = 16}} = - asn1_wrapper:decode('DoubleEllipses','SeqAlt',Bytes4), - - %% SET - ?line {ok,Bytes5} = - asn1_wrapper:encode('DoubleEllipses','Set',#'Set'{a = 10,c = true}), - ?line {ok,#'SetV2'{a=10,b = asn1_NOVALUE, c = true}} = - asn1_wrapper:decode('DoubleEllipses','SetV2',Bytes5), - ?line {ok,Bytes6} = - asn1_wrapper:encode('DoubleEllipses','SetV2', - #'SetV2'{a=10,b = false, c = true}), - ?line {ok,#'Set'{a = 10, c = true}} = - asn1_wrapper:decode('DoubleEllipses','Set',Bytes6), - - ?line {ok,Bytes7} = - asn1_wrapper:encode('DoubleEllipses','SetAlt', - #'SetAlt'{a = 10, d = 12, - b = [1,0,1,0], e = true, - c = false, f = 14, g = 16}), - ?line {ok,#'SetAltV2'{a = 10, d = 12, - b = <<2#1010:4>>, e = true, - h = asn1_NOVALUE, i = asn1_NOVALUE, - c = false, f = 14, g = 16}} = - asn1_wrapper:decode('DoubleEllipses','SetAltV2',Bytes7), - ?line {ok,Bytes8} = - asn1_wrapper:encode('DoubleEllipses','SetAltV2', - #'SetAltV2'{a = 10, d = 12, - b = [1,0,1,0], e = true, - h = "PS", i = 13, - c = false, f = 14, g = 16}), - ?line {ok,#'SetAlt'{a = 10, d = 12, - b = <<2#1010:4>>, e = true, - c = false, f = 14, g = 16}} = - asn1_wrapper:decode('DoubleEllipses','SetAlt',Bytes8), + roundtrip('Set', #'Set'{a=10,c=true}), + roundtrip('SetV2', #'SetV2'{a=10,b=false,c=true}), + roundtrip('SetAlt', + #'SetAlt'{a=10,d=12, + b = <<2#1010:4>>, + e=true,c=false,f=14,g=16}), + roundtrip('SetAltV2', + #'SetAltV2'{a=10,d=12, + b = <<2#1010:4>>, + e=true,h="PS",i=13,c=false,f=14,g=16}), ok. + +roundtrip(T, V) -> + asn1_test_lib:roundtrip('DoubleEllipses', T, V). diff --git a/lib/asn1/test/testEnumExt.erl b/lib/asn1/test/testEnumExt.erl index cbc13ee6da..c66adaf949 100644 --- a/lib/asn1/test/testEnumExt.erl +++ b/lib/asn1/test/testEnumExt.erl @@ -33,7 +33,7 @@ main(Rule) when Rule =:= per; Rule =:= uper -> %% ENUMERATED with extensionmark (value is an extensionvalue) Or = roundtrip('Ext1', orange), %% unknown extensionvalue - {ok,{asn1_enum,0}} = asn1_wrapper:decode('EnumExt','Ext',Or), + {ok,{asn1_enum,0}} = 'EnumExt':decode('Ext', Or), %% ENUMERATED no extensionmark B64 = <<64>>, @@ -45,12 +45,12 @@ main(ber) -> roundtrip('Ext', red), %% value is an extensionvalue - {ok,Bytes1_1} = asn1_wrapper:encode('EnumExt','Ext1',orange), - {ok,{asn1_enum,7}} = asn1_wrapper:decode('EnumExt','Ext',lists:flatten(Bytes1_1)), + {ok,Bytes1_1} = 'EnumExt':encode('Ext1', orange), + {ok,{asn1_enum,7}} = 'EnumExt':decode('Ext', Bytes1_1), %% ENUMERATED no extensionmark roundtrip('Noext', red), - ?line {error,{asn1,_}} = (catch asn1_wrapper:encode('EnumExt','Noext',orange)), + {error,{asn1,_}} = (catch 'EnumExt':encode('Noext', orange)), %% ENUMERATED with atom 'com' roundtrip('Globalstate', preop), @@ -77,9 +77,7 @@ common(Erule) -> ok. roundtrip(Type, Value) -> - {ok,Encoded} = 'EnumExt':encode(Type, Value), - {ok,Value} = 'EnumExt':decode(Type, Encoded), - Encoded. + asn1_test_lib:roundtrip_enc('EnumExt', Type, Value). v_roundtrip(Erule, Type, Value) -> Encoded = roundtrip(Type, Value), diff --git a/lib/asn1/test/testFragmented.erl b/lib/asn1/test/testFragmented.erl new file mode 100644 index 0000000000..8d5fa07a5b --- /dev/null +++ b/lib/asn1/test/testFragmented.erl @@ -0,0 +1,40 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2013. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +%% +-module(testFragmented). + +-export([main/1]). + +main(_Erule) -> + roundtrip('PDU', {'PDU',1,false,["abc","def"]}), + B256 = lists:seq(0, 255), + K1 = lists:duplicate(4, B256), + K8 = binary_to_list(iolist_to_binary(lists:duplicate(8, K1))), + roundtrip('PDU', {'PDU',1,false,[K8,K8]}), + roundtrip('PDU', {'PDU',1,false,[K8,K8,K8,K8]}), + roundtrip('PDU', {'PDU',1,false,[K8,K8,K8,K8,K8,K8]}), + roundtrip('PDU', {'PDU',1,false,[K8,K8,K8,K8,K8,K8,K8,K8]}), + roundtrip('PDU', {'PDU',1,false,[K8,K8,K8,K8,K8,K8,K8,K8, + K8,K8,K8,K8,K8,K8]}), + roundtrip('PDU', {'PDU',1,false,[K8,K8,K8,K8,K8,K8,K8,K8, + K8,K8,K8,K8,K8,K8,K8,K8]}), + ok. + +roundtrip(T, V) -> + asn1_test_lib:roundtrip('Fragmented', T, V). diff --git a/lib/asn1/test/testINSTANCE_OF.erl b/lib/asn1/test/testINSTANCE_OF.erl index ce411beb92..c855ca3c06 100644 --- a/lib/asn1/test/testINSTANCE_OF.erl +++ b/lib/asn1/test/testINSTANCE_OF.erl @@ -18,46 +18,23 @@ %% %% -module(testINSTANCE_OF). - -export([main/1]). -include_lib("test_server/include/test_server.hrl"). -main(Erule) -> +main(_Erule) -> + Int = roundtrip('Int', 3), - ?line {ok,Integer} = asn1_wrapper:encode('INSTANCEOF','Int',3), - Int = list_to_binary(Integer), ValotherName = {otherName,{'INSTANCE OF',{2,4},Int}}, + _ = roundtrip('GeneralName', ValotherName), + VallastName1 = {lastName,{'GeneralName_lastName',{2,4},12}}, + _ = roundtrip('GeneralName', VallastName1), + VallastName2 = {lastName,{'GeneralName_lastName',{2,3,4}, {'Seq',12,true}}}, - ?line {ok,BytesoN}= - asn1_wrapper:encode('INSTANCEOF','GeneralName',ValotherName), - ?line {ok,Res1={otherName,_}} = - asn1_wrapper:decode('INSTANCEOF','GeneralName',BytesoN), - ?line ok = test_encdec(Erule,Int,Res1), - - ?line {ok,ByteslN1}= - asn1_wrapper:encode('INSTANCEOF','GeneralName',VallastName1), - ?line {ok,Res2={lastName,_}} = - asn1_wrapper:decode('INSTANCEOF','GeneralName',ByteslN1), - ?line test_encdec(Erule,Res2), - - ?line {ok,ByteslN2}= - asn1_wrapper:encode('INSTANCEOF','GeneralName',VallastName2), - ?line {ok,Res3={lastName,_}} = - asn1_wrapper:decode('INSTANCEOF','GeneralName',ByteslN2), - ?line test_encdec(Erule,Res3). - -test_encdec(_Erule,Int,{otherName,{'INSTANCE OF',{2,4},Int}}) -> - ok; -test_encdec(Erule,Int,R={otherName,{'INSTANCE OF',{2,4},_Int2}}) -> - {error,{Erule,Int,R}}. + _ = roundtrip('GeneralName', VallastName2), + ok. -test_encdec(_Erule,{lastName,{'GeneralName_lastName',{2,4},12}}) -> - ok; -test_encdec(_Erule,{lastName,{'GeneralName_lastName',{2,3,4}, - {'Seq',12,true}}}) -> - ok; -test_encdec(Erule,Res) -> - {error,{Erule,Res}}. +roundtrip(T, V) -> + asn1_test_lib:roundtrip_enc('INSTANCEOF', T, V). diff --git a/lib/asn1/test/testInfObj.erl b/lib/asn1/test/testInfObj.erl index c7b19a0cbb..cd335e1023 100644 --- a/lib/asn1/test/testInfObj.erl +++ b/lib/asn1/test/testInfObj.erl @@ -59,13 +59,71 @@ main(_Erule) -> {'ConstructedPdu',2,{'CONSTRUCTED-DEFAULT_Type',999,false}}), roundtrip('InfObj', 'ConstructedPdu', {'ConstructedPdu',3,true}), + {'ConstructedPdu',4,{_,42,<<13:7>>}} = + enc_dec('InfObj', 'ConstructedPdu', + {'ConstructedPdu',4,{'',42,<<13:7>>}}), + roundtrip('InfObj', 'ConstructedPdu', + {'ConstructedPdu',5,{i,-250138}}), + roundtrip('InfObj', 'ConstructedPdu', + {'ConstructedPdu',5,{b,<<13456:15>>}}), + roundtrip('InfObj', 'ConstructedPdu', + {'ConstructedPdu',6,[]}), + roundtrip('InfObj', 'ConstructedPdu', + {'ConstructedPdu',6,[10,7,16,1,5,13,12]}), + roundtrip('InfObj', 'ConstructedPdu', + {'ConstructedPdu',7,[]}), + roundtrip('InfObj', 'ConstructedPdu', + {'ConstructedPdu',7,[64,1,19,17,35]}), + + roundtrip('InfObj', 'ConstructedSet', + {'ConstructedSet',1,{'CONSTRUCTED-DEFAULT_Type',-2001,true}}), + roundtrip('InfObj', 'ConstructedSet', + {'ConstructedSet',2,{'CONSTRUCTED-DEFAULT_Type',999,false}}), + roundtrip('InfObj', 'ConstructedSet', + {'ConstructedSet',3,true}), + {'ConstructedSet',4,{_,42,<<13:7>>}} = + enc_dec('InfObj', 'ConstructedSet', + {'ConstructedSet',4,{'',42,<<13:7>>}}), + roundtrip('InfObj', 'ConstructedSet', + {'ConstructedSet',5,{i,-250138}}), + roundtrip('InfObj', 'ConstructedSet', + {'ConstructedSet',5,{b,<<13456:15>>}}), + roundtrip('InfObj', 'ConstructedSet', + {'ConstructedSet',6,[]}), + roundtrip('InfObj', 'ConstructedSet', + {'ConstructedSet',6,[10,7,16,1,5,13,12]}), + roundtrip('InfObj', 'ConstructedSet', + {'ConstructedSet',7,[]}), + roundtrip('InfObj', 'ConstructedSet', + {'ConstructedSet',7,[64,1,19,17,35]}), roundtrip('InfObj', 'Seq2', {'Seq2',42,[true,false,false,true], - [false,true,false]}). + [false,true,false]}), + + roundtrip('InfObj', 'OptionalInSeq', {'OptionalInSeq',3,true}), + roundtrip('InfObj', 'OptionalInSeq', {'OptionalInSeq',3,asn1_NOVALUE}), + roundtrip('InfObj', 'DefaultInSeq', {'DefaultInSeq',3,false}), + roundtrip('InfObj', 'DefaultInSeq', {'DefaultInSeq',3,true}), + {'DefaultInSeq',3,true} = + enc_dec('InfObj', 'DefaultInSeq', {'DefaultInSeq',3,asn1_DEFAULT}), + + roundtrip('InfObj', 'Multiple-Optionals', + {'Multiple-Optionals',1,42,true,"abc"}), + roundtrip('InfObj', 'Multiple-Optionals', + {'Multiple-Optionals',1,asn1_NOVALUE,true,"abc"}), + roundtrip('InfObj', 'Multiple-Optionals', + {'Multiple-Optionals',1,42,asn1_NOVALUE,"abc"}), + roundtrip('InfObj', 'Multiple-Optionals', + {'Multiple-Optionals',1,42,true,asn1_NOVALUE}), + roundtrip('InfObj', 'Multiple-Optionals', + {'Multiple-Optionals',1,asn1_NOVALUE,asn1_NOVALUE,asn1_NOVALUE}). roundtrip(M, T, V) -> - {ok,Enc} = M:encode(T, V), + asn1_test_lib:roundtrip(M, T, V). + +enc_dec(M, T, V0) -> + {ok,Enc} = M:encode(T, V0), {ok,V} = M:decode(T, Enc), - ok. + V. diff --git a/lib/asn1/test/testInfObjectClass.erl b/lib/asn1/test/testInfObjectClass.erl index 98408502c6..c36c05a2ea 100644 --- a/lib/asn1/test/testInfObjectClass.erl +++ b/lib/asn1/test/testInfObjectClass.erl @@ -29,24 +29,22 @@ main(Rule) -> %% this test is added for OTP-4591, to test that elements in decoded %% value has terms in right order. Val = {'Seq',12,13,2}, - ?line {ok,Bytes}= asn1_wrapper:encode('InfClass','Seq',Val), - ?line {ok,Val} = asn1_wrapper:decode('InfClass','Seq',Bytes), + roundtrip('Seq', Val), %% OTP-5783 - ?line {error,{asn1,{'Type not compatible with table constraint', - {component,'ArgumentType'}, - {value,_},_}}} = asn1_wrapper:encode('InfClass','Seq', - {'Seq',12,13,1}), + {error,{asn1,{'Type not compatible with table constraint', + {component,'ArgumentType'}, + {value,_},_}}} = 'InfClass':encode('Seq', {'Seq',12,13,1}), Bytes2 = case Rule of ber -> <<48,9,2,1,12,2,1,11,2,1,1>>; _ -> - <<1,12,1,11,1,1>> + <<1,12,1,11,1,1>> end, - ?line {error,{asn1,{'Type not compatible with table constraint', - {{component,_}, - {value,_B},_}}}} = - asn1_wrapper:decode('InfClass','Seq',Bytes2). + {error,{asn1,{'Type not compatible with table constraint', + {{component,_}, + {value,_B},_}}}} = 'InfClass':decode('Seq', Bytes2), + ok. - - +roundtrip(T, V) -> + asn1_test_lib:roundtrip('InfClass', T, V). diff --git a/lib/asn1/test/testMegaco.erl b/lib/asn1/test/testMegaco.erl index f4edcebb7e..644042b484 100644 --- a/lib/asn1/test/testMegaco.erl +++ b/lib/asn1/test/testMegaco.erl @@ -20,165 +20,28 @@ -module(testMegaco). --export([compile/3,main/2,msg11/0]). +-export([compile/3,main/2]). -include_lib("test_server/include/test_server.hrl"). --define(MID, {ip4Address, #'IP4Address'{address = [124, 124, 124, 222], - portNumber = 55555}}). --define(A4444, ["11111111"]). --record('MegacoMessage', - { - authHeader = asn1_NOVALUE, - mess - }). - --record('Message', - { - version, - mId, - messageBody - }). % with extension mark - --record('IP4Address', - { - address, - portNumber = asn1_NOVALUE - }). - --record('TransactionRequest', - { - transactionId, - actions = [] - }). % with extension mark - --record('ActionRequest', - { - contextId, - contextRequest = asn1_NOVALUE, - contextAttrAuditReq = asn1_NOVALUE, - commandRequests = [] - }). - --record('CommandRequest', - { - command, - optional = asn1_NOVALUE, - wildcardReturn = asn1_NOVALUE - }). % with extension mark - --record('NotifyRequest', - { - terminationID, - observedEventsDescriptor, - errorDescriptor = asn1_NOVALUE - }). % with extension mark - --record('ObservedEventsDescriptor', - { - requestId, - observedEventLst = [] - }). - --record('ObservedEvent', - { - eventName, - streamID = asn1_NOVALUE, - eventParList = [], - timeNotation = asn1_NOVALUE - }). % with extension mark - --record('EventParameter', - { - eventParameterName, - value - }). - --record('TimeNotation', - { - date, - time - }). - --record(megaco_term_id, {contains_wildcards = ["f"], id}). - - -compile(_Config,ber,[optimize]) -> - {ok,no_module,no_module}; -compile(_Config,per,[optimize]) -> - {ok,no_module,no_module}; -compile(Config,Erule,Options) -> +compile(Config, Erule, Options) -> asn1_test_lib:compile("MEDIA-GATEWAY-CONTROL.asn", Config, [Erule|Options]), asn1_test_lib:compile("OLD-MEDIA-GATEWAY-CONTROL.asn", Config, [Erule|Options]), {ok,'OLD-MEDIA-GATEWAY-CONTROL','MEDIA-GATEWAY-CONTROL'}. - main(no_module,_) -> ok; main('OLD-MEDIA-GATEWAY-CONTROL',Config) -> -% Msg = msg11(), CaseDir = ?config(case_dir, Config), {ok,Msg} = asn1ct:value('OLD-MEDIA-GATEWAY-CONTROL','MegacoMessage', [{i, CaseDir}]), - ?line {ok,Bytes} = asn1_wrapper:encode('OLD-MEDIA-GATEWAY-CONTROL', - 'MegacoMessage',Msg), - ?line {ok,Msg} = asn1_wrapper:decode('OLD-MEDIA-GATEWAY-CONTROL', - 'MegacoMessage', - Bytes), + asn1_test_lib:roundtrip('OLD-MEDIA-GATEWAY-CONTROL', 'MegacoMessage', Msg), ok; -main(Mod='MEDIA-GATEWAY-CONTROL',Config) -> - ?line DataDir = ?config(data_dir,Config), - io:format("DataDir:~p~n",[DataDir]), - ?line {ok,FilenameList} = file:list_dir(filename:join([DataDir, - megacomessages])), - %% remove any junk files that may be in the megacomessage directory - Pred = fun(X) -> - case lists:reverse(X) of - [$l,$a,$v,$.|_R] ->true; - _ -> false - end - end, - MegacoMsgFilenameList = lists:filter(Pred,FilenameList), - - Fun = fun(F) -> - M = read_msg(filename:join([DataDir,megacomessages,F])), - {ok,B} = asn1_wrapper:encode(Mod,element(1,M),M), - {ok,M} = asn1_wrapper:decode(Mod,element(1,M),B) - end, - ?line lists:foreach(Fun,MegacoMsgFilenameList), - ok. - -read_msg(File) -> - case file:read_file(File) of - {ok,Bin} -> - binary_to_term(Bin); - _ -> - io:format("couldn't read file ~p~n",[File]) - end. - - -request(Mid, TransId, ContextId, CmdReq) when is_list(CmdReq) -> - Actions = [#'ActionRequest'{contextId = ContextId, - commandRequests = CmdReq}], - Req = {transactions, - [{transactionRequest, - #'TransactionRequest'{transactionId = TransId, - actions = Actions}}]}, - #'MegacoMessage'{mess = #'Message'{version = 1, - mId = Mid, - messageBody = Req}}. - -msg11() -> - TimeStamp = #'TimeNotation'{date = "19990729", - time = "22012001"}, - Parm = #'EventParameter'{eventParameterName = "ds", - value = "916135551212"}, - - Event = #'ObservedEvent'{eventName = "ddce", - timeNotation = TimeStamp, - eventParList = [Parm]}, - Desc = #'ObservedEventsDescriptor'{requestId = 2223, - observedEventLst = [Event]}, - NotifyReq = #'NotifyRequest'{terminationID = [#megaco_term_id{id = ?A4444}], - observedEventsDescriptor = Desc}, - CmdReq = #'CommandRequest'{command = {notifyReq, NotifyReq}}, - request(?MID, 10002, 0, [CmdReq]). +main('MEDIA-GATEWAY-CONTROL'=Mod, Config) -> + DataDir = ?config(data_dir, Config), + Files = filelib:wildcard(filename:join([DataDir,megacomessages,"*.val"])), + lists:foreach(fun(File) -> + {ok,Bin} = file:read_file(File), + V = binary_to_term(Bin), + T = element(1, V), + asn1_test_lib:roundtrip(Mod, T, V) + end, Files). diff --git a/lib/asn1/test/testMergeCompile.erl b/lib/asn1/test/testMergeCompile.erl index 8ef7ba3458..7cda71c441 100644 --- a/lib/asn1/test/testMergeCompile.erl +++ b/lib/asn1/test/testMergeCompile.erl @@ -30,42 +30,35 @@ main(Erule) -> %% test of module MS.set.asn that tests OTP-4492: different tagdefault in %% modules and types with same name in modules - ?line MSVal = {'Type4M2',8,true,three,"OCTET STRING"}, - ?line {ok,MSBytes} = asn1_wrapper:encode('MS','Type4M2',MSVal), - ?line {ok,MSVal} = asn1_wrapper:decode('MS','Type4M2',MSBytes), - + MSVal = {'Type4M2',8,true,three,"OCTET STRING"}, + asn1_test_lib:roundtrip('MS', 'Type4M2', MSVal), %% test of RANAP.set.asn1 - ?line _PIEVal = [{'ProtocolIE-Field',4,ignore,{'Cause',{radioNetwork,{'CauseRadioNetwork','rab-pre-empted'}}}}], PIEVal2 = [{'ProtocolIE-Field',4,ignore,{radioNetwork,'rab-pre-empted'}}], - ?line _PEVal = [{'ProtocolExtensionField',[0]}], -%% ?line EncVal = asn1rt_per_v1:encode_integer([],100), - ?line EncVal = + EncVal = case Erule of per -> <<1,100>>; uper -> <<1,100>>; ber -> - [2,1,1] + <<2,1,1>> end, - ?line PEVal2 = [{dummy,1,ignore,EncVal},{dummy,2,reject,EncVal}], - ?line Val2 = + PEVal2 = [{'ProtocolExtensionField',1,ignore,EncVal}, + {'ProtocolExtensionField',2,reject,EncVal}], + Val2 = #'InitiatingMessage'{procedureCode=1, criticality=ignore, value=#'Iu-ReleaseCommand'{protocolIEs=PIEVal2, protocolExtensions=asn1_NOVALUE}}, - ?line {ok,Bytes2} = asn1_wrapper:encode('RANAPSET','InitiatingMessage',Val2), - ?line {ok,_Ret2} = asn1_wrapper:decode('RANAPSET','InitiatingMessage',Bytes2), - - ?line Val3 = + asn1_test_lib:roundtrip('RANAPSET', 'InitiatingMessage', Val2), + Val3 = #'InitiatingMessage'{procedureCode=1, criticality=ignore, value=#'Iu-ReleaseCommand'{protocolIEs=PIEVal2, protocolExtensions=PEVal2}}, - ?line {ok,Bytes3} = asn1_wrapper:encode('RANAPSET','InitiatingMessage',Val3), - ?line {ok,_Ret3} = asn1_wrapper:decode('RANAPSET','InitiatingMessage',Bytes3). + asn1_test_lib:roundtrip('RANAPSET', 'InitiatingMessage', Val3). mvrasn(Erule) -> @@ -83,78 +76,73 @@ mvrasn(Erule) -> ?line ok = test(mvrasn6,'InsertSubscriberDataArg'). test(isd)-> - EncPdu = [48,128,129,7,145,148,113,50,1,0,241,131,1,0,176,128,5,0,161,128,48,22,2,1,1,144,2,241,33,145,4,0,1,2,3,146,3,36,131,16,148,2,1,42,48,35,2,1,2,144,2,241,33,145,4,255,255,255,255,146,3,37,147,18,147,0,148,13,7,67,79,77,80,65,78,89,4,67,79,77,53,48,28,2,1,3,144,2,241,33,146,3,26,98,31,148,14,9,67,79,77,80,65,78,89,49,50,3,67,79,77,0,0,0,0,152,1,2,0,0], - - ?line {ok,_} = asn1_wrapper:decode('Mvrasn4', - 'InsertSubscriberDataArg', - EncPdu), + EncPdu = <<48,128,129,7,145,148,113,50,1,0,241,131,1,0,176,128,5,0, + 161,128,48,22,2,1,1,144,2,241,33,145,4,0,1,2,3,146,3,36, + 131,16,148,2,1,42,48,35,2,1,2,144,2,241,33,145,4,255,255, + 255,255,146,3,37,147,18,147,0,148,13,7,67,79,77,80,65,78, + 89,4,67,79,77,53,48,28,2,1,3,144,2,241,33,146,3,26,98,31, + 148,14,9,67,79,77,80,65,78,89,49,50,3,67,79,77,0,0,0,0, + 152,1,2,0,0>>, + {ok,_} = 'Mvrasn4':decode('InsertSubscriberDataArg', EncPdu), ok; % % Problems with indefinite length encoding !!! % test(isd2)-> - EncPdu = [48, 128, 128, 8, 98, 2, 50, 1, 0, 0, 0, 241, 176, 128, 161, 128, 48, 128, 2, 1, 1, 144, 2, 241, 33, 145, 4, 255, 23, 12, 1, 146, 3, 9, 17, 1, 147, 0, 148, 13, 7, 67, 79, 77, 80, 65, 78, 89, 4, 67, 79, 77, 53, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - - ?line {ok,_DecPdu} = asn1_wrapper:decode('Mvrasn4', - 'InsertSubscriberDataArg', - EncPdu), - + EncPdu = <<48,128,128,8,98,2,50,1,0,0,0,241,176,128,161,128,48,128,2,1,1,144, + 2,241,33,145,4,255,23,12,1,146,3,9,17,1,147,0,148,13,7,67,79,77,80, + 65,78,89,4,67,79,77,53,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0>>, + {ok,_DecPdu} = 'Mvrasn4':decode('InsertSubscriberDataArg', EncPdu), ok; % % Is doing fine, although there is indefinite encoding used... !!! % test(dsd)-> - EncPdu = [48, 128, 128, 8, 98, 2, 50, 1, 0, 0, 0, 241, 170, 2, 5, 0, 0, 0, 0, 0], - - ?line {ok,_DecPdu} = asn1_wrapper:decode('Mvrasn4', - 'DeleteSubscriberDataArg', - EncPdu), - + EncPdu = <<48,128,128,8,98,2,50,1,0,0,0,241,170,2,5,0,0,0,0,0>>, + {ok,_DecPdu} = 'Mvrasn4':decode('DeleteSubscriberDataArg', EncPdu), ok; % % Is doing fine !!! % test(ul_res)-> - EncPdu = [48, 9, 4, 7, 145, 148, 113, 66, 16, 17, 241], - - ?line {ok,_DecPdu} = asn1_wrapper:decode('Mvrasn4', - 'UpdateGprsLocationRes', - EncPdu), - + EncPdu = <<48,9,4,7,145,148,113,66,16,17,241>>, + {ok,_DecPdu} = 'Mvrasn4':decode('UpdateGprsLocationRes', EncPdu), ok; test(seqofseq) -> - {ok,_V} = asn1_wrapper:decode('Mvrasn4', - 'SentParameters', - [48,129,190,161,128,4,16,176,197,182,68,41,243,188,205,123,13,9,145,206,200,144,102,4,4,176,197,182,68,4,8,41,243,188,205,123,13,9,145,0,0,161,128,4,16,39,0,3,117,35,189,130,21,42,104,49,194,212,24,151,234,4,4,39,0,3,117,4,8,35,189,130,21,42,104,49,194,0,0,161,128,4,16,62,207,166,59,71,29,37,97,120,25,132,80,144,251,161,123,4,4,62,207,166,59,4,8,71,29,37,97,120,25,132,80,0,0,161,128,4,16,95,183,173,151,17,76,148,146,248,102,127,215,102,224,39,60,4,4,95,183,173,151,4,8,17,76,148,146,248,102,127,215,0,0,161,128,4,16,41,198,247,157,117,190,203,170,91,146,88,91,223,220,188,16,4,4,41,198,247,157,4,8,117,190,203,170,91,146,88,91,0,0]), + EncPdu = <<48,129,190,161,128,4,16,176,197,182,68,41,243,188,205,123,13, + 9,145,206,200,144,102,4,4,176,197,182,68,4,8,41,243,188,205, + 123,13,9,145,0,0,161,128,4,16,39,0,3,117,35,189,130,21,42,104, + 49,194,212,24,151,234,4,4,39,0,3,117,4,8,35,189,130,21,42,104, + 49,194,0,0,161,128,4,16,62,207,166,59,71,29,37,97,120,25,132, + 80,144,251,161,123,4,4,62,207,166,59,4,8,71,29,37,97,120,25, + 132,80,0,0,161,128,4,16,95,183,173,151,17,76,148,146,248,102, + 127,215,102,224,39,60,4,4,95,183,173,151,4,8,17,76,148,146,248, + 102,127,215,0,0,161,128,4,16,41,198,247,157,117,190,203,170,91, + 146,88,91,223,220,188,16,4,4,41,198,247,157,4,8,117,190,203,170,91,146,88,91,0,0>>, + {ok,_V} = 'Mvrasn4':decode('SentParameters', EncPdu), ok; test('InsertSubscriberDataArg') -> - {ok,_V} = - asn1_wrapper:decode('Mvrasn4','InsertSubscriberDataArg', - [16#30,16#80,16#81,16#07,16#91,16#94, - 16#71,16#92,16#00,16#35,16#80,16#83, - 16#01,16#00,16#A6,16#06,16#04,16#01, - 16#21,16#04,16#01,16#22,16#B0,16#80, - 16#05,16#00,16#A1,16#80,16#30,16#1A, - 16#02,16#01,16#01,16#90,16#02,16#F1, - 16#21,16#92,16#03,16#0D,16#92,16#1F, - 16#94,16#0C,16#03,16#53,16#49,16#4D, - 16#03,16#47,16#53,16#4E,16#03,16#4C, - 16#4B,16#50,16#00,16#00,16#00,16#00, - 16#98,16#01,16#00,16#00,16#00]), + EncPdu = <<16#30,16#80,16#81,16#07,16#91,16#94, + 16#71,16#92,16#00,16#35,16#80,16#83, + 16#01,16#00,16#A6,16#06,16#04,16#01, + 16#21,16#04,16#01,16#22,16#B0,16#80, + 16#05,16#00,16#A1,16#80,16#30,16#1A, + 16#02,16#01,16#01,16#90,16#02,16#F1, + 16#21,16#92,16#03,16#0D,16#92,16#1F, + 16#94,16#0C,16#03,16#53,16#49,16#4D, + 16#03,16#47,16#53,16#4E,16#03,16#4C, + 16#4B,16#50,16#00,16#00,16#00,16#00, + 16#98,16#01,16#00,16#00,16#00>>, + {ok,_V} = 'Mvrasn4':decode('InsertSubscriberDataArg', EncPdu), ok. test(mvrasn6,'InsertSubscriberDataArg') -> Val = {'InsertSubscriberDataArg',"IMSI","Address","C",serviceGranted,["abc","cde"],["tele","serv","ice"],asn1_NOVALUE,asn1_NOVALUE,asn1_NOVALUE,asn1_NOVALUE,asn1_NOVALUE,asn1_NOVALUE,asn1_NOVALUE,asn1_NOVALUE,{'NAEA-PreferredCI',"NCC",asn1_NOVALUE},{'GPRSSubscriptionData','NULL',[{'PDP-Context',49,"PT","PDP-Address","QoS",'NULL',"APN",asn1_NOVALUE,asn1_NOVALUE,asn1_NOVALUE}],asn1_NOVALUE},'NULL',onlyMSC,{'LSAInformation','NULL',accessOutsideLSAsAllowed,[{'LSAData',"LSA","L",'NULL',asn1_NOVALUE},{'LSAData',"LSA","L",'NULL',asn1_NOVALUE}],asn1_NOVALUE},'NULL',{'LCSInformation',["Addr","ess","string"],[{'LCS-PrivacyClass',"S","ExtSS",notifyLocationAllowed,[{'ExternalClient',{'LCSClientExternalID',"Addr",asn1_NOVALUE},asn1_NOVALUE,asn1_NOVALUE,asn1_NOVALUE}],[broadcastService,anonymousLocation,targetMSsubscribedService],asn1_NOVALUE}],asn1_NOVALUE},100,"age",{'MC-SS-Info',"S","ExtSS",5,4,asn1_NOVALUE},"C",{'SGSN-CAMEL-SubscriptionInfo',{'GPRS-CSI',[{'GPRS-CamelTDPData',attach,13,"Addr",continueTransaction,asn1_NOVALUE}],11,asn1_NOVALUE,'NULL','NULL'},{'SMS-CSI',[{'SMS-CAMEL-TDP-DataList','sms-CollectedInfo',13,"Addr",continueTransaction,asn1_NOVALUE}],11,asn1_NOVALUE,'NULL','NULL'},asn1_NOVALUE},"ON"}, - - {ok,Bytes}= - asn1_wrapper:encode('Mvrasn6','InsertSubscriberDataArg',Val), - - {ok,_Res} = - asn1_wrapper:decode('Mvrasn6','InsertSubscriberDataArg',Bytes), - + {ok,Bytes} = 'Mvrasn6':encode('InsertSubscriberDataArg', Val), + {ok,_} = 'Mvrasn6':decode('InsertSubscriberDataArg', Bytes), ok. diff --git a/lib/asn1/test/testNBAPsystem.erl b/lib/asn1/test/testNBAPsystem.erl index 0f4459f5b2..57cb483374 100644 --- a/lib/asn1/test/testNBAPsystem.erl +++ b/lib/asn1/test/testNBAPsystem.erl @@ -19,7 +19,7 @@ %% -module(testNBAPsystem). --export([compile/2,test/2,cell_setup_req_msg/0]). +-export([compile/2,test/2]). -include_lib("test_server/include/test_server.hrl"). @@ -96,23 +96,16 @@ test(_Erule,Config) -> ticket_5812(Config) -> ?line Msg = v_5812(), - ?line {ok,B2} = asn1_wrapper:encode('NBAP-PDU-Discriptions', - 'NBAP-PDU', - Msg), + {ok,B2} = 'NBAP-PDU-Discriptions':encode('NBAP-PDU', Msg), V = <<0,28,74,0,3,48,0,0,1,0,123,64,41,0,0,0,126,64,35,95,208,2,89,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,145,0,1,205,0,0,0,0,2,98,64,1,128>>, ?line ok = compare(V,B2), - ?line {ok,Msg2} = asn1_wrapper:decode('NBAP-PDU-Discriptions', - 'NBAP-PDU',B2), + {ok,Msg2} = 'NBAP-PDU-Discriptions':decode('NBAP-PDU', B2), ?line ok = check_record_names(Msg2,Config). enc_audit_req_msg() -> Msg = {initiatingMessage, audit_req_msg()}, - ?line {ok,B}=asn1_wrapper:encode('NBAP-PDU-Discriptions', - 'NBAP-PDU', - Msg), - ?line {ok,_Msg}=asn1_wrapper:decode('NBAP-PDU-Discriptions', - 'NBAP-PDU', - B), + {ok,B} = 'NBAP-PDU-Discriptions':encode('NBAP-PDU', Msg), + {ok,_Msg} = 'NBAP-PDU-Discriptions':decode('NBAP-PDU', B), ?line {initiatingMessage, #'InitiatingMessage'{value=#'AuditRequest'{protocolIEs=[{_,114,ignore,_}], protocolExtensions = asn1_NOVALUE}}} = _Msg, @@ -121,12 +114,8 @@ enc_audit_req_msg() -> cell_setup_req_msg_test() -> Msg = {initiatingMessage, cell_setup_req_msg()}, - ?line {ok,B}=asn1_wrapper:encode('NBAP-PDU-Discriptions', - 'NBAP-PDU', - Msg), - ?line {ok,_Msg}=asn1_wrapper:decode('NBAP-PDU-Discriptions', - 'NBAP-PDU', - B), + {ok,B} = 'NBAP-PDU-Discriptions':encode('NBAP-PDU', Msg), + {ok,_Msg} = 'NBAP-PDU-Discriptions':decode('NBAP-PDU', B), io:format("Msg: ~P~n~n_Msg: ~P~n",[Msg,15,_Msg,15]), ok. diff --git a/lib/asn1/test/testOpenTypeImplicitTag.erl b/lib/asn1/test/testOpenTypeImplicitTag.erl index a37d8004ef..0fbf70d037 100644 --- a/lib/asn1/test/testOpenTypeImplicitTag.erl +++ b/lib/asn1/test/testOpenTypeImplicitTag.erl @@ -24,18 +24,9 @@ -include_lib("test_server/include/test_server.hrl"). main(_Rules) -> - - ?line {ok,Bytes1} = - asn1_wrapper:encode('OpenTypeImplicitTag','Seq', - {'Seq',[1,1,255],[1,1,255],12,[1,1,255]}), - ?line {ok,{'Seq',_,_,12,_}} = - asn1_wrapper:decode('OpenTypeImplicitTag','Seq', - lists:flatten(Bytes1)), - - ?line {ok,Bytes2} = - asn1_wrapper:encode('OpenTypeImplicitTag','Seq', - {'Seq',[1,1,255],asn1_NOVALUE,12,[1,1,255]}), - ?line {ok,{'Seq',_,asn1_NOVALUE,12,_}} = - asn1_wrapper:decode('OpenTypeImplicitTag','Seq', - lists:flatten(Bytes2)), + roundtrip('Seq', {'Seq',<<1,1,255>>,<<1,1,255>>,12,<<1,1,255>>}), + roundtrip('Seq', {'Seq',<<1,1,255>>,asn1_NOVALUE,12,<<1,1,255>>}), ok. + +roundtrip(T, V) -> + asn1_test_lib:roundtrip('OpenTypeImplicitTag', T, V). diff --git a/lib/asn1/test/testOpt.erl b/lib/asn1/test/testOpt.erl index a1ad8099b5..a6dcccad15 100644 --- a/lib/asn1/test/testOpt.erl +++ b/lib/asn1/test/testOpt.erl @@ -18,8 +18,6 @@ %% %% -module(testOpt). - --export([compile/2]). -export([main/1]). -include_lib("test_server/include/test_server.hrl"). @@ -39,92 +37,29 @@ bool32 = asn1_NOVALUE, bool33 = asn1_NOVALUE}). - -compile(Config,Rules) -> - - ?line DataDir = ?config(data_dir,Config), - ?line OutDir = ?config(priv_dir,Config), - ?line true = code:add_patha(?config(priv_dir,Config)), - ?line ok = asn1ct:compile(DataDir ++ "Opt",[Rules,{outdir,OutDir}]). - - - main(_Rules) -> - - ?line {ok,Bytes11} = asn1_wrapper:encode('Opt','Opt1',#'Opt1'{bool0 = true, - bool1 = true, - bool2 = true, - bool3 = true}), - ?line {ok,{'Opt1',true,true,true,true}} = - asn1_wrapper:decode('Opt','Opt1',lists:flatten(Bytes11)), + roundtrip('Opt1', #'Opt1'{bool0=true,bool1=true,bool2=true,bool3=true}), + roundtrip('Opt1', #'Opt1'{bool0=true,bool1=asn1_NOVALUE,bool2=asn1_NOVALUE, + bool3=asn1_NOVALUE}), + roundtrip('Opt1', #'Opt1'{bool0=true,bool1=asn1_NOVALUE,bool2=false,bool3=asn1_NOVALUE}), + roundtrip('Opt1', #'Opt1'{bool0=false,bool1=asn1_NOVALUE,bool2=asn1_NOVALUE,bool3=false}), - ?line {ok,Bytes12} = asn1_wrapper:encode('Opt','Opt1',#'Opt1'{bool0 = true}), - ?line {ok,{'Opt1',true,asn1_NOVALUE,asn1_NOVALUE,asn1_NOVALUE}} = - asn1_wrapper:decode('Opt','Opt1',lists:flatten(Bytes12)), - - ?line {ok,Bytes13} = asn1_wrapper:encode('Opt','Opt1',#'Opt1'{bool0 = true, - bool2 = false}), - ?line {ok,{'Opt1',true,asn1_NOVALUE,false,asn1_NOVALUE}} = - asn1_wrapper:decode('Opt','Opt1',lists:flatten(Bytes13)), - - ?line {ok,Bytes14} = asn1_wrapper:encode('Opt','Opt1',#'Opt1'{bool0 = false, - bool3 = false}), - ?line {ok,{'Opt1',false,asn1_NOVALUE,asn1_NOVALUE,false}} = - asn1_wrapper:decode('Opt','Opt1',lists:flatten(Bytes14)), - - - - - ?line {ok,Bytes21} = asn1_wrapper:encode('Opt','Opt2',#'Opt2'{bool10 = false, - bool11 = false, - bool12 = false, - bool13 = false}), - ?line {ok,{'Opt2',false,false,false,false}} = - asn1_wrapper:decode('Opt','Opt2',lists:flatten(Bytes21)), - - ?line {ok,Bytes22} = asn1_wrapper:encode('Opt','Opt2',#'Opt2'{bool10 = true, - bool13 = false}), - ?line {ok,{'Opt2',true,asn1_NOVALUE,asn1_NOVALUE,false}} = - asn1_wrapper:decode('Opt','Opt2',lists:flatten(Bytes22)), - - ?line {ok,Bytes23} = asn1_wrapper:encode('Opt','Opt2',#'Opt2'{bool10 = true, - bool11 = false, - bool13 = false}), - ?line {ok,{'Opt2',true,false,asn1_NOVALUE,false}} = - asn1_wrapper:decode('Opt','Opt2',lists:flatten(Bytes23)), - - ?line {ok,Bytes24} = asn1_wrapper:encode('Opt','Opt2',#'Opt2'{bool10 = false, - bool12 = false, - bool13 = false}), - ?line {ok,{'Opt2',false,asn1_NOVALUE,false,false}} = - asn1_wrapper:decode('Opt','Opt2',lists:flatten(Bytes24)), - - - - - ?line {ok,Bytes31} = asn1_wrapper:encode('Opt','Opt3',#'Opt3'{bool30 = false, - bool31 = false, - bool32 = false, - bool33 = false}), - ?line {ok,{'Opt3',false,false,false,false}} = - asn1_wrapper:decode('Opt','Opt3',lists:flatten(Bytes31)), - - ?line {ok,Bytes32} = asn1_wrapper:encode('Opt','Opt3',#'Opt3'{}), - ?line {ok,{'Opt3',asn1_NOVALUE,asn1_NOVALUE,asn1_NOVALUE,asn1_NOVALUE}} = - asn1_wrapper:decode('Opt','Opt3',lists:flatten(Bytes32)), - - ?line {ok,Bytes33} = asn1_wrapper:encode('Opt','Opt3',#'Opt3'{bool30 = true}), - ?line {ok,{'Opt3',true,asn1_NOVALUE,asn1_NOVALUE,asn1_NOVALUE}} = - asn1_wrapper:decode('Opt','Opt3',lists:flatten(Bytes33)), - - ?line {ok,Bytes34} = asn1_wrapper:encode('Opt','Opt3',#'Opt3'{bool32 = false}), - ?line {ok,{'Opt3',asn1_NOVALUE,asn1_NOVALUE,false,asn1_NOVALUE}} = - asn1_wrapper:decode('Opt','Opt3',lists:flatten(Bytes34)), - - ?line {ok,Bytes35} = asn1_wrapper:encode('Opt','Opt3',#'Opt3'{bool33 = false}), - ?line {ok,{'Opt3',asn1_NOVALUE,asn1_NOVALUE,asn1_NOVALUE,false}} = - asn1_wrapper:decode('Opt','Opt3',lists:flatten(Bytes35)), - - - + roundtrip('Opt2', #'Opt2'{bool10=false,bool11=false,bool12=false,bool13=false}), + roundtrip('Opt2', #'Opt2'{bool10=true,bool11=asn1_NOVALUE,bool12=asn1_NOVALUE, + bool13=false}), + roundtrip('Opt2', #'Opt2'{bool10=true,bool11=false,bool12=asn1_NOVALUE,bool13=false}), + roundtrip('Opt2', #'Opt2'{bool10=false,bool11=asn1_NOVALUE,bool12=false,bool13=false}), + + roundtrip('Opt3', #'Opt3'{bool30=false,bool31=false,bool32=false,bool33=false}), + roundtrip('Opt3', #'Opt3'{bool30=asn1_NOVALUE,bool31=asn1_NOVALUE,bool32=asn1_NOVALUE, + bool33=asn1_NOVALUE}), + roundtrip('Opt3', #'Opt3'{bool30=true,bool31=asn1_NOVALUE,bool32=asn1_NOVALUE, + bool33=asn1_NOVALUE}), + roundtrip('Opt3', #'Opt3'{bool30=asn1_NOVALUE,bool31=asn1_NOVALUE,bool32=false, + bool33=asn1_NOVALUE}), + roundtrip('Opt3', #'Opt3'{bool30=asn1_NOVALUE,bool31=asn1_NOVALUE,bool32=asn1_NOVALUE, + bool33=false}), ok. + +roundtrip(Type, Value) -> + asn1_test_lib:roundtrip('Opt', Type, Value). diff --git a/lib/asn1/test/testParamBasic.erl b/lib/asn1/test/testParamBasic.erl index a10468d592..3a55408e94 100644 --- a/lib/asn1/test/testParamBasic.erl +++ b/lib/asn1/test/testParamBasic.erl @@ -29,53 +29,22 @@ -record('T22',{number, string}). main(Rules) -> - - ?line {ok,Bytes11} = - asn1_wrapper:encode('ParamBasic','T11', - #'T11'{number = 11, - string = "hello"}), - ?line {ok,{'T11',11,"hello"}} = - asn1_wrapper:decode('ParamBasic','T11',Bytes11), - - ?line {ok,Bytes12} = - asn1_wrapper:encode('ParamBasic','T12', - #'T12'{number = 11, - string = <<2#10101:5>>}), - {ok,{'T12',11,<<2#10101:5>>}} = - asn1_wrapper:decode('ParamBasic','T12',Bytes12), - - ?line {ok,Bytes13} = - asn1_wrapper:encode('ParamBasic','T21', - #'T21'{number = 11, - string = "hello"}), - ?line {ok,{'T21',11,"hello"}} = - asn1_wrapper:decode('ParamBasic','T21',Bytes13), - - ?line {ok,Bytes14} = - asn1_wrapper:encode('ParamBasic','T22', - #'T22'{number = 11, - string = <<2#10101:5>>}), - {ok,{'T22',11,<<2#10101:5>>}} = - asn1_wrapper:decode('ParamBasic','T22',Bytes14), - + roundtrip('T11', #'T11'{number=11,string="hello"}), + roundtrip('T12', #'T12'{number=11,string = <<21:5>>}), + roundtrip('T21', #'T21'{number=11,string="hello"}), + roundtrip('T22', #'T22'{number=11,string = <<21:5>>}), case Rules of der -> - - ?line {ok,[48,3,128,1,11]} = - asn1_wrapper:encode('ParamBasic','T11', - #'T11'{number = 11, - string = "hej"}), - ?line {ok,{'T11',11,"hej"}} = - asn1_wrapper:decode('ParamBasic','T11',[48,3,128,1,11]), - - ?line {ok,[48,3,128,1,11]} = - asn1_wrapper:encode('ParamBasic','T12', - #'T12'{number = 11, - string = [1,0,1,0]}), - - ?line {ok,{'T12',11,[1,0,1,0]}} = - asn1_wrapper:decode('ParamBasic','T12',[48,3,128,1,11]); + <<48,3,128,1,11>> = + roundtrip_enc('T11', #'T11'{number=11,string="hej"}), + <<48,3,128,1,11>> = + roundtrip_enc('T12', #'T12'{number=11,string=[1,0,1,0]}); _ -> ok end, - ok. + +roundtrip(Type, Value) -> + asn1_test_lib:roundtrip('ParamBasic', Type, Value). + +roundtrip_enc(Type, Value) -> + asn1_test_lib:roundtrip_enc('ParamBasic', Type, Value). diff --git a/lib/asn1/test/testParameterizedInfObj.erl b/lib/asn1/test/testParameterizedInfObj.erl index 1dfa52f401..f3b4f9b170 100644 --- a/lib/asn1/test/testParameterizedInfObj.erl +++ b/lib/asn1/test/testParameterizedInfObj.erl @@ -41,53 +41,51 @@ param(Erule) -> iE_Extensions = [#'ProtocolExtensionField'{id=14, criticality=reject, - extensionValue=open_type(Erule,[0])}, + extensionValue= <<0>>}, #'ProtocolExtensionField'{id=2, criticality=ignore, - extensionValue=open_type(Erule,[1])}]}, + extensionValue= <<1>>}]}, BERVal = #'AllocationOrRetentionPriority' {priorityLevel = true, iE_Extensions = [#'ProtocolExtensionField'{id=14, criticality=reject, - extensionValue=[2,1,0]}, + extensionValue= <<2,1,0>>}, #'ProtocolExtensionField'{id=2, criticality=ignore, - extensionValue=[2,1,1]}]}, - ?line {ok,Bytes1} = - case asn1_wrapper:erule(Erule) of - per -> - asn1_wrapper:encode('Param','AllocationOrRetentionPriority', - PERVal); - _ -> - asn1_wrapper:encode('Param','AllocationOrRetentionPriority', - BERVal) - end, - - ?line {ok,{'AllocationOrRetentionPriority',true,[_R1,_R2]}} = - asn1_wrapper:decode('Param','AllocationOrRetentionPriority',Bytes1), + extensionValue= <<2,1,1>>}]}, + case Erule of + ber -> + roundtrip('AllocationOrRetentionPriority', BERVal); + per -> + roundtrip('AllocationOrRetentionPriority', PERVal); + uper -> + roundtrip('AllocationOrRetentionPriority', PERVal) + end, %% test code for OTP-4242, ValueFromObject - case asn1_wrapper:erule(Erule) of + case Erule of ber -> - ?line {ok,_Val3} = asn1_wrapper:decode('Param','OS1',[4,2,1,2]), - ?line {error,_Reason1} = - asn1_wrapper:decode('Param','OS1',[4,4,1,2,3,4]), - ?line {error,_Reason2} = - asn1_wrapper:decode('Param','OS2',[4,4,1,2,3,4]), - ?line {ok,_Val4} = asn1_wrapper:decode('Param','OS1',[4,2,1,2]); - per -> - ?line {ok,Bytes3} = - asn1_wrapper:encode('Param','OS1',[1,2]), - ?line {ok,[1,2]} = - asn1_wrapper:decode('Param','OS1',Bytes3), - ?line {error,_Reason3} = - asn1_wrapper:encode('Param','OS1',[1,2,3,4]) + {ok,_Val3} = 'Param':decode('OS1', [4,2,1,2]), + {error,_Reason1} = 'Param':decode('OS1',[4,4,1,2,3,4]), + {error,_Reason2} = 'Param':decode('OS2',[4,4,1,2,3,4]), + {ok,_Val4} = 'Param':decode('OS1',[4,2,1,2]); + _ -> %per/uper + roundtrip('OS1', [1,2]), + {error,_Reason3} = 'Param':encode('OS1', [1,2,3,4]) end, + roundtrip('Scl', {'Scl',42,{a,9738654}}), + roundtrip('Scl', {'Scl',42,{b,false}}), + roundtrip('Scl', {'Scl',42,{b,true}}), + ok. +roundtrip(T, V) -> + asn1_test_lib:roundtrip('Param', T, V). + + ranap(_Erule) -> PIEVal2 = [{'ProtocolIE-Field',4,ignore,{radioNetwork,'rab-pre-empted'}}], ?line Val2 = @@ -96,16 +94,11 @@ ranap(_Erule) -> value=#'Iu-ReleaseCommand'{protocolIEs=PIEVal2, protocolExtensions=asn1_NOVALUE}}, - ?line {ok,Bytes2} = asn1_wrapper:encode('RANAP','InitiatingMessage',Val2), - ?line {ok,_Ret2} = asn1_wrapper:decode('RANAP','InitiatingMessage',Bytes2), + {ok,Bytes2} = 'RANAP':encode('InitiatingMessage', Val2), + {ok,_Ret2} = 'RANAP':decode('InitiatingMessage', Bytes2), ok. -open_type(uper,Val) when is_list(Val) -> - list_to_binary(Val); -open_type(_,Val) -> - Val. - param2(Config, Erule) -> roundtrip2('HandoverRequired', {'HandoverRequired', @@ -138,7 +131,7 @@ param2(Config, Erule) -> {'ProtocolIE-Field',2,-42}, {'ProtocolIE-Field',100,Open100}, {'ProtocolIE-Field',101,Open101}]}} = - asn1_wrapper:decode('Param2', 'HandoverRequired', Enc), + 'Param2':decode('HandoverRequired', Enc), true = is_binary(Open100), true = is_binary(Open101), @@ -150,6 +143,4 @@ param2(Config, Erule) -> roundtrip2(T, V) -> - {ok,Enc} = asn1_wrapper:encode('Param2', T, V), - {ok,V} = asn1_wrapper:decode('Param2', T, Enc), - Enc. + asn1_test_lib:roundtrip_enc('Param2', T, V). diff --git a/lib/asn1/test/testPrim.erl b/lib/asn1/test/testPrim.erl index a6e68a9fe0..e07379e634 100644 --- a/lib/asn1/test/testPrim.erl +++ b/lib/asn1/test/testPrim.erl @@ -36,8 +36,7 @@ bool(Rules) -> case Rules of ber -> [begin - {error,{asn1,{encode_boolean,517}}} = - (catch 'Prim':encode(T, 517)) + {error,{asn1,{encode_boolean,517}}} = enc_error(T, 517) end || T <- Types], ok; _ -> @@ -90,12 +89,12 @@ enum(Rules) -> roundtrip('Enum', monday), roundtrip('Enum', thursday), - {error,{asn1,{_,4}}} = (catch 'Prim':encode('Enum', 4)), + {error,{asn1,{_,4}}} = enc_error('Enum', 4), case Rules of Per when Per =:= per; Per =:= uper -> - {ok,<<0>>} = 'Prim':encode('SingleEnumVal', true), - {ok,<<0>>} = 'Prim':encode('SingleEnumValExt', true); + <<0>> = roundtrip('SingleEnumVal', true), + <<0>> = roundtrip('SingleEnumValExt', true); ber -> ok end, @@ -128,15 +127,36 @@ null(_Rules) -> %%========================================================== %% Null ::= NULL %%========================================================== - - {ok,Bytes1} = asn1_wrapper:encode('Prim','Null',monday), - {ok,'NULL'} = asn1_wrapper:decode('Prim','Null',lists:flatten(Bytes1)), + roundtrip('Null', monday, 'NULL'), ok. roundtrip(T, V) -> - {ok,E} = 'Prim':encode(T, V), - {ok,V} = 'Prim':decode(T, E), - E. + roundtrip(T, V, V). + +roundtrip(Type, Value, ExpectedValue) -> + case get(no_ok_wrapper) of + false -> + asn1_test_lib:roundtrip_enc('Prim', Type, Value, ExpectedValue); + true -> + M = 'Prim', + Enc = M:encode(Type, Value), + ExpectedValue = M:decode(Type, Enc), + Enc + end. + +enc_error(T, V) -> + case get(no_ok_wrapper) of + false -> + 'Prim':encode(T, V); + true -> + try 'Prim':encode(T, V) of + _ -> + ?t:fail() + catch + _:Reason -> + Reason + end + end. real(_Rules) -> %%========================================================== @@ -144,67 +164,45 @@ real(_Rules) -> %%========================================================== %% Base 2 - ?line {ok,Bytes1} = asn1_wrapper:encode('Real','AngleInRadians',{1,2,1}), - ?line {ok,{1,2,1}} = asn1_wrapper:decode('Real','AngleInRadians',Bytes1), - - ?line {ok,Bytes2} = asn1_wrapper:encode('Real','AngleInRadians',{129,2,1}), - ?line {ok,{129,2,1}} = asn1_wrapper:decode('Real','AngleInRadians',Bytes2), - - ?line {ok,Bytes3} = asn1_wrapper:encode('Real','AngleInRadians',{128,2,1}), - ?line {ok,{1,2,8}} = asn1_wrapper:decode('Real','AngleInRadians',Bytes3), - - ?line {ok,Bytes4} = asn1_wrapper:encode('Real','AngleInRadians',{128,2,-7}), - ?line {ok,{1,2,0}} = asn1_wrapper:decode('Real','AngleInRadians',Bytes4), - - ?line {ok,Bytes5} = asn1_wrapper:encode('Real','AngleInRadians',{16#f1f1f1,2,128}), - ?line {ok,{16#f1f1f1,2,128}} = asn1_wrapper:decode('Real','AngleInRadians',Bytes5), + real_roundtrip('AngleInRadians', {1,2,1}), + real_roundtrip('AngleInRadians', {129,2,1}), + real_roundtrip('AngleInRadians', {128,2,1}, {1,2,8}), + real_roundtrip('AngleInRadians', {128,2,-7}, {1,2,0}), + real_roundtrip('AngleInRadians', {16#f1f1f1,2,128}), %% Base 10, tuple format - ?line {ok,Bytes6} = asn1_wrapper:encode('Real','AngleInRadians',{1,10,1}), - ?line {ok,"1.E1"} = asn1_wrapper:decode('Real','AngleInRadians',Bytes6), - - ?line {ok,Bytes7} = asn1_wrapper:encode('Real','AngleInRadians',{100,10,1}), - ?line {ok,"1.E3"} = asn1_wrapper:decode('Real','AngleInRadians',Bytes7), - - ?line {ok,Bytes8} = asn1_wrapper:encode('Real','AngleInRadians',{-100,10,1}), - ?line {ok,"-1.E3"} = asn1_wrapper:decode('Real','AngleInRadians',Bytes8), - - ?line {ok,Bytes9} = asn1_wrapper:encode('Real','AngleInRadians',{00002,10,1}), - ?line {ok,"2.E1"} = asn1_wrapper:decode('Real','AngleInRadians',Bytes9), - - ?line {ok,Bytes10} = asn1_wrapper:encode('Real','AngleInRadians',{123000,10,0}), - ?line {ok,"123.E3"} = asn1_wrapper:decode('Real','AngleInRadians',Bytes10), - - ?line {ok,Bytes11} = asn1_wrapper:encode('Real','AngleInRadians',{123456789,10,123456789}), - ?line {ok,"123456789.E123456789"} = asn1_wrapper:decode('Real','AngleInRadians',Bytes11), - - ?line {ok,Bytes12} = asn1_wrapper:encode('Real','AngleInRadians',{-12345,10,-12345}), - ?line {ok,"-12345.E-12345"} = asn1_wrapper:decode('Real','AngleInRadians',Bytes12), + real_roundtrip('AngleInRadians', {1,10,1}, "1.E1"), + real_roundtrip('AngleInRadians', {100,10,1}, "1.E3"), + real_roundtrip('AngleInRadians', {-100,10,1}, "-1.E3"), + real_roundtrip('AngleInRadians', {2,10,1}, "2.E1"), + real_roundtrip('AngleInRadians', {123000,10,0}, "123.E3"), + real_roundtrip('AngleInRadians', {123456789,10,123456789}, + "123456789.E123456789" ), + real_roundtrip('AngleInRadians', {-12345,10,-12345}, "-12345.E-12345"), %% Base 10, string format NR3 - - ?line {ok,Bytes13} = asn1_wrapper:encode('Real','AngleInRadians',"123.123E123"), - ?line {ok,"123123.E120"} = asn1_wrapper:decode('Real','AngleInRadians',Bytes13), - - ?line {ok,Bytes14} = asn1_wrapper:encode('Real','AngleInRadians',"0.0E0"), - ?line {ok,"0.E+0"} = asn1_wrapper:decode('Real','AngleInRadians',Bytes14), - ?line {ok,Bytes15} = asn1_wrapper:encode('Real','AngleInRadians',"0.0123"), - ?line {ok,"123.E-4"} = asn1_wrapper:decode('Real','AngleInRadians',Bytes15), + real_roundtrip('AngleInRadians', "123.123E123", "123123.E120"), + real_roundtrip('AngleInRadians', "0.0E0", "0.E+0"), + real_roundtrip('AngleInRadians', "0.0123", "123.E-4"), + real_roundtrip('AngleInRadians', "0", "0.E+0"), + real_roundtrip('AngleInRadians', "-123.45", "-12345.E-2"), + real_roundtrip('AngleInRadians', "123456789E123456789", + "123456789.E123456789"), + real_roundtrip('AngleInRadians', "01.000E1", "1.E1"), + real_roundtrip('AngleInRadians', "120.0001", "1200001.E-4"), - ?line {ok,Bytes16} = asn1_wrapper:encode('Real','AngleInRadians',"0"), - ?line {ok,"0.E+0"} = asn1_wrapper:decode('Real','AngleInRadians',Bytes16), - - ?line {ok,Bytes17} = asn1_wrapper:encode('Real','AngleInRadians',"-123.45"), - ?line {ok,"-12345.E-2"} = asn1_wrapper:decode('Real','AngleInRadians',Bytes17), - - ?line {ok,Bytes18} = - asn1_wrapper:encode('Real','AngleInRadians',"123456789E123456789"), - ?line {ok,"123456789.E123456789"} = - asn1_wrapper:decode('Real','AngleInRadians',Bytes18), + ok. - ?line {ok,Bytes19} = asn1_wrapper:encode('Real','AngleInRadians',"01.000E1"), - ?line {ok,"1.E1"} = asn1_wrapper:decode('Real','AngleInRadians',Bytes19), +real_roundtrip(T, V) -> + real_roundtrip(T, V, V). - ?line {ok,Bytes20} = asn1_wrapper:encode('Real','AngleInRadians',"120.0001"), - ?line {ok,"1200001.E-4"} = asn1_wrapper:decode('Real','AngleInRadians',Bytes20). +real_roundtrip(Type, Value, ExpectedValue) -> + case get(no_ok_wrapper) of + false -> + asn1_test_lib:roundtrip('Real', Type, Value, ExpectedValue); + true -> + M = 'Real', + ExpectedValue = M:decode(Type, M:encode(Type, Value)), + ok + end. diff --git a/lib/asn1/test/testPrimExternal.erl b/lib/asn1/test/testPrimExternal.erl index 65c3c3a31a..07a1de931f 100644 --- a/lib/asn1/test/testPrimExternal.erl +++ b/lib/asn1/test/testPrimExternal.erl @@ -24,84 +24,27 @@ -include_lib("test_server/include/test_server.hrl"). external(_Rules) -> - - - ?line {ok,Bytes10} = asn1_wrapper:encode('PrimExternal','NT',"kalle"), - ?line {ok,"kalle"} = asn1_wrapper:decode('PrimExternal','NT',lists:flatten(Bytes10)), - - ?line {ok,Bytes11} = asn1_wrapper:encode('PrimExternal','Imp',"kalle"), - ?line {ok,"kalle"} = asn1_wrapper:decode('PrimExternal','Imp',lists:flatten(Bytes11)), - - ?line {ok,Bytes12} = asn1_wrapper:encode('PrimExternal','Exp',"kalle"), - ?line {ok,"kalle"} = asn1_wrapper:decode('PrimExternal','Exp',lists:flatten(Bytes12)), - - - ?line {ok,Bytes13} = asn1_wrapper:encode('PrimExternal','NTNT',"kalle"), - ?line {ok,"kalle"} = asn1_wrapper:decode('PrimExternal','NTNT',lists:flatten(Bytes13)), - - ?line {ok,Bytes14} = asn1_wrapper:encode('PrimExternal','NTImp',"kalle"), - ?line {ok,"kalle"} = asn1_wrapper:decode('PrimExternal','NTImp',lists:flatten(Bytes14)), - - ?line {ok,Bytes15} = asn1_wrapper:encode('PrimExternal','NTExp',"kalle"), - ?line {ok,"kalle"} = asn1_wrapper:decode('PrimExternal','NTExp',lists:flatten(Bytes15)), - - - ?line {ok,Bytes16} = asn1_wrapper:encode('PrimExternal','ImpNT',"kalle"), - ?line {ok,"kalle"} = asn1_wrapper:decode('PrimExternal','ImpNT',lists:flatten(Bytes16)), - - ?line {ok,Bytes17} = asn1_wrapper:encode('PrimExternal','ImpImp',"kalle"), - ?line {ok,"kalle"} = asn1_wrapper:decode('PrimExternal','ImpImp',lists:flatten(Bytes17)), - - ?line {ok,Bytes18} = asn1_wrapper:encode('PrimExternal','ImpExp',"kalle"), - ?line {ok,"kalle"} = asn1_wrapper:decode('PrimExternal','ImpExp',lists:flatten(Bytes18)), - - - ?line {ok,Bytes19} = asn1_wrapper:encode('PrimExternal','ExpNT',"kalle"), - ?line {ok,"kalle"} = asn1_wrapper:decode('PrimExternal','ExpNT',lists:flatten(Bytes19)), - - ?line {ok,Bytes20} = asn1_wrapper:encode('PrimExternal','ExpImp',"kalle"), - ?line {ok,"kalle"} = asn1_wrapper:decode('PrimExternal','ExpImp',lists:flatten(Bytes20)), - - ?line {ok,Bytes21} = asn1_wrapper:encode('PrimExternal','ExpExp',"kalle"), - ?line {ok,"kalle"} = asn1_wrapper:decode('PrimExternal','ExpExp',lists:flatten(Bytes21)), - - - - - - ?line {ok,Bytes31} = asn1_wrapper:encode('PrimExternal','XNTNT',"kalle"), - ?line {ok,"kalle"} = asn1_wrapper:decode('PrimExternal','XNTNT',lists:flatten(Bytes31)), - - ?line {ok,Bytes32} = asn1_wrapper:encode('PrimExternal','XNTImp',"kalle"), - ?line {ok,"kalle"} = asn1_wrapper:decode('PrimExternal','XNTImp',lists:flatten(Bytes32)), - - ?line {ok,Bytes33} = asn1_wrapper:encode('PrimExternal','XNTExp',"kalle"), - ?line {ok,"kalle"} = asn1_wrapper:decode('PrimExternal','XNTExp',lists:flatten(Bytes33)), - - - ?line {ok,Bytes34} = asn1_wrapper:encode('PrimExternal','XImpNT',"kalle"), - ?line {ok,"kalle"} = asn1_wrapper:decode('PrimExternal','XImpNT',lists:flatten(Bytes34)), - - ?line {ok,Bytes35} = asn1_wrapper:encode('PrimExternal','XImpImp',"kalle"), - ?line {ok,"kalle"} = asn1_wrapper:decode('PrimExternal','XImpImp',lists:flatten(Bytes35)), - - ?line {ok,Bytes36} = asn1_wrapper:encode('PrimExternal','XImpExp',"kalle"), - ?line {ok,"kalle"} = asn1_wrapper:decode('PrimExternal','XImpExp',lists:flatten(Bytes36)), - - - ?line {ok,Bytes37} = asn1_wrapper:encode('PrimExternal','XExpNT',"kalle"), - ?line {ok,"kalle"} = asn1_wrapper:decode('PrimExternal','XExpNT',lists:flatten(Bytes37)), - - ?line {ok,Bytes38} = asn1_wrapper:encode('PrimExternal','XExpImp',"kalle"), - ?line {ok,"kalle"} = asn1_wrapper:decode('PrimExternal','XExpImp',lists:flatten(Bytes38)), - - ?line {ok,Bytes39} = asn1_wrapper:encode('PrimExternal','XExpExp',"kalle"), - ?line {ok,"kalle"} = asn1_wrapper:decode('PrimExternal','XExpExp',lists:flatten(Bytes39)), - - - - - - - -ok. + Types = ['NT', + 'Imp', + 'Exp', + 'NTNT', + 'NTImp', + 'NTExp', + 'ImpNT', + 'ImpImp', + 'ImpExp', + 'ExpNT', + 'ExpImp', + 'ExpExp', + 'XNTNT', + 'XNTImp', + 'XNTExp', + 'XImpNT', + 'XImpImp', + 'XImpExp', + 'XExpNT', + 'XExpImp', + 'XExpExp'], + _ = [asn1_test_lib:roundtrip('PrimExternal', T, "kalle") || + T <- Types], + ok. diff --git a/lib/asn1/test/testPrimStrings.erl b/lib/asn1/test/testPrimStrings.erl index e2322c92a9..be5409aa92 100644 --- a/lib/asn1/test/testPrimStrings.erl +++ b/lib/asn1/test/testPrimStrings.erl @@ -28,9 +28,46 @@ -export([bmp_string/1]). -export([times/1]). -export([utf8_string/1]). +-export([fragmented/1]). -include_lib("test_server/include/test_server.hrl"). +fragmented(Rules) -> + Lens = fragmented_lengths(), + fragmented_octet_string(Rules, Lens), + case Rules of + per -> + %% NYI. + ok; + _ -> + fragmented_strings(Lens) + end. + +fragmented_strings(Lens) -> + Types = ['Ns','Ps','Ps11','Vis','IA5'], + [fragmented_strings(Len, Types) || Len <- Lens], + ok. + +fragmented_strings(Len, Types) -> + Str = make_ns_value(Len), + [roundtrip(Type, Str) || Type <- Types], + ok. + +make_ns_value(0) -> []; +make_ns_value(N) -> [($0 - 1) + random:uniform(10)|make_ns_value(N-1)]. + +fragmented_lengths() -> + K16 = 1 bsl 14, + K32 = K16 + K16, + K48 = K32 + K16, + K64 = K48 + K16, + [0,1,14,15,16,17,127,128, + K16-1,K16,K16+1,K16+(1 bsl 7)-1,K16+(1 bsl 7),K16+(1 bsl 7)+1, + K32-1,K32,K32+1,K32+(1 bsl 7)-1,K32+(1 bsl 7),K32+(1 bsl 7)+1, + K48-1,K48,K48+1,K48+(1 bsl 7)-1,K48+(1 bsl 7),K48+(1 bsl 7)+1, + K64-1,K64,K64+1,K64+(1 bsl 7)-1,K64+(1 bsl 7),K64+(1 bsl 7)+1, + K64+K16-1,K64+K16,K64+K16+1]. + bit_string(Rules) -> %%========================================================== @@ -311,8 +348,6 @@ octet_string(Rules) -> ok end, - fragmented_octet_string(Rules), - S255 = lists:seq(1, 255), Strings = {type,true,"","1","12","345",true, S255,[$a|S255],[$a,$b|S255],397}, @@ -324,17 +359,7 @@ octet_string(Rules) -> p_roundtrip('OsVarStringsExt', ShortenedStrings), ok. -fragmented_octet_string(Erules) -> - K16 = 1 bsl 14, - K32 = K16 + K16, - K48 = K32 + K16, - K64 = K48 + K16, - Lens = [0,1,14,15,16,17,127,128, - K16-1,K16,K16+1,K16+(1 bsl 7)-1,K16+(1 bsl 7),K16+(1 bsl 7)+1, - K32-1,K32,K32+1,K32+(1 bsl 7)-1,K32+(1 bsl 7),K32+(1 bsl 7)+1, - K48-1,K48,K48+1,K48+(1 bsl 7)-1,K48+(1 bsl 7),K48+(1 bsl 7)+1, - K64-1,K64,K64+1,K64+(1 bsl 7)-1,K64+(1 bsl 7),K64+(1 bsl 7)+1, - K64+K16-1,K64+K16,K64+K16+1], +fragmented_octet_string(Erules, Lens) -> Types = ['Os','OsFrag','OsFragExt'], [fragmented_octet_string(Erules, Types, L) || L <- Lens], fragmented_octet_string(Erules, ['FixedOs65536'], 65536), @@ -697,14 +722,10 @@ p_roundtrip(Type, Value0) -> roundtrip(Type, Value). roundtrip(Type, Value) -> - {ok,Encoded} = 'PrimStrings':encode(Type, Value), - {ok,Value} = 'PrimStrings':decode(Type, Encoded), - ok. + roundtrip(Type, Value, Value). roundtrip(Type, Value, Expected) -> - {ok,Encoded} = 'PrimStrings':encode(Type, Value), - {ok,Expected} = 'PrimStrings':decode(Type, Encoded), - ok. + asn1_test_lib:roundtrip('PrimStrings', Type, Value, Expected). bs_roundtrip(Type, Value) -> bs_roundtrip(Type, Value, Value). diff --git a/lib/asn1/test/testSelectionTypes.erl b/lib/asn1/test/testSelectionTypes.erl index 6d1641388f..6d060321da 100644 --- a/lib/asn1/test/testSelectionTypes.erl +++ b/lib/asn1/test/testSelectionTypes.erl @@ -18,19 +18,16 @@ %% %% -module(testSelectionTypes). - -export([test/0]). -include_lib("test_server/include/test_server.hrl"). test() -> Val = ["PrintableString","PrintableString","PrintableString"], - ?line {ok,Bin}=asn1_wrapper:encode('SelectionType','MendeleyevTable',Val), - ?line {ok,Val} = asn1_wrapper:decode('SelectionType','MendeleyevTable',Bin), - - ?line Val2 = ['SelectionType':einsteinium()], - ?line ["Es"] = Val2, - - ?line {ok,Bin2}=asn1_wrapper:encode('SelectionType','MendeleyevTable',Val2), - ?line {ok,Val2} = asn1_wrapper:decode('SelectionType','MendeleyevTable',Bin2). + ["Es"] = Val2 = ['SelectionType':einsteinium()], + roundtrip('MendeleyevTable', Val), + roundtrip('MendeleyevTable', Val2), + ok. +roundtrip(T, V) -> + asn1_test_lib:roundtrip('SelectionType', T, V). diff --git a/lib/asn1/test/testSeq2738.erl b/lib/asn1/test/testSeq2738.erl index cddfe4b311..9c059f2fc9 100644 --- a/lib/asn1/test/testSeq2738.erl +++ b/lib/asn1/test/testSeq2738.erl @@ -18,27 +18,16 @@ %% %% -module(testSeq2738). - -export([main/1]). -include_lib("test_server/include/test_server.hrl"). -%-record('SeqOpt',{int, opt = asn1_NOVALUE}). -record('SeqOptFake',{int, opt = asn1_NOVALUE}). -%-record('OptSeq',{int=17}). -record('OptSeqFake',{bool = false}). - - - main(_Rules) -> - - ?line {ok,Bytes} = - asn1_wrapper:encode('Seq2738','SeqOptFake', - #'SeqOptFake'{int = 10, - opt = #'OptSeqFake'{}}), - ?line {ok,#'SeqOptFake'{int=10,opt=#'OptSeqFake'{bool=false}}} = - asn1_wrapper:decode('Seq2738','SeqOptFake',lists:flatten(Bytes)), - ?line {error,_} = - asn1_wrapper:decode('Seq2738','SeqOpt',lists:flatten(Bytes)), + Enc = asn1_test_lib:roundtrip_enc('Seq2738', + 'SeqOptFake', + #'SeqOptFake'{int=10,opt=#'OptSeqFake'{}}), + {error,_} = 'Seq2738':decode('SeqOpt', Enc), ok. diff --git a/lib/asn1/test/testSeqDefault.erl b/lib/asn1/test/testSeqDefault.erl index a772b749bd..22c1b7ee3a 100644 --- a/lib/asn1/test/testSeqDefault.erl +++ b/lib/asn1/test/testSeqDefault.erl @@ -33,148 +33,64 @@ -record('SeqDef3',{bool3 = asn1_DEFAULT, seq3 = asn1_DEFAULT, int3 = asn1_DEFAULT}). -record('SeqDef3Imp',{bool3 = asn1_DEFAULT, seq3 = asn1_DEFAULT, int3 = asn1_DEFAULT}). -record('SeqDef3Exp',{bool3 = asn1_DEFAULT, seq3 = asn1_DEFAULT, int3 = asn1_DEFAULT}). --record('SeqIn',{boolIn, intIn}). +-record('SeqIn',{boolIn = asn1_NOVALUE, intIn = 12}). main(_Rules) -> - - ?line {ok,Bytes11} = - asn1_wrapper:encode('SeqDefault','SeqDef1',#'SeqDef1'{bool1 = true, - int1 = 15, - seq1 = #'SeqIn'{boolIn = true, - intIn = 66}}), - ?line {ok,{'SeqDef1',true,15,{'SeqIn',true,66}}} = - asn1_wrapper:decode('SeqDefault','SeqDef1',lists:flatten(Bytes11)), - - - ?line {ok,Bytes12} = asn1_wrapper:encode('SeqDefault','SeqDef1',#'SeqDef1'{int1 = 15}), - ?line {ok,{'SeqDef1',true,15,{'SeqIn',asn1_NOVALUE,12}}} = - asn1_wrapper:decode('SeqDefault','SeqDef1',lists:flatten(Bytes12)), - - - ?line {ok,Bytes21} = - asn1_wrapper:encode('SeqDefault','SeqDef2',#'SeqDef2'{bool2 = true, - int2 = 15, - seq2 = #'SeqIn'{boolIn = true, - intIn = 66}}), - ?line {ok,{'SeqDef2',{'SeqIn',true,66},true,15}} = - asn1_wrapper:decode('SeqDefault','SeqDef2',lists:flatten(Bytes21)), - - - ?line {ok,Bytes22} = asn1_wrapper:encode('SeqDefault','SeqDef2',#'SeqDef2'{int2 = 15}), - ?line {ok,{'SeqDef2',{'SeqIn',asn1_NOVALUE,12},true,15}} = - asn1_wrapper:decode('SeqDefault','SeqDef2',lists:flatten(Bytes22)), - - - - ?line {ok,Bytes31} = - asn1_wrapper:encode('SeqDefault','SeqDef3',#'SeqDef3'{bool3 = true, - int3 = 15, - seq3 = #'SeqIn'{boolIn = true, - intIn = 66}}), - ?line {ok,{'SeqDef3',true,{'SeqIn',true,66},15}} = - asn1_wrapper:decode('SeqDefault','SeqDef3',lists:flatten(Bytes31)), - - - ?line {ok,Bytes32} = asn1_wrapper:encode('SeqDefault','SeqDef3',#'SeqDef3'{int3 = 15}), - ?line {ok,{'SeqDef3',true,{'SeqIn',asn1_NOVALUE,12},15}} = - asn1_wrapper:decode('SeqDefault','SeqDef3',lists:flatten(Bytes32)), - - - - - - ?line {ok,Bytes41} = - asn1_wrapper:encode('SeqDefault','SeqDef1Imp',#'SeqDef1Imp'{bool1 = true, - int1 = 15, - seq1 = #'SeqIn'{boolIn = true, - intIn = 66}}), - ?line {ok,{'SeqDef1Imp',true,15,{'SeqIn',true,66}}} = - asn1_wrapper:decode('SeqDefault','SeqDef1Imp',lists:flatten(Bytes41)), - - - ?line {ok,Bytes42} = asn1_wrapper:encode('SeqDefault','SeqDef1Imp',#'SeqDef1Imp'{int1 = 15}), - ?line {ok,{'SeqDef1Imp',true,15,{'SeqIn',asn1_NOVALUE,12}}} = - asn1_wrapper:decode('SeqDefault','SeqDef1Imp',lists:flatten(Bytes42)), - - - ?line {ok,Bytes51} = - asn1_wrapper:encode('SeqDefault','SeqDef2Imp',#'SeqDef2Imp'{bool2 = true, - int2 = 15, - seq2 = #'SeqIn'{boolIn = true, - intIn = 66}}), - ?line {ok,{'SeqDef2Imp',{'SeqIn',true,66},true,15}} = - asn1_wrapper:decode('SeqDefault','SeqDef2Imp',lists:flatten(Bytes51)), - - - ?line {ok,Bytes52} = asn1_wrapper:encode('SeqDefault','SeqDef2Imp',#'SeqDef2Imp'{int2 = 15}), - ?line {ok,{'SeqDef2Imp',{'SeqIn',asn1_NOVALUE,12},true,15}} = - asn1_wrapper:decode('SeqDefault','SeqDef2Imp',lists:flatten(Bytes52)), - - - - ?line {ok,Bytes61} = - asn1_wrapper:encode('SeqDefault','SeqDef3Imp',#'SeqDef3Imp'{bool3 = true, - int3 = 15, - seq3 = #'SeqIn'{boolIn = true, - intIn = 66}}), - ?line {ok,{'SeqDef3Imp',true,{'SeqIn',true,66},15}} = - asn1_wrapper:decode('SeqDefault','SeqDef3Imp',lists:flatten(Bytes61)), - - - ?line {ok,Bytes62} = asn1_wrapper:encode('SeqDefault','SeqDef3Imp',#'SeqDef3Imp'{int3 = 15}), - ?line {ok,{'SeqDef3Imp',true,{'SeqIn',asn1_NOVALUE,12},15}} = - asn1_wrapper:decode('SeqDefault','SeqDef3Imp',lists:flatten(Bytes62)), - - - - - - - ?line {ok,Bytes71} = - asn1_wrapper:encode('SeqDefault','SeqDef1Exp',#'SeqDef1Exp'{bool1 = true, - int1 = 15, - seq1 = #'SeqIn'{boolIn = true, - intIn = 66}}), - ?line {ok,{'SeqDef1Exp',true,15,{'SeqIn',true,66}}} = - asn1_wrapper:decode('SeqDefault','SeqDef1Exp',lists:flatten(Bytes71)), - - - ?line {ok,Bytes72} = asn1_wrapper:encode('SeqDefault','SeqDef1Exp',#'SeqDef1Exp'{int1 = 15}), - ?line {ok,{'SeqDef1Exp',true,15,{'SeqIn',asn1_NOVALUE,12}}} = - asn1_wrapper:decode('SeqDefault','SeqDef1Exp',lists:flatten(Bytes72)), - - - ?line {ok,Bytes81} = - asn1_wrapper:encode('SeqDefault','SeqDef2Exp',#'SeqDef2Exp'{bool2 = true, - int2 = 15, - seq2 = #'SeqIn'{boolIn = true, - intIn = 66}}), - ?line {ok,{'SeqDef2Exp',{'SeqIn',true,66},true,15}} = - asn1_wrapper:decode('SeqDefault','SeqDef2Exp',lists:flatten(Bytes81)), - - - ?line {ok,Bytes82} = asn1_wrapper:encode('SeqDefault','SeqDef2Exp',#'SeqDef2Exp'{int2 = 15, - bool2 = true}), - ?line {ok,{'SeqDef2Exp',{'SeqIn',asn1_NOVALUE,12},true,15}} = - asn1_wrapper:decode('SeqDefault','SeqDef2Exp',lists:flatten(Bytes82)), - - - - ?line {ok,Bytes91} = - asn1_wrapper:encode('SeqDefault','SeqDef3Exp',#'SeqDef3Exp'{bool3 = true, - int3 = 15, - seq3 = #'SeqIn'{boolIn = true, - intIn = 66}}), - ?line {ok,{'SeqDef3Exp',true,{'SeqIn',true,66},15}} = - asn1_wrapper:decode('SeqDefault','SeqDef3Exp',lists:flatten(Bytes91)), - - - ?line {ok,Bytes92} = asn1_wrapper:encode('SeqDefault','SeqDef3Exp',#'SeqDef3Exp'{int3 = 15}), - ?line {ok,{'SeqDef3Exp',true,{'SeqIn',asn1_NOVALUE,12},15}} = - asn1_wrapper:decode('SeqDefault','SeqDef3Exp',lists:flatten(Bytes92)), - - - - + roundtrip('SeqDef1', #'SeqDef1'{bool1=true,int1=15,seq1=#'SeqIn'{boolIn=true,intIn=66}}), + roundtrip('SeqDef1', + #'SeqDef1'{bool1=asn1_DEFAULT,int1=15,seq1=asn1_DEFAULT}, + #'SeqDef1'{bool1=true,int1=15,seq1=#'SeqIn'{}}), + + roundtrip('SeqDef2', #'SeqDef2'{seq2=#'SeqIn'{boolIn=true,intIn=66},bool2=true,int2=15}), + roundtrip('SeqDef2', + #'SeqDef2'{seq2=asn1_DEFAULT,bool2=asn1_DEFAULT,int2=15}, + #'SeqDef2'{seq2=#'SeqIn'{},bool2=true,int2=15}), + + roundtrip('SeqDef3', #'SeqDef3'{bool3=true,seq3=#'SeqIn'{boolIn=true,intIn=66},int3=15}), + roundtrip('SeqDef3', + #'SeqDef3'{bool3=asn1_DEFAULT,seq3=asn1_DEFAULT,int3=15}, + #'SeqDef3'{bool3=true,seq3=#'SeqIn'{},int3=15}), + + roundtrip('SeqDef1Imp', #'SeqDef1Imp'{bool1=true,int1=15, + seq1=#'SeqIn'{boolIn=true,intIn=66}}), + roundtrip('SeqDef1Imp', + #'SeqDef1Imp'{bool1=asn1_DEFAULT,int1=15,seq1=asn1_DEFAULT}, + #'SeqDef1Imp'{bool1=true,int1=15,seq1=#'SeqIn'{}}), + + roundtrip('SeqDef2Imp', #'SeqDef2Imp'{seq2=#'SeqIn'{boolIn=true,intIn=66}, + bool2=true,int2=15}), + roundtrip('SeqDef2Imp', + #'SeqDef2Imp'{seq2=asn1_DEFAULT,bool2=asn1_DEFAULT,int2=15}, + #'SeqDef2Imp'{seq2=#'SeqIn'{},bool2=true,int2=15}), + + roundtrip('SeqDef3Imp', + #'SeqDef3Imp'{bool3=true,seq3=#'SeqIn'{boolIn=true,intIn=66},int3=15}), + roundtrip('SeqDef3Imp', + #'SeqDef3Imp'{bool3=asn1_DEFAULT,seq3=asn1_DEFAULT,int3=15}, + #'SeqDef3Imp'{bool3=true,seq3=#'SeqIn'{},int3=15}), + + roundtrip('SeqDef1Exp', + #'SeqDef1Exp'{bool1=true,int1=15,seq1=#'SeqIn'{boolIn=true,intIn=66}}), + roundtrip('SeqDef1Exp', + #'SeqDef1Exp'{bool1=asn1_DEFAULT,int1=15,seq1=asn1_DEFAULT}, + #'SeqDef1Exp'{bool1=true,int1=15,seq1=#'SeqIn'{}}), + + roundtrip('SeqDef2Exp', #'SeqDef2Exp'{seq2=#'SeqIn'{boolIn=true,intIn=66}, + bool2=true,int2=15}), + roundtrip('SeqDef2Exp', + #'SeqDef2Exp'{seq2=asn1_DEFAULT,bool2=true,int2=15}, + #'SeqDef2Exp'{seq2=#'SeqIn'{},bool2=true,int2=15}), + + roundtrip('SeqDef3Exp', + #'SeqDef3Exp'{bool3=true,seq3=#'SeqIn'{boolIn=true,intIn=66},int3=15}), + roundtrip('SeqDef3Exp', + #'SeqDef3Exp'{bool3=asn1_DEFAULT,seq3=asn1_DEFAULT,int3=15}, + #'SeqDef3Exp'{bool3=true,seq3=#'SeqIn'{},int3=15}), ok. + +roundtrip(Type, Value) -> + roundtrip(Type, Value, Value). + +roundtrip(Type, Value, ExpectedValue) -> + asn1_test_lib:roundtrip('SeqDefault', Type, Value, ExpectedValue). diff --git a/lib/asn1/test/testSeqExtension.erl b/lib/asn1/test/testSeqExtension.erl index b996634996..8473459c36 100644 --- a/lib/asn1/test/testSeqExtension.erl +++ b/lib/asn1/test/testSeqExtension.erl @@ -108,18 +108,14 @@ main(Erule, DataDir, Opts) -> ok. roundtrip(Type, Value) -> - {ok,Encoded} = 'SeqExtension':encode(Type, Value), - {ok,Value} = 'SeqExtension':decode(Type, Encoded), - ok. + asn1_test_lib:roundtrip('SeqExtension', Type, Value). v_roundtrip2(Erule, Type, Value) -> Encoded = asn1_test_lib:hex_to_bin(v(Erule, Type)), Encoded = roundtrip2(Type, Value). roundtrip2(Type, Value) -> - {ok,Encoded} = 'SeqExtension2':encode(Type, Value), - {ok,Value} = 'SeqExtension2':decode(Type, Encoded), - Encoded. + asn1_test_lib:roundtrip_enc('SeqExtension2', Type, Value). v(ber, 'SeqExt66') -> "30049F41 017D"; v(per, 'SeqExt66') -> "C0420000 00000000 00004001 FA"; diff --git a/lib/asn1/test/testSeqExternal.erl b/lib/asn1/test/testSeqExternal.erl index b89b98d3fa..a8e0902244 100644 --- a/lib/asn1/test/testSeqExternal.erl +++ b/lib/asn1/test/testSeqExternal.erl @@ -20,121 +20,38 @@ -module(testSeqExternal). -include("External.hrl"). --export([compile/3]). -export([main/1]). -include_lib("test_server/include/test_server.hrl"). - -record('SeqXSet1',{set, bool, int}). -record('SeqXSet2',{bool, set, int}). -record('SeqXSet3',{bool, int, set}). -%-record('NT',{os, bool}). -%-record('Imp',{os, bool}). -%-record('Exp',{os, bool}). - - -compile(Config,Rules,Options) -> - - ?line DataDir = ?config(data_dir,Config), - ?line OutDir = ?config(priv_dir,Config), - ?line true = code:add_patha(?config(priv_dir,Config)), - ?line ok = asn1ct:compile(DataDir ++ "SeqExternal", - [Rules,{outdir,OutDir}]++Options). - - main(_Rules) -> - - ?line {ok,Bytes11} = - asn1_wrapper:encode('SeqExternal','XNTNT',#'XSeqNT'{bool = true, os = "kalle"}), - ?line {ok,{'XSeqNT',[107,97,108,108,101],true}} = - asn1_wrapper:decode('SeqExternal','XNTNT',lists:flatten(Bytes11)), - - ?line {ok,Bytes12} = - asn1_wrapper:encode('SeqExternal','XImpNT',#'XSeqNT'{bool = true, os = "kalle"}), - ?line {ok,{'XSeqNT',[107,97,108,108,101],true}} = - asn1_wrapper:decode('SeqExternal','XImpNT',lists:flatten(Bytes12)), - - ?line {ok,Bytes13} = - asn1_wrapper:encode('SeqExternal','XExpNT',#'XSeqNT'{bool = true, os = "kalle"}), - ?line {ok,{'XSeqNT',[107,97,108,108,101],true}} = - asn1_wrapper:decode('SeqExternal','XExpNT',lists:flatten(Bytes13)), - - - - ?line {ok,Bytes21} = - asn1_wrapper:encode('SeqExternal','XNTImp',#'XSeqImp'{bool = true, os = "kalle"}), - ?line {ok,{'XSeqImp',[107,97,108,108,101],true}} = - asn1_wrapper:decode('SeqExternal','XNTImp',lists:flatten(Bytes21)), - - ?line {ok,Bytes22} = - asn1_wrapper:encode('SeqExternal','XImpImp',#'XSeqImp'{bool = true, os = "kalle"}), - ?line {ok,{'XSeqImp',[107,97,108,108,101],true}} = - asn1_wrapper:decode('SeqExternal','XImpImp',lists:flatten(Bytes22)), - - ?line {ok,Bytes23} = - asn1_wrapper:encode('SeqExternal','XExpImp',#'XSeqImp'{bool = true, os = "kalle"}), - ?line {ok,{'XSeqImp',[107,97,108,108,101],true}} = - asn1_wrapper:decode('SeqExternal','XExpImp',lists:flatten(Bytes23)), - - - - ?line {ok,Bytes31} = - asn1_wrapper:encode('SeqExternal','XNTExp',#'XSeqExp'{bool = true, os = "kalle"}), - ?line {ok,{'XSeqExp',[107,97,108,108,101],true}} = - asn1_wrapper:decode('SeqExternal','XNTExp',lists:flatten(Bytes31)), - - ?line {ok,Bytes32} = - asn1_wrapper:encode('SeqExternal','XImpExp',#'XSeqExp'{bool = true, os = "kalle"}), - ?line {ok,{'XSeqExp',[107,97,108,108,101],true}} = - asn1_wrapper:decode('SeqExternal','XImpExp',lists:flatten(Bytes32)), - - ?line {ok,Bytes33} = - asn1_wrapper:encode('SeqExternal','XExpExp',#'XSeqExp'{bool = true, os = "kalle"}), - ?line {ok,{'XSeqExp',[107,97,108,108,101],true}} = - asn1_wrapper:decode('SeqExternal','XExpExp',lists:flatten(Bytes33)), - - - - ?line {ok,Bytes41} = - asn1_wrapper:encode('SeqExternal','SeqXSet1', - #'SeqXSet1'{bool = true, - int = 66, - set = #'XSet1'{bool1 = true, - int1 = 77, - set1 = #'XSetIn'{boolIn = false, - intIn = 88}}}), - ?line {ok,{'SeqXSet1',{'XSet1',true,77,{'XSetIn',false,88}},true,66}} = - asn1_wrapper:decode('SeqExternal','SeqXSet1',lists:flatten(Bytes41)), - - - - ?line {ok,Bytes42} = - asn1_wrapper:encode('SeqExternal','SeqXSet2', - #'SeqXSet2'{bool = true, - int = 66, - set = #'XSet1'{bool1 = true, - int1 = 77, - set1 = #'XSetIn'{boolIn = false, - intIn = 88}}}), - ?line {ok,{'SeqXSet2',true,{'XSet1',true,77,{'XSetIn',false,88}},66}} = - asn1_wrapper:decode('SeqExternal','SeqXSet2',lists:flatten(Bytes42)), - - ?line {ok,Bytes43} = - asn1_wrapper:encode('SeqExternal','SeqXSet3', - #'SeqXSet3'{bool = true, - int = 66, - set = #'XSet1'{bool1 = true, - int1 = 77, - set1 = #'XSetIn'{boolIn = false, - intIn = 88}}}), - ?line {ok,{'SeqXSet3',true,66,{'XSet1',true,77,{'XSetIn',false,88}}}} = - asn1_wrapper:decode('SeqExternal','SeqXSet3',lists:flatten(Bytes43)), - - - - + roundtrip('XNTNT', #'XSeqNT'{os="kalle",bool=true}), + roundtrip('XImpNT', #'XSeqNT'{os="kalle",bool=true}), + roundtrip('XExpNT', #'XSeqNT'{os="kalle",bool=true}), + roundtrip('XNTImp', #'XSeqImp'{os="kalle",bool=true}), + roundtrip('XImpImp', #'XSeqImp'{os="kalle",bool=true}), + roundtrip('XExpImp', #'XSeqImp'{os="kalle",bool=true}), + roundtrip('XNTExp', #'XSeqExp'{os="kalle",bool=true}), + roundtrip('XImpExp', #'XSeqExp'{os="kalle",bool=true}), + roundtrip('XExpExp', #'XSeqExp'{os="kalle",bool=true}), + roundtrip('SeqXSet1', + #'SeqXSet1'{set=#'XSet1'{bool1=true,int1=77, + set1=#'XSetIn'{boolIn=false,intIn=88}}, + bool=true,int=66}), + roundtrip('SeqXSet2', + #'SeqXSet2'{bool=true, + set=#'XSet1'{bool1=true,int1=77, + set1=#'XSetIn'{boolIn=false,intIn=88}}, + int=66}), + roundtrip('SeqXSet3', + #'SeqXSet3'{bool=true,int=66, + set=#'XSet1'{bool1=true,int1=77, + set1=#'XSetIn'{boolIn=false,intIn=88}}}), ok. - +roundtrip(T, V) -> + asn1_test_lib:roundtrip('SeqExternal', T, V). diff --git a/lib/asn1/test/testSeqIndefinite.erl b/lib/asn1/test/testSeqIndefinite.erl deleted file mode 100644 index c7b8aba523..0000000000 --- a/lib/asn1/test/testSeqIndefinite.erl +++ /dev/null @@ -1,48 +0,0 @@ -%% -%% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1999-2012. All Rights Reserved. -%% -%% The contents of this file are subject to the Erlang Public License, -%% Version 1.1, (the "License"); you may not use this file except in -%% compliance with the License. You should have received a copy of the -%% Erlang Public License along with this software. If not, it can be -%% retrieved online at http://www.erlang.org/. -%% -%% Software distributed under the License is distributed on an "AS IS" -%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See -%% the License for the specific language governing rights and limitations -%% under the License. -%% -%% %CopyrightEnd% -%% -%% --module(testSeqIndefinite). - --export([main/1]). - --include_lib("test_server/include/test_server.hrl"). - -main(per) -> ok; -main(ber) -> - - %% normal encoding - B = [48,20,1,1,255,48,9,1,1,255,2,4,251,35,238,194,2,4,251,55,236,161], - %% indefinite length encoding - Bi = [48,22,1,1,255,48,128,1,1,255,2,4,251,35,238,194,0,0,2,4,251,55,236,161], - %% the value which is encoded - V = {'SeqS3',true,{'SeqS3_seqS3',true,-81531198},-80221023}, - ?line {ok,V} = asn1_wrapper:decode('SeqSetIndefinite','SeqS3',B), - ?line {ok,V} = asn1_wrapper:decode('SeqSetIndefinite','SeqS3',Bi), - - %% normal encoding but with unknown extension component - _Be = [48,23,1,1,255,48,12,1,1,255,2,4,251,35,238,194,1,1,255,2,4,251,55,236,161], - %% indefinite length encoding but with unknown extension component - _Bei = [48,25,1,1,255,48,128,1,1,255,2,4,251,35,238,194,1,1,255,0,0,2,4,251,55,236,161], - - ?line {ok,V} = asn1_wrapper:decode('SeqSetIndefinite','SeqS3',B), - ?line {ok,V} = asn1_wrapper:decode('SeqSetIndefinite','SeqS3',Bi), - ok. - - - diff --git a/lib/asn1/test/testSeqOf.erl b/lib/asn1/test/testSeqOf.erl index db537b1478..7f8f4079b4 100644 --- a/lib/asn1/test/testSeqOf.erl +++ b/lib/asn1/test/testSeqOf.erl @@ -83,6 +83,32 @@ main(_Rules) -> roundtrip('Seq4', #'Seq4'{seq43=SeqIn3}, #'Seq4'{seq41=[],seq42=[], seq43=SeqIn3}), + + roundtrip('Seq5', {'Seq5',true,[],77}), + roundtrip('Seq5', {'Seq5',true,[""],77}), + roundtrip('Seq5', {'Seq5',true,["a"],77}), + roundtrip('Seq5', {'Seq5',true,["ab"],77}), + roundtrip('Seq5', {'Seq5',true,["abc"],77}), + + roundtrip('Seq6', {'Seq6',[],[],101}), + roundtrip('Seq6', {'Seq6',[],[7],101}), + roundtrip('Seq6', {'Seq6',[],[1,7],101}), + roundtrip('Seq6', {'Seq6',[1],[],101}), + roundtrip('Seq6', {'Seq6',[2],[7],101}), + roundtrip('Seq6', {'Seq6',[3],[1,7],101}), + + roundtrip('Seq8', {'Seq8',[],37}), + + roundtrip('Seq9', {'Seq9',true,[],97}), + roundtrip('Seq9', {'Seq9',true,[""],97}), + roundtrip('Seq9', {'Seq9',true,["x"],97}), + roundtrip('Seq9', {'Seq9',true,["xy"],97}), + roundtrip('Seq9', {'Seq9',true,["xyz"],97}), + + roundtrip('Seq10', {'Seq10',true,[""],97}), + roundtrip('Seq10', {'Seq10',true,["a"],97}), + roundtrip('Seq10', {'Seq10',true,["a","b"],97}), + roundtrip('Seq10', {'Seq10',true,["a","b","c"],97}), roundtrip('SeqEmp', #'SeqEmp'{seq1=[#'Empty'{}]}), @@ -123,15 +149,9 @@ roundtrip(T, V) -> roundtrip(T, V, V). roundtrip(Type, Val, Expected) -> - M = 'SeqOf', - {ok,Enc} = M:encode(Type, Val), - {ok,Expected} = M:decode(Type, Enc), - ok. + asn1_test_lib:roundtrip('SeqOf', Type, Val, Expected). xroundtrip(T1, T2, Val) -> - M = 'XSeqOf', - {ok,Enc} = M:encode(T1, Val), - {ok,Enc} = M:encode(T2, Val), - {ok,Val} = M:decode(T1, Enc), - {ok,Val} = M:decode(T2, Enc), + Enc = asn1_test_lib:roundtrip_enc('XSeqOf', T1, Val), + Enc = asn1_test_lib:roundtrip_enc('XSeqOf', T2, Val), ok. diff --git a/lib/asn1/test/testSeqOfCho.erl b/lib/asn1/test/testSeqOfCho.erl index 5b83c8bf21..f749845bb9 100644 --- a/lib/asn1/test/testSeqOfCho.erl +++ b/lib/asn1/test/testSeqOfCho.erl @@ -31,117 +31,45 @@ -record('SeqOfChoEmbOpt_SEQOF',{bool1, int1, seq1 = asn1_NOVALUE}). main(_Rules) -> - - ?line {ok,Bytes11} = - asn1_wrapper:encode('SeqOfCho','SeqChoDef',#'SeqChoDef'{bool1 = true, - int1 = 17}), - ?line {ok,{'SeqChoDef',true,17,[]}} = - asn1_wrapper:decode('SeqOfCho','SeqChoDef',lists:flatten(Bytes11)), - - - ?line {ok,Bytes12} = - asn1_wrapper:encode('SeqOfCho','SeqChoDef',#'SeqChoDef'{bool1 = true, - int1 = 17, - seq1 = [{boolIn,true}, - {intIn,25}]}), - ?line {ok,{'SeqChoDef',true,17,[{boolIn,true},{intIn,25}]}} = - asn1_wrapper:decode('SeqOfCho','SeqChoDef',lists:flatten(Bytes12)), - - - - ?line {ok,Bytes15} = - asn1_wrapper:encode('SeqOfCho','SeqChoOpt',#'SeqChoOpt'{bool1 = true, - int1 = 17}), - ?line {ok,{'SeqChoOpt',true,17,asn1_NOVALUE}} = - asn1_wrapper:decode('SeqOfCho','SeqChoOpt',lists:flatten(Bytes15)), - - - ?line {ok,Bytes16} = - asn1_wrapper:encode('SeqOfCho','SeqChoOpt',#'SeqChoOpt'{bool1 = true, - int1 = 17, - seq1 = [{boolIn,true}, - {intIn,25}]}), - ?line {ok,{'SeqChoOpt',true,17,[{boolIn,true},{intIn,25}]}} = - asn1_wrapper:decode('SeqOfCho','SeqChoOpt',lists:flatten(Bytes16)), - - - - - - ?line {ok,Bytes21} = - asn1_wrapper:encode('SeqOfCho','SeqChoEmbDef',#'SeqChoEmbDef'{bool1 = true, - int1 = 17}), - ?line {ok,{'SeqChoEmbDef',true,17,[]}} = - asn1_wrapper:decode('SeqOfCho','SeqChoEmbDef',lists:flatten(Bytes21)), - - - ?line {ok,Bytes22} = - asn1_wrapper:encode('SeqOfCho','SeqChoEmbDef',#'SeqChoEmbDef'{bool1 = true, - int1 = 17, - seq1 = [{boolIn,true}, - {intIn,25}]}), - ?line {ok,{'SeqChoEmbDef',true,17,[{boolIn,true},{intIn,25}]}} = - asn1_wrapper:decode('SeqOfCho','SeqChoEmbDef',lists:flatten(Bytes22)), - - - - ?line {ok,Bytes25} = - asn1_wrapper:encode('SeqOfCho','SeqChoEmbOpt',#'SeqChoEmbOpt'{bool1 = true, - int1 = 17}), - ?line {ok,{'SeqChoEmbOpt',true,17,asn1_NOVALUE}} = - asn1_wrapper:decode('SeqOfCho','SeqChoEmbOpt',lists:flatten(Bytes25)), - - - ?line {ok,Bytes26} = - asn1_wrapper:encode('SeqOfCho','SeqChoEmbOpt',#'SeqChoEmbOpt'{bool1 = true, - int1 = 17, - seq1 = [{boolIn,true}, - {intIn,25}]}), - ?line {ok,{'SeqChoEmbOpt',true,17,[{boolIn,true},{intIn,25}]}} = - asn1_wrapper:decode('SeqOfCho','SeqChoEmbOpt',lists:flatten(Bytes26)), - - - - - - - ?line {ok,Bytes31} = - asn1_wrapper:encode('SeqOfCho','SeqOfChoEmbDef',[#'SeqOfChoEmbDef_SEQOF'{bool1 = true, - int1 = 17}]), - ?line {ok,[{'SeqOfChoEmbDef_SEQOF',true,17,[]}]} = - asn1_wrapper:decode('SeqOfCho','SeqOfChoEmbDef',lists:flatten(Bytes31)), - - - ?line {ok,Bytes32} = - asn1_wrapper:encode('SeqOfCho','SeqOfChoEmbDef', - [#'SeqOfChoEmbDef_SEQOF'{bool1 = true, - int1 = 17, - seq1 = [{boolIn,true}, - {intIn,25}]}]), - ?line {ok,[{'SeqOfChoEmbDef_SEQOF',true,17,[{boolIn,true},{intIn,25}]}]} = - asn1_wrapper:decode('SeqOfCho','SeqOfChoEmbDef',lists:flatten(Bytes32)), - - - - ?line {ok,Bytes35} = - asn1_wrapper:encode('SeqOfCho','SeqOfChoEmbOpt',[#'SeqOfChoEmbOpt_SEQOF'{bool1 = true, - int1 = 17}]), - ?line {ok,[{'SeqOfChoEmbOpt_SEQOF',true,17,asn1_NOVALUE}]} = - asn1_wrapper:decode('SeqOfCho','SeqOfChoEmbOpt',lists:flatten(Bytes35)), - - - ?line {ok,Bytes36} = - asn1_wrapper:encode('SeqOfCho','SeqOfChoEmbOpt', - [#'SeqOfChoEmbOpt_SEQOF'{bool1 = true, - int1 = 17, - seq1 = [{boolIn,true}, - {intIn,25}]}]), - ?line {ok,[{'SeqOfChoEmbOpt_SEQOF',true,17,[{boolIn,true},{intIn,25}]}]} = - asn1_wrapper:decode('SeqOfCho','SeqOfChoEmbOpt',lists:flatten(Bytes36)), - - - - + roundtrip('SeqChoDef', + #'SeqChoDef'{bool1=true,int1=17,seq1=asn1_DEFAULT}, + #'SeqChoDef'{bool1=true,int1=17,seq1=[]}), + roundtrip('SeqChoDef', + #'SeqChoDef'{bool1=true,int1=17, + seq1=[{boolIn,true},{intIn,25}]}), + roundtrip('SeqChoOpt', + #'SeqChoOpt'{bool1=true,int1=17,seq1=asn1_NOVALUE}), + roundtrip('SeqChoOpt', + #'SeqChoOpt'{bool1=true,int1=17, + seq1=[{boolIn,true},{intIn,25}]}), + + roundtrip('SeqChoEmbDef', + #'SeqChoEmbDef'{bool1=true,int1=17,seq1=asn1_DEFAULT}, + #'SeqChoEmbDef'{bool1=true,int1=17,seq1=[]}), + roundtrip('SeqChoEmbDef', + #'SeqChoEmbDef'{bool1=true,int1=17, + seq1=[{boolIn,true},{intIn,25}]}), + roundtrip('SeqChoEmbOpt', + #'SeqChoEmbOpt'{bool1=true,int1=17,seq1=asn1_NOVALUE}), + roundtrip('SeqChoEmbOpt', + #'SeqChoEmbOpt'{bool1=true,int1=17, + seq1=[{boolIn,true},{intIn,25}]}), + + roundtrip('SeqOfChoEmbDef', + [#'SeqOfChoEmbDef_SEQOF'{bool1=true,int1=17,seq1=asn1_DEFAULT}], + [#'SeqOfChoEmbDef_SEQOF'{bool1=true,int1=17,seq1=[]}]), + roundtrip('SeqOfChoEmbDef', + [#'SeqOfChoEmbDef_SEQOF'{bool1=true,int1=17, + seq1=[{boolIn,true},{intIn,25}]}]), + roundtrip('SeqOfChoEmbOpt', + [#'SeqOfChoEmbOpt_SEQOF'{bool1=true,int1=17,seq1=asn1_NOVALUE}]), + roundtrip('SeqOfChoEmbOpt', + [#'SeqOfChoEmbOpt_SEQOF'{bool1=true,int1=17, + seq1=[{boolIn,true},{intIn,25}]}]), ok. +roundtrip(Type, Value) -> + roundtrip(Type, Value, Value). +roundtrip(Type, Value, ExpectedValue) -> + asn1_test_lib:roundtrip('SeqOfCho', Type, Value, ExpectedValue). diff --git a/lib/asn1/test/testSeqOfExternal.erl b/lib/asn1/test/testSeqOfExternal.erl index 4c4c9e2b0f..2e60f441c1 100644 --- a/lib/asn1/test/testSeqOfExternal.erl +++ b/lib/asn1/test/testSeqOfExternal.erl @@ -18,9 +18,6 @@ %% %% -module(testSeqOfExternal). - - --export([compile/3]). -export([main/1]). -include_lib("test_server/include/test_server.hrl"). @@ -30,142 +27,53 @@ -record('Imp',{os, bool}). -record('Exp',{os, bool}). - - -compile(Config,Rules,Options) -> - - ?line DataDir = ?config(data_dir,Config), - ?line OutDir = ?config(priv_dir,Config), - ?line true = code:add_patha(?config(priv_dir,Config)), - ?line ok = asn1ct:compile(DataDir ++ "SeqOfExternal",[Rules,{outdir,OutDir}]++Options). - - - main(_Rules) -> - - ?line {ok,Bytes11} = - asn1_wrapper:encode('SeqOfExternal','NTNT',[#'NT'{bool = true, os = "kalle"}, - #'NT'{bool = true, os = "kalle"}]), - ?line {ok,[{'NT',[107,97,108,108,101],true},{'NT',[107,97,108,108,101],true}]} = - asn1_wrapper:decode('SeqOfExternal','NTNT',lists:flatten(Bytes11)), - - ?line {ok,Bytes12} = - asn1_wrapper:encode('SeqOfExternal','ImpNT',[#'NT'{bool = true, os = "kalle"}, - #'NT'{bool = true, os = "kalle"}]), - ?line {ok,[{'NT',[107,97,108,108,101],true},{'NT',[107,97,108,108,101],true}]} = - asn1_wrapper:decode('SeqOfExternal','ImpNT',lists:flatten(Bytes12)), - - ?line {ok,Bytes13} = - asn1_wrapper:encode('SeqOfExternal','ExpNT',[#'NT'{bool = true, os = "kalle"}, - #'NT'{bool = true, os = "kalle"}]), - ?line {ok,[{'NT',[107,97,108,108,101],true},{'NT',[107,97,108,108,101],true}]} = - asn1_wrapper:decode('SeqOfExternal','ExpNT',lists:flatten(Bytes13)), - - - - ?line {ok,Bytes21} = - asn1_wrapper:encode('SeqOfExternal','NTImp',[#'Imp'{bool = true, os = "kalle"}, - #'Imp'{bool = true, os = "kalle"}]), - ?line {ok,[{'Imp',[107,97,108,108,101],true},{'Imp',[107,97,108,108,101],true}]} = - asn1_wrapper:decode('SeqOfExternal','NTImp',lists:flatten(Bytes21)), - - ?line {ok,Bytes22} = - asn1_wrapper:encode('SeqOfExternal','ImpImp',[#'Imp'{bool = true, os = "kalle"}, - #'Imp'{bool = true, os = "kalle"}]), - ?line {ok,[{'Imp',[107,97,108,108,101],true},{'Imp',[107,97,108,108,101],true}]} = - asn1_wrapper:decode('SeqOfExternal','ImpImp',lists:flatten(Bytes22)), - - ?line {ok,Bytes23} = - asn1_wrapper:encode('SeqOfExternal','ExpImp',[#'Imp'{bool = true, os = "kalle"}, - #'Imp'{bool = true, os = "kalle"}]), - ?line {ok,[{'Imp',[107,97,108,108,101],true},{'Imp',[107,97,108,108,101],true}]} = - asn1_wrapper:decode('SeqOfExternal','ExpImp',lists:flatten(Bytes23)), - - - - ?line {ok,Bytes31} = - asn1_wrapper:encode('SeqOfExternal','NTExp',[#'Exp'{bool = true, os = "kalle"}, - #'Exp'{bool = true, os = "kalle"}]), - ?line {ok,[{'Exp',[107,97,108,108,101],true},{'Exp',[107,97,108,108,101],true}]} = - asn1_wrapper:decode('SeqOfExternal','NTExp',lists:flatten(Bytes31)), - - ?line {ok,Bytes32} = - asn1_wrapper:encode('SeqOfExternal','ImpExp',[#'Exp'{bool = true, os = "kalle"}, - #'Exp'{bool = true, os = "kalle"}]), - ?line {ok,[{'Exp',[107,97,108,108,101],true},{'Exp',[107,97,108,108,101],true}]} = - asn1_wrapper:decode('SeqOfExternal','ImpExp',lists:flatten(Bytes32)), - - ?line {ok,Bytes33} = - asn1_wrapper:encode('SeqOfExternal','ExpExp',[#'Exp'{bool = true, os = "kalle"}, - #'Exp'{bool = true, os = "kalle"}]), - ?line {ok,[{'Exp',[107,97,108,108,101],true},{'Exp',[107,97,108,108,101],true}]} = - asn1_wrapper:decode('SeqOfExternal','ExpExp',lists:flatten(Bytes33)), - - - - - - - - ?line {ok,Bytes41} = - asn1_wrapper:encode('SeqOfExternal','XNTNT',[#'XSeqNT'{bool = true, os = "kalle"}, - #'XSeqNT'{bool = true, os = "kalle"}]), - ?line {ok,[{'XSeqNT',[107,97,108,108,101],true},{'XSeqNT',[107,97,108,108,101],true}]} = - asn1_wrapper:decode('SeqOfExternal','XNTNT',lists:flatten(Bytes41)), - - ?line {ok,Bytes42} = - asn1_wrapper:encode('SeqOfExternal','XImpNT',[#'XSeqNT'{bool = true, os = "kalle"}, - #'XSeqNT'{bool = true, os = "kalle"}]), - ?line {ok,[{'XSeqNT',[107,97,108,108,101],true},{'XSeqNT',[107,97,108,108,101],true}]} = - asn1_wrapper:decode('SeqOfExternal','XImpNT',lists:flatten(Bytes42)), - - ?line {ok,Bytes43} = - asn1_wrapper:encode('SeqOfExternal','XExpNT',[#'XSeqNT'{bool = true, os = "kalle"}, - #'XSeqNT'{bool = true, os = "kalle"}]), - ?line {ok,[{'XSeqNT',[107,97,108,108,101],true},{'XSeqNT',[107,97,108,108,101],true}]} = - asn1_wrapper:decode('SeqOfExternal','XExpNT',lists:flatten(Bytes43)), - - - - ?line {ok,Bytes51} = - asn1_wrapper:encode('SeqOfExternal','XNTImp',[#'XSeqImp'{bool = true, os = "kalle"}, - #'XSeqImp'{bool = true, os = "kalle"}]), - ?line {ok,[{'XSeqImp',[107,97,108,108,101],true},{'XSeqImp',[107,97,108,108,101],true}]} = - asn1_wrapper:decode('SeqOfExternal','XNTImp',lists:flatten(Bytes51)), - - ?line {ok,Bytes52} = - asn1_wrapper:encode('SeqOfExternal','XImpImp',[#'XSeqImp'{bool = true, os = "kalle"}, - #'XSeqImp'{bool = true, os = "kalle"}]), - ?line {ok,[{'XSeqImp',[107,97,108,108,101],true},{'XSeqImp',[107,97,108,108,101],true}]} = - asn1_wrapper:decode('SeqOfExternal','XImpImp',lists:flatten(Bytes52)), - - ?line {ok,Bytes53} = - asn1_wrapper:encode('SeqOfExternal','XExpImp',[#'XSeqImp'{bool = true, os = "kalle"}, - #'XSeqImp'{bool = true, os = "kalle"}]), - ?line {ok,[{'XSeqImp',[107,97,108,108,101],true},{'XSeqImp',[107,97,108,108,101],true}]} = - asn1_wrapper:decode('SeqOfExternal','XExpImp',lists:flatten(Bytes53)), - - - - ?line {ok,Bytes61} = - asn1_wrapper:encode('SeqOfExternal','XNTExp',[#'XSeqExp'{bool = true, os = "kalle"}, - #'XSeqExp'{bool = true, os = "kalle"}]), - ?line {ok,[{'XSeqExp',[107,97,108,108,101],true},{'XSeqExp',[107,97,108,108,101],true}]} = - asn1_wrapper:decode('SeqOfExternal','XNTExp',lists:flatten(Bytes61)), - - ?line {ok,Bytes62} = - asn1_wrapper:encode('SeqOfExternal','XImpExp',[#'XSeqExp'{bool = true, os = "kalle"}, - #'XSeqExp'{bool = true, os = "kalle"}]), - ?line {ok,[{'XSeqExp',[107,97,108,108,101],true},{'XSeqExp',[107,97,108,108,101],true}]} = - asn1_wrapper:decode('SeqOfExternal','XImpExp',lists:flatten(Bytes62)), - - ?line {ok,Bytes63} = - asn1_wrapper:encode('SeqOfExternal','XExpExp',[#'XSeqExp'{bool = true, os = "kalle"}, - #'XSeqExp'{bool = true, os = "kalle"}]), - ?line {ok,[{'XSeqExp',[107,97,108,108,101],true},{'XSeqExp',[107,97,108,108,101],true}]} = - asn1_wrapper:decode('SeqOfExternal','XExpExp',lists:flatten(Bytes63)), - - - - + roundtrip('NTNT', + [#'NT'{os="kalle",bool=true},#'NT'{os="kalle",bool=true}]), + roundtrip('ImpNT', + [#'NT'{os="kalle",bool=true},#'NT'{os="kalle",bool=true}]), + roundtrip('ExpNT', + [#'NT'{os="kalle",bool=true},#'NT'{os="kalle",bool=true}]), + roundtrip('NTImp', + [#'Imp'{os="kalle",bool=true},#'Imp'{os="kalle",bool=true}]), + roundtrip('ImpImp', + [#'Imp'{os="kalle",bool=true},#'Imp'{os="kalle",bool=true}]), + roundtrip('ExpImp', + [#'Imp'{os="kalle",bool=true},#'Imp'{os="kalle",bool=true}]), + roundtrip('NTExp', + [#'Exp'{os="kalle",bool=true},#'Exp'{os="kalle",bool=true}]), + roundtrip('ImpExp', + [#'Exp'{os="kalle",bool=true},#'Exp'{os="kalle",bool=true}]), + roundtrip('ExpExp', + [#'Exp'{os="kalle",bool=true},#'Exp'{os="kalle",bool=true}]), + roundtrip('XNTNT', + [#'XSeqNT'{os="kalle",bool=true}, + #'XSeqNT'{os="kalle",bool=true}]), + roundtrip('XImpNT', + [#'XSeqNT'{os="kalle",bool=true}, + #'XSeqNT'{os="kalle",bool=true}]), + roundtrip('XExpNT', + [#'XSeqNT'{os="kalle",bool=true}, + #'XSeqNT'{os="kalle",bool=true}]), + roundtrip('XNTImp', + [#'XSeqImp'{os="kalle",bool=true}, + #'XSeqImp'{os="kalle",bool=true}]), + roundtrip('XImpImp', + [#'XSeqImp'{os="kalle",bool=true}, + #'XSeqImp'{os="kalle",bool=true}]), + roundtrip('XExpImp', + [#'XSeqImp'{os="kalle",bool=true}, + #'XSeqImp'{os="kalle",bool=true}]), + roundtrip('XNTExp', + [#'XSeqExp'{os="kalle",bool=true}, + #'XSeqExp'{os="kalle",bool=true}]), + roundtrip('XImpExp', + [#'XSeqExp'{os="kalle",bool=true}, + #'XSeqExp'{os="kalle",bool=true}]), + roundtrip('XExpExp', + [#'XSeqExp'{os="kalle",bool=true}, + #'XSeqExp'{os="kalle",bool=true}]), ok. + +roundtrip(T, V) -> + asn1_test_lib:roundtrip('SeqOfExternal', T, V). diff --git a/lib/asn1/test/testSeqOfIndefinite.erl b/lib/asn1/test/testSeqOfIndefinite.erl index 01ef36e0b4..b771405d84 100644 --- a/lib/asn1/test/testSeqOfIndefinite.erl +++ b/lib/asn1/test/testSeqOfIndefinite.erl @@ -33,60 +33,53 @@ main() -> ?line ok = test('InsertSubscriberDataArg'). % OTP-4232 test(isd)-> - EncPdu = [48,128,129,7,145,148,113,50,1,0,241,131,1,0,176,128,5,0,161,128,48,22,2,1,1,144,2,241,33,145,4,0,1,2,3,146,3,36,131,16,148,2,1,42,48,35,2,1,2,144,2,241,33,145,4,255,255,255,255,146,3,37,147,18,147,0,148,13,7,67,79,77,80,65,78,89,4,67,79,77,53,48,28,2,1,3,144,2,241,33,146,3,26,98,31,148,14,9,67,79,77,80,65,78,89,49,50,3,67,79,77,0,0,0,0,152,1,2,0,0], - - ?line {ok,_} = asn1_wrapper:decode('Mvrasn-11-4', - 'InsertSubscriberDataArg', - EncPdu), + EncPdu = <<48,128,129,7,145,148,113,50,1,0,241,131,1,0,176,128,5,0, + 161,128,48,22,2,1,1,144,2,241,33,145,4,0,1,2,3,146,3,36, + 131,16,148,2,1,42,48,35,2,1,2,144,2,241,33,145,4,255,255, + 255,255,146,3,37,147,18,147,0,148,13,7,67,79,77,80,65,78, + 89,4,67,79,77,53,48,28,2,1,3,144,2,241,33,146,3,26,98,31, + 148,14,9,67,79,77,80,65,78,89,49,50,3,67,79,77,0,0,0,0, + 152,1,2,0,0>>, + {ok,_} = 'Mvrasn-11-4':decode('InsertSubscriberDataArg', EncPdu), ok; % % Problems with indefinite length encoding !!! % test(isd2)-> - EncPdu = [48, 128, 128, 8, 98, 2, 50, 1, 0, 0, 0, 241, 176, 128, 161, 128, 48, 128, 2, 1, 1, 144, 2, 241, 33, 145, 4, 255, 23, 12, 1, 146, 3, 9, 17, 1, 147, 0, 148, 13, 7, 67, 79, 77, 80, 65, 78, 89, 4, 67, 79, 77, 53, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - - ?line {ok,_DecPdu} = asn1_wrapper:decode('Mvrasn-11-4', - 'InsertSubscriberDataArg', - EncPdu), - + EncPdu = <<48,128,128,8,98,2,50,1,0,0,0,241,176,128,161,128,48,128,2,1,1,144, + 2,241,33,145,4,255,23,12,1,146,3,9,17,1,147,0,148,13,7,67,79,77,80, + 65,78,89,4,67,79,77,53,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0>>, + {ok,_DecPdu} = 'Mvrasn-11-4':decode('InsertSubscriberDataArg', EncPdu), ok; % % Is doing fine, although there is indefinite encoding used... !!! % test(dsd)-> - EncPdu = [48, 128, 128, 8, 98, 2, 50, 1, 0, 0, 0, 241, 170, 2, 5, 0, 0, 0, 0, 0], - - ?line {ok,_DecPdu} = asn1_wrapper:decode('Mvrasn-11-4', - 'DeleteSubscriberDataArg', - EncPdu), - + EncPdu = <<48,128,128,8,98,2,50,1,0,0,0,241,170,2,5,0,0,0,0,0>>, + {ok,_DecPdu} = 'Mvrasn-11-4':decode('DeleteSubscriberDataArg', EncPdu), ok; % % Is doing fine !!! % test(ul_res)-> - EncPdu = [48, 9, 4, 7, 145, 148, 113, 66, 16, 17, 241], - - ?line {ok,_DecPdu} = asn1_wrapper:decode('Mvrasn-11-4', - 'UpdateGprsLocationRes', - EncPdu), - + EncPdu = <<48,9,4,7,145,148,113,66,16,17,241>>, + {ok,_DecPdu} = 'Mvrasn-11-4':decode('UpdateGprsLocationRes', EncPdu), ok; test(prim) -> - ?line {ok,Bytes} = asn1_wrapper:encode('SeqOf','SeqOfInt',[10,20,30]), - ?line [Tag,_Len|Ints] = lists:flatten(Bytes), - ?line {ok,[10,20,30]} = - asn1_wrapper:decode('SeqOf','SeqOfInt',[Tag,128|Ints] ++ [0,0]), + Bytes = asn1_test_lib:roundtrip_enc('SeqOf', 'SeqOfInt', [10,20,30]), + <<Tag,_Len,Ints/binary>> = Bytes, + {ok,[10,20,30]} = + 'SeqOf':decode('SeqOfInt', <<Tag,128,Ints/binary,0,0>>), ok; test(seqofseq) -> - {ok,_V} = asn1_wrapper:decode('Mvrasn-DataTypes-1', - 'SentParameters', - [48, + {ok,_V} = 'Mvrasn-DataTypes-1':decode( + 'SentParameters', + [48, 129, 190, 161, @@ -281,17 +274,16 @@ test(seqofseq) -> 0]), ok; test('InsertSubscriberDataArg') -> - {ok,_V} = - asn1_wrapper:decode('Mvrasn-11-4','InsertSubscriberDataArg', - [16#30,16#80,16#81,16#07,16#91,16#94, - 16#71,16#92,16#00,16#35,16#80,16#83, - 16#01,16#00,16#A6,16#06,16#04,16#01, - 16#21,16#04,16#01,16#22,16#B0,16#80, - 16#05,16#00,16#A1,16#80,16#30,16#1A, - 16#02,16#01,16#01,16#90,16#02,16#F1, - 16#21,16#92,16#03,16#0D,16#92,16#1F, - 16#94,16#0C,16#03,16#53,16#49,16#4D, - 16#03,16#47,16#53,16#4E,16#03,16#4C, - 16#4B,16#50,16#00,16#00,16#00,16#00, - 16#98,16#01,16#00,16#00,16#00]), + EncPdu = <<16#30,16#80,16#81,16#07,16#91,16#94, + 16#71,16#92,16#00,16#35,16#80,16#83, + 16#01,16#00,16#A6,16#06,16#04,16#01, + 16#21,16#04,16#01,16#22,16#B0,16#80, + 16#05,16#00,16#A1,16#80,16#30,16#1A, + 16#02,16#01,16#01,16#90,16#02,16#F1, + 16#21,16#92,16#03,16#0D,16#92,16#1F, + 16#94,16#0C,16#03,16#53,16#49,16#4D, + 16#03,16#47,16#53,16#4E,16#03,16#4C, + 16#4B,16#50,16#00,16#00,16#00,16#00, + 16#98,16#01,16#00,16#00,16#00>>, + {ok,_V} = 'Mvrasn-11-4':decode('InsertSubscriberDataArg', EncPdu), ok. diff --git a/lib/asn1/test/testSeqOfTag.erl b/lib/asn1/test/testSeqOfTag.erl index 2359df0c59..38c1dcb90f 100644 --- a/lib/asn1/test/testSeqOfTag.erl +++ b/lib/asn1/test/testSeqOfTag.erl @@ -44,145 +44,48 @@ -record('Exp',{os, bool}). main(_Rules) -> - - ?line {ok,Bytes11} = - asn1_wrapper:encode('SeqOfTag','SeqTagNt', - #'SeqTagNt'{nt = [#'NT'{bool = true, os = "kalle"}, - #'NT'{bool = true, os = "kalle"}]}), - ?line {ok,{'SeqTagNt', - [{'NT',[107,97,108,108,101],true},{'NT',[107,97,108,108,101],true}]}} = - asn1_wrapper:decode('SeqOfTag','SeqTagNt',lists:flatten(Bytes11)), - - ?line {ok,Bytes12} = - asn1_wrapper:encode('SeqOfTag','SeqTagNtI', - #'SeqTagNtI'{imp = [#'Imp'{bool = true, os = "kalle"}, - #'Imp'{bool = true, os = "kalle"}]}), - ?line {ok,{'SeqTagNtI', - [{'Imp',[107,97,108,108,101],true},{'Imp',[107,97,108,108,101],true}]}} = - asn1_wrapper:decode('SeqOfTag','SeqTagNtI',lists:flatten(Bytes12)), - - ?line {ok,Bytes13} = - asn1_wrapper:encode('SeqOfTag','SeqTagNtE', - #'SeqTagNtE'{exp = [#'Exp'{bool = true, os = "kalle"}, - #'Exp'{bool = true, os = "kalle"}]}), - ?line {ok,{'SeqTagNtE', - [{'Exp',[107,97,108,108,101],true},{'Exp',[107,97,108,108,101],true}]}} = - asn1_wrapper:decode('SeqOfTag','SeqTagNtE',lists:flatten(Bytes13)), - - - - ?line {ok,Bytes21} = - asn1_wrapper:encode('SeqOfTag','SeqTagI', - #'SeqTagI'{nt = [#'NT'{bool = true, os = "kalle"}, - #'NT'{bool = true, os = "kalle"}]}), - ?line {ok,{'SeqTagI', - [{'NT',[107,97,108,108,101],true},{'NT',[107,97,108,108,101],true}]}} = - asn1_wrapper:decode('SeqOfTag','SeqTagI',lists:flatten(Bytes21)), - - ?line {ok,Bytes22} = - asn1_wrapper:encode('SeqOfTag','SeqTagII', - #'SeqTagII'{imp = [#'Imp'{bool = true, os = "kalle"}, - #'Imp'{bool = true, os = "kalle"}]}), - ?line {ok,{'SeqTagII', - [{'Imp',[107,97,108,108,101],true},{'Imp',[107,97,108,108,101],true}]}} = - asn1_wrapper:decode('SeqOfTag','SeqTagII',lists:flatten(Bytes22)), - - ?line {ok,Bytes23} = - asn1_wrapper:encode('SeqOfTag','SeqTagIE', - #'SeqTagIE'{exp = [#'Exp'{bool = true, os = "kalle"}, - #'Exp'{bool = true, os = "kalle"}]}), - ?line {ok,{'SeqTagIE', - [{'Exp',[107,97,108,108,101],true},{'Exp',[107,97,108,108,101],true}]}} = - asn1_wrapper:decode('SeqOfTag','SeqTagIE',lists:flatten(Bytes23)), - - - - ?line {ok,Bytes31} = - asn1_wrapper:encode('SeqOfTag','SeqTagE', - #'SeqTagE'{nt = [#'NT'{bool = true, os = "kalle"}, - #'NT'{bool = true, os = "kalle"}]}), - ?line {ok,{'SeqTagE', - [{'NT',[107,97,108,108,101],true},{'NT',[107,97,108,108,101],true}]}} = - asn1_wrapper:decode('SeqOfTag','SeqTagE',lists:flatten(Bytes31)), - - ?line {ok,Bytes32} = - asn1_wrapper:encode('SeqOfTag','SeqTagEI', - #'SeqTagEI'{imp = [#'Imp'{bool = true, os = "kalle"}, - #'Imp'{bool = true, os = "kalle"}]}), - ?line {ok,{'SeqTagEI', - [{'Imp',[107,97,108,108,101],true},{'Imp',[107,97,108,108,101],true}]}} = - asn1_wrapper:decode('SeqOfTag','SeqTagEI',lists:flatten(Bytes32)), - - ?line {ok,Bytes33} = - asn1_wrapper:encode('SeqOfTag','SeqTagEE', - #'SeqTagEE'{exp = [#'Exp'{bool = true, os = "kalle"}, - #'Exp'{bool = true, os = "kalle"}]}), - ?line {ok,{'SeqTagEE', - [{'Exp',[107,97,108,108,101],true},{'Exp',[107,97,108,108,101],true}]}} = - asn1_wrapper:decode('SeqOfTag','SeqTagEE',lists:flatten(Bytes33)), - - - - + roundtrip('SeqTagNt', #'SeqTagNt'{nt=[#'NT'{os="kalle",bool=true}, + #'NT'{os="kalle",bool=true}]}), + roundtrip('SeqTagNtI', #'SeqTagNtI'{imp=[#'Imp'{os="kalle",bool=true}, + #'Imp'{os="kalle",bool=true}]}), + roundtrip('SeqTagNtE', #'SeqTagNtE'{exp=[#'Exp'{os="kalle",bool=true}, + #'Exp'{os="kalle",bool=true}]}), + roundtrip('SeqTagI', #'SeqTagI'{nt=[#'NT'{os="kalle",bool=true}, + #'NT'{os="kalle",bool=true}]}), + roundtrip('SeqTagII', #'SeqTagII'{imp=[#'Imp'{os="kalle",bool=true}, + #'Imp'{os="kalle",bool=true}]}), + roundtrip('SeqTagIE', #'SeqTagIE'{exp=[#'Exp'{os="kalle",bool=true}, + #'Exp'{os="kalle",bool=true}]}), + roundtrip('SeqTagE', #'SeqTagE'{nt=[#'NT'{os="kalle",bool=true}, + #'NT'{os="kalle",bool=true}]}), + roundtrip('SeqTagEI', #'SeqTagEI'{imp=[#'Imp'{os="kalle",bool=true}, + #'Imp'{os="kalle",bool=true}]}), + roundtrip('SeqTagEE', #'SeqTagEE'{exp=[#'Exp'{os="kalle",bool=true}, + #'Exp'{os="kalle",bool=true}]}), + roundtrip('SeqTagXNt', + #'SeqTagXNt'{xnt=[#'XSeqNT'{os="kalle",bool=true}, + #'XSeqNT'{os="kalle",bool=true}]}), + roundtrip('SeqTagXI', + #'SeqTagXI'{ximp=[#'XSeqImp'{os="kalle",bool=true}, + #'XSeqImp'{os="kalle",bool=true}]}), + roundtrip('SeqTagXE', + #'SeqTagXE'{xexp=[#'XSeqExp'{os="kalle",bool=true}, + #'XSeqExp'{os="kalle",bool=true}]}), + roundtrip('SeqTagImpX', + #'SeqTagImpX'{xnt=[#'XSeqNT'{os="kalle",bool=true}, + #'XSeqNT'{os="kalle",bool=true}], + ximp=[#'XSeqImp'{os="kalle",bool=true}, + #'XSeqImp'{os="kalle",bool=true}], + xexp=[#'XSeqExp'{os="kalle",bool=true}, + #'XSeqExp'{os="kalle",bool=true}]}), + roundtrip('SeqTagExpX', + #'SeqTagExpX'{xnt=[#'XSeqNT'{os="kalle",bool=true}, + #'XSeqNT'{os="kalle",bool=true}], + ximp=[#'XSeqImp'{os="kalle",bool=true}, + #'XSeqImp'{os="kalle",bool=true}], + xexp=[#'XSeqExp'{os="kalle",bool=true}, + #'XSeqExp'{os="kalle",bool=true}]}), + ok. - - - ?line {ok,Bytes41} = - asn1_wrapper:encode('SeqOfTag','SeqTagXNt', - #'SeqTagXNt'{xnt = [#'XSeqNT'{bool = true, os = "kalle"}, - #'XSeqNT'{bool = true, os = "kalle"}]}), - ?line {ok,{'SeqTagXNt', - [{'XSeqNT',[107,97,108,108,101],true},{'XSeqNT',[107,97,108,108,101],true}]}} = - asn1_wrapper:decode('SeqOfTag','SeqTagXNt',lists:flatten(Bytes41)), - - ?line {ok,Bytes42} = - asn1_wrapper:encode('SeqOfTag','SeqTagXI', - #'SeqTagXI'{ximp = [#'XSeqImp'{bool = true, os = "kalle"}, - #'XSeqImp'{bool = true, os = "kalle"}]}), - ?line {ok,{'SeqTagXI', - [{'XSeqImp',[107,97,108,108,101],true},{'XSeqImp',[107,97,108,108,101],true}]}} = - asn1_wrapper:decode('SeqOfTag','SeqTagXI',lists:flatten(Bytes42)), - - ?line {ok,Bytes43} = - asn1_wrapper:encode('SeqOfTag','SeqTagXE', - #'SeqTagXE'{xexp = [#'XSeqExp'{bool = true, os = "kalle"}, - #'XSeqExp'{bool = true, os = "kalle"}]}), - ?line {ok,{'SeqTagXE', - [{'XSeqExp',[107,97,108,108,101],true},{'XSeqExp',[107,97,108,108,101],true}]}} = - asn1_wrapper:decode('SeqOfTag','SeqTagXE',lists:flatten(Bytes43)), - - - - - - ?line {ok,Bytes51} = - asn1_wrapper:encode('SeqOfTag','SeqTagImpX', - #'SeqTagImpX'{xnt = [#'XSeqNT'{bool = true, os = "kalle"}, - #'XSeqNT'{bool = true, os = "kalle"}], - ximp = [#'XSeqImp'{bool = true, os = "kalle"}, - #'XSeqImp'{bool = true, os = "kalle"}], - xexp = [#'XSeqExp'{bool = true, os = "kalle"}, - #'XSeqExp'{bool = true, os = "kalle"}]}), - ?line {ok,{'SeqTagImpX', - [{'XSeqNT',[107,97,108,108,101],true},{'XSeqNT',[107,97,108,108,101],true}], - [{'XSeqImp',[107,97,108,108,101],true},{'XSeqImp',[107,97,108,108,101],true}], - [{'XSeqExp',[107,97,108,108,101],true},{'XSeqExp',[107,97,108,108,101],true}]}} = - asn1_wrapper:decode('SeqOfTag','SeqTagImpX',lists:flatten(Bytes51)), - - - - ?line {ok,Bytes52} = - asn1_wrapper:encode('SeqOfTag','SeqTagExpX', - #'SeqTagExpX'{xnt = [#'XSeqNT'{bool = true, os = "kalle"}, - #'XSeqNT'{bool = true, os = "kalle"}], - ximp = [#'XSeqImp'{bool = true, os = "kalle"}, - #'XSeqImp'{bool = true, os = "kalle"}], - xexp = [#'XSeqExp'{bool = true, os = "kalle"}, - #'XSeqExp'{bool = true, os = "kalle"}]}), - ?line {ok,{'SeqTagExpX', - [{'XSeqNT',[107,97,108,108,101],true},{'XSeqNT',[107,97,108,108,101],true}], - [{'XSeqImp',[107,97,108,108,101],true},{'XSeqImp',[107,97,108,108,101],true}], - [{'XSeqExp',[107,97,108,108,101],true},{'XSeqExp',[107,97,108,108,101],true}]}} = - asn1_wrapper:decode('SeqOfTag','SeqTagExpX',lists:flatten(Bytes52)), - -ok. +roundtrip(T, V) -> + asn1_test_lib:roundtrip('SeqOfTag', T, V). diff --git a/lib/asn1/test/testSeqOptional.erl b/lib/asn1/test/testSeqOptional.erl index 8013f3c685..c9478105a4 100644 --- a/lib/asn1/test/testSeqOptional.erl +++ b/lib/asn1/test/testSeqOptional.erl @@ -37,159 +37,48 @@ -record('SeqChoOpt',{int, cho = asn1_NOVALUE}). main(_Rules) -> - - ?line {ok,Bytes11} = - asn1_wrapper:encode('SeqOptional','SeqOpt1',#'SeqOpt1'{bool1 = true, - int1 = 15, - seq1 = #'SeqIn'{boolIn = true, - intIn = 66}}), - ?line {ok,{'SeqOpt1',true,15,{'SeqIn',true,66}}} = - asn1_wrapper:decode('SeqOptional','SeqOpt1',lists:flatten(Bytes11)), - - - ?line {ok,Bytes12} = asn1_wrapper:encode('SeqOptional','SeqOpt1',#'SeqOpt1'{int1 = 15}), - ?line {ok,{'SeqOpt1',asn1_NOVALUE,15,asn1_NOVALUE}} = - asn1_wrapper:decode('SeqOptional','SeqOpt1',lists:flatten(Bytes12)), - - - ?line {ok,Bytes21} = - asn1_wrapper:encode('SeqOptional','SeqOpt2',#'SeqOpt2'{bool2 = true, - int2 = 15, - seq2 = #'SeqIn'{boolIn = true, - intIn = 66}}), - ?line {ok,{'SeqOpt2',{'SeqIn',true,66},true,15}} = - asn1_wrapper:decode('SeqOptional','SeqOpt2',lists:flatten(Bytes21)), - - - ?line {ok,Bytes22} = asn1_wrapper:encode('SeqOptional','SeqOpt2',#'SeqOpt2'{int2 = 15, - bool2 = true}), - ?line {ok,{'SeqOpt2',asn1_NOVALUE,true,15}} = - asn1_wrapper:decode('SeqOptional','SeqOpt2',lists:flatten(Bytes22)), - - - - ?line {ok,Bytes31} = - asn1_wrapper:encode('SeqOptional','SeqOpt3',#'SeqOpt3'{bool3 = true, - int3 = 15, - seq3 = #'SeqIn'{boolIn = true, - intIn = 66}}), - ?line {ok,{'SeqOpt3',true,{'SeqIn',true,66},15}} = - asn1_wrapper:decode('SeqOptional','SeqOpt3',lists:flatten(Bytes31)), - - - ?line {ok,Bytes32} = asn1_wrapper:encode('SeqOptional','SeqOpt3',#'SeqOpt3'{int3 = 15}), - ?line {ok,{'SeqOpt3',asn1_NOVALUE,asn1_NOVALUE,15}} = - asn1_wrapper:decode('SeqOptional','SeqOpt3',lists:flatten(Bytes32)), - - - - - - ?line {ok,Bytes41} = - asn1_wrapper:encode('SeqOptional','SeqOpt1Imp',#'SeqOpt1Imp'{bool1 = true, - int1 = 15, - seq1 = #'SeqIn'{boolIn = true, - intIn = 66}}), - ?line {ok,{'SeqOpt1Imp',true,15,{'SeqIn',true,66}}} = - asn1_wrapper:decode('SeqOptional','SeqOpt1Imp',lists:flatten(Bytes41)), - - - ?line {ok,Bytes42} = asn1_wrapper:encode('SeqOptional','SeqOpt1Imp',#'SeqOpt1Imp'{int1 = 15}), - ?line {ok,{'SeqOpt1Imp',asn1_NOVALUE,15,asn1_NOVALUE}} = - asn1_wrapper:decode('SeqOptional','SeqOpt1Imp',lists:flatten(Bytes42)), - - - ?line {ok,Bytes51} = - asn1_wrapper:encode('SeqOptional','SeqOpt2Imp',#'SeqOpt2Imp'{bool2 = true, - int2 = 15, - seq2 = #'SeqIn'{boolIn = true, - intIn = 66}}), - ?line {ok,{'SeqOpt2Imp',{'SeqIn',true,66},true,15}} = - asn1_wrapper:decode('SeqOptional','SeqOpt2Imp',lists:flatten(Bytes51)), - - - ?line {ok,Bytes52} = asn1_wrapper:encode('SeqOptional','SeqOpt2Imp',#'SeqOpt2Imp'{int2 = 15, - bool2 = true}), - ?line {ok,{'SeqOpt2Imp',asn1_NOVALUE,true,15}} = - asn1_wrapper:decode('SeqOptional','SeqOpt2Imp',lists:flatten(Bytes52)), - - - - ?line {ok,Bytes61} = - asn1_wrapper:encode('SeqOptional','SeqOpt3Imp',#'SeqOpt3Imp'{bool3 = true, - int3 = 15, - seq3 = #'SeqIn'{boolIn = true, - intIn = 66}}), - ?line {ok,{'SeqOpt3Imp',true,{'SeqIn',true,66},15}} = - asn1_wrapper:decode('SeqOptional','SeqOpt3Imp',lists:flatten(Bytes61)), - - - ?line {ok,Bytes62} = asn1_wrapper:encode('SeqOptional','SeqOpt3Imp',#'SeqOpt3Imp'{int3 = 15}), - ?line {ok,{'SeqOpt3Imp',asn1_NOVALUE,asn1_NOVALUE,15}} = - asn1_wrapper:decode('SeqOptional','SeqOpt3Imp',lists:flatten(Bytes62)), - - - - - - - ?line {ok,Bytes71} = - asn1_wrapper:encode('SeqOptional','SeqOpt1Exp',#'SeqOpt1Exp'{bool1 = true, - int1 = 15, - seq1 = #'SeqIn'{boolIn = true, - intIn = 66}}), - ?line {ok,{'SeqOpt1Exp',true,15,{'SeqIn',true,66}}} = - asn1_wrapper:decode('SeqOptional','SeqOpt1Exp',lists:flatten(Bytes71)), - - - ?line {ok,Bytes72} = asn1_wrapper:encode('SeqOptional','SeqOpt1Exp',#'SeqOpt1Exp'{int1 = 15}), - ?line {ok,{'SeqOpt1Exp',asn1_NOVALUE,15,asn1_NOVALUE}} = - asn1_wrapper:decode('SeqOptional','SeqOpt1Exp',lists:flatten(Bytes72)), - - - ?line {ok,Bytes81} = - asn1_wrapper:encode('SeqOptional','SeqOpt2Exp',#'SeqOpt2Exp'{bool2 = true, - int2 = 15, - seq2 = #'SeqIn'{boolIn = true, - intIn = 66}}), - ?line {ok,{'SeqOpt2Exp',{'SeqIn',true,66},true,15}} = - asn1_wrapper:decode('SeqOptional','SeqOpt2Exp',lists:flatten(Bytes81)), - - - ?line {ok,Bytes82} = asn1_wrapper:encode('SeqOptional','SeqOpt2Exp',#'SeqOpt2Exp'{int2 = 15, - bool2 = true}), - ?line {ok,{'SeqOpt2Exp',asn1_NOVALUE,true,15}} = - asn1_wrapper:decode('SeqOptional','SeqOpt2Exp',lists:flatten(Bytes82)), - - - - ?line {ok,Bytes91} = - asn1_wrapper:encode('SeqOptional','SeqOpt3Exp',#'SeqOpt3Exp'{bool3 = true, - int3 = 15, - seq3 = #'SeqIn'{boolIn = true, - intIn = 66}}), - ?line {ok,{'SeqOpt3Exp',true,{'SeqIn',true,66},15}} = - asn1_wrapper:decode('SeqOptional','SeqOpt3Exp',lists:flatten(Bytes91)), - - - ?line {ok,Bytes92} = asn1_wrapper:encode('SeqOptional','SeqOpt3Exp',#'SeqOpt3Exp'{int3 = 15}), - ?line {ok,{'SeqOpt3Exp',asn1_NOVALUE,asn1_NOVALUE,15}} = - asn1_wrapper:decode('SeqOptional','SeqOpt3Exp',lists:flatten(Bytes92)), - - - - ?line {ok,Bytes101} = - asn1_wrapper:encode('SeqOptional','SeqChoOpt',#'SeqChoOpt'{int = 15, - cho = {boolC,true}}), - ?line {ok,{'SeqChoOpt',15,{boolC,true}}} = - asn1_wrapper:decode('SeqOptional','SeqChoOpt',lists:flatten(Bytes101)), - - - ?line {ok,Bytes102} = asn1_wrapper:encode('SeqOptional','SeqChoOpt',#'SeqChoOpt'{int = 15}), - ?line {ok,{'SeqChoOpt',15,asn1_NOVALUE}} = - asn1_wrapper:decode('SeqOptional','SeqChoOpt',lists:flatten(Bytes102)), - - - - + roundtrip('SeqOpt1', #'SeqOpt1'{bool1=true,int1=15, + seq1=#'SeqIn'{boolIn=true,intIn=66}}), + roundtrip('SeqOpt1', #'SeqOpt1'{bool1=asn1_NOVALUE, + int1=15,seq1=asn1_NOVALUE}), + roundtrip('SeqOpt2', #'SeqOpt2'{seq2=#'SeqIn'{boolIn=true,intIn=66}, + bool2=true,int2=15}), + roundtrip('SeqOpt2', #'SeqOpt2'{seq2=asn1_NOVALUE,bool2=true,int2=15}), + roundtrip('SeqOpt3', #'SeqOpt3'{bool3=true, + seq3=#'SeqIn'{boolIn=true, + intIn=66},int3=15}), + roundtrip('SeqOpt3', #'SeqOpt3'{bool3=asn1_NOVALUE, + seq3=asn1_NOVALUE,int3=15}), + roundtrip('SeqOpt1Imp', #'SeqOpt1Imp'{bool1=true,int1=15, + seq1=#'SeqIn'{boolIn=true,intIn=66}}), + roundtrip('SeqOpt1Imp', #'SeqOpt1Imp'{bool1=asn1_NOVALUE, + int1=15,seq1=asn1_NOVALUE}), + roundtrip('SeqOpt2Imp', #'SeqOpt2Imp'{seq2=#'SeqIn'{boolIn=true,intIn=66}, + bool2=true,int2=15}), + roundtrip('SeqOpt2Imp', #'SeqOpt2Imp'{seq2=asn1_NOVALUE, + bool2=true,int2=15}), + roundtrip('SeqOpt3Imp', #'SeqOpt3Imp'{bool3=true, + seq3=#'SeqIn'{boolIn=true,intIn=66}, + int3=15}), + roundtrip('SeqOpt3Imp', #'SeqOpt3Imp'{bool3=asn1_NOVALUE, + seq3=asn1_NOVALUE,int3=15}), + roundtrip('SeqOpt1Exp', #'SeqOpt1Exp'{bool1=true,int1=15, + seq1=#'SeqIn'{boolIn=true, + intIn=66}}), + roundtrip('SeqOpt1Exp', #'SeqOpt1Exp'{bool1=asn1_NOVALUE, + int1=15,seq1=asn1_NOVALUE}), + roundtrip('SeqOpt2Exp', #'SeqOpt2Exp'{seq2=#'SeqIn'{boolIn=true,intIn=66}, + bool2=true,int2=15}), + roundtrip('SeqOpt2Exp', #'SeqOpt2Exp'{seq2=asn1_NOVALUE, + bool2=true,int2=15}), + roundtrip('SeqOpt3Exp', #'SeqOpt3Exp'{bool3=true, + seq3=#'SeqIn'{boolIn=true,intIn=66}, + int3=15}), + roundtrip('SeqOpt3Exp', #'SeqOpt3Exp'{bool3=asn1_NOVALUE, + seq3=asn1_NOVALUE,int3=15}), + roundtrip('SeqChoOpt', #'SeqChoOpt'{int=15,cho={boolC,true}}), + roundtrip('SeqChoOpt', #'SeqChoOpt'{int=15,cho=asn1_NOVALUE}), ok. + +roundtrip(Type, Value) -> + asn1_test_lib:roundtrip('SeqOptional', Type, Value). diff --git a/lib/asn1/test/testSeqPrim.erl b/lib/asn1/test/testSeqPrim.erl index c2451a7cd1..eb21d50a37 100644 --- a/lib/asn1/test/testSeqPrim.erl +++ b/lib/asn1/test/testSeqPrim.erl @@ -27,58 +27,15 @@ -record('Empty',{}). main(_Rules) -> - - - - ?line {ok,Bytes11} = - asn1_wrapper:encode('SeqPrim','Seq',#'Seq'{bool = true, - boolCon = true, - boolPri = true, - boolApp = true, - boolExpCon = true, - boolExpPri = true, - boolExpApp = true}), - ?line {ok,{'Seq',true,true,true,true,true,true,true}} = - asn1_wrapper:decode('SeqPrim','Seq',lists:flatten(Bytes11)), - - - - - ?line {ok,Bytes12} = - asn1_wrapper:encode('SeqPrim','Seq',#'Seq'{bool = false, - boolCon = false, - boolPri = false, - boolApp = false, - boolExpCon = false, - boolExpPri = false, - boolExpApp = false}), - ?line {ok,{'Seq',false,false,false,false,false,false,false}} = - asn1_wrapper:decode('SeqPrim','Seq',lists:flatten(Bytes12)), - - - - - ?line {ok,Bytes13} = - asn1_wrapper:encode('SeqPrim','Seq',#'Seq'{bool = false, - boolCon = true, - boolPri = false, - boolApp = true, - boolExpCon = false, - boolExpPri = true, - boolExpApp = false}), - ?line {ok,{'Seq',false,true,false,true,false,true,false}} = - asn1_wrapper:decode('SeqPrim','Seq',lists:flatten(Bytes13)), - - - - - - ?line {ok,Bytes21} = - asn1_wrapper:encode('SeqPrim','Empty',#'Empty'{}), - ?line {ok,{'Empty'}} = - asn1_wrapper:decode('SeqPrim','Empty',lists:flatten(Bytes21)), - - - + roundtrip('Seq', #'Seq'{bool=true,boolCon=true,boolPri=true,boolApp=true, + boolExpCon=true,boolExpPri=true,boolExpApp=true}), + roundtrip('Seq', #'Seq'{bool=false,boolCon=false,boolPri=false, + boolApp=false,boolExpCon=false, + boolExpPri=false,boolExpApp=false}), + roundtrip('Seq', #'Seq'{bool=false,boolCon=true,boolPri=false,boolApp=true, + boolExpCon=false,boolExpPri=true,boolExpApp=false}), + roundtrip('Empty', #'Empty'{}), ok. +roundtrip(Type, Value) -> + asn1_test_lib:roundtrip('SeqPrim', Type, Value). diff --git a/lib/asn1/test/testSeqSetDefaultVal.erl b/lib/asn1/test/testSeqSetDefaultVal.erl index bd6c9428e2..fb61bf1647 100644 --- a/lib/asn1/test/testSeqSetDefaultVal.erl +++ b/lib/asn1/test/testSeqSetDefaultVal.erl @@ -18,10 +18,9 @@ %% %% -module(testSeqSetDefaultVal). - --include("External.hrl"). -export([main/1]). +-include("External.hrl"). -include_lib("test_server/include/test_server.hrl"). -record('SeqInts',{a = asn1_DEFAULT, @@ -95,242 +94,217 @@ bb = asn1_DEFAULT}). main(_Rules) -> - - ?line {ok,[48,0]} = - asn1_wrapper:encode('Default','SeqInts',#'SeqInts'{}), - ?line {ok,[48,0]} = - asn1_wrapper:encode('Default','SeqInts',#'SeqInts'{a=1,b=-1,c=three, - d=1}), - ?line {ok,{'SeqInts',1,-1,3,1}} = - asn1_wrapper:decode('Default','SeqInts',[48,0]), - - ?line {ok,[49,0]} = - asn1_wrapper:encode('Default','SetInts',#'SetInts'{}), - ?line {ok,[49,0]} = - asn1_wrapper:encode('Default','SetInts',#'SetInts'{a=1,b=-1,c=three, - d=1}), - ?line {ok,{'SetInts',1,-1,3,1}} = - asn1_wrapper:decode('Default','SetInts',[49,0]), - - - ?line {ok,[48,0]} = - asn1_wrapper:encode('Default','SeqBS', - #'SeqBS'{a=2#1010110, - b=16#A8A, - c=[second], - d=[1,0,0,1]}), - - ?line {ok,[48,0]} = - asn1_wrapper:encode('Default','SeqBS', - #'SeqBS'{a=[1,0,1,0,1,1,0], - b=[1,0,1,0,1,0,0,0,1,0,1,0], - c={5,<<64>>}, - d=9}), - - ?line {ok,[48,3,131,1,0]} = - asn1_wrapper:encode('Default','SeqBS', - #'SeqBS'{a=[1,0,1,0,1,1,0], - b=[1,0,1,0,1,0,0,0,1,0,1,0], - c={5,<<64>>}, - d=0}), - - {ok,{'SeqBS',[1,0,1,0,1,1,0],2698,[second],<<>>}} = - asn1_wrapper:decode('Default','SeqBS',[48,3,131,1,0]), - - ?line {ok,{'SeqBS',[1,0,1,0,1,1,0],2698,[second],[1,0,0,1]}} = - asn1_wrapper:decode('Default','SeqBS',[48,0]), - - ?line {ok,[49,0]} = - asn1_wrapper:encode('Default','SetBS', - #'SetBS'{a=2#1010110, - b=16#A8A, - c=[second], - d=[1,0,0,1]}), - - ?line {ok,[49,0]} = - asn1_wrapper:encode('Default','SetBS', - #'SetBS'{a=[1,0,1,0,1,1,0], - b=[1,0,1,0,1,0,0,0,1,0,1,0], - c={5,<<64>>}, - d=9}), - - ?line {ok,[49,3,131,1,0]} = - asn1_wrapper:encode('Default','SetBS', - #'SetBS'{a=[1,0,1,0,1,1,0], - b=[1,0,1,0,1,0,0,0,1,0,1,0], - c={5,<<64>>}, - d=0}), - - {ok,{'SetBS',[1,0,1,0,1,1,0],2698,[second],<<>>}} = - asn1_wrapper:decode('Default','SetBS',[49,3,131,1,0]), - - ?line {ok,{'SetBS',[1,0,1,0,1,1,0],2698,[second],[1,0,0,1]}} = - asn1_wrapper:decode('Default','SetBS',[49,0]), - - ?line {ok,[48,0]} = - asn1_wrapper:encode('Default','SeqOS', - #'SeqOS'{a=[172], - b=[16#A8,16#A0], - c='NULL'}), - - ?line {ok,[48,0]} = - asn1_wrapper:encode('Default','SeqOS', - #'SeqOS'{a=2#10101100, - b=16#A8A0, - c='NULL'}), - - ?line {ok,{'SeqOS',[172],[16#A8,16#A0],'NULL'}} = - asn1_wrapper:decode('Default','SeqOS',[48,0]), - - ?line {ok,[49,0]} = - asn1_wrapper:encode('Default','SetOS', - #'SetOS'{a=[172], - b=[16#A8,16#A0], - c='NULL'}), - - ?line {ok,[49,0]} = - asn1_wrapper:encode('Default','SetOS', - #'SetOS'{a=2#10101100, - b=16#A8A0, - c='NULL'}), - - ?line {ok,{'SetOS',[172],[16#A8,16#A0],'NULL'}} = - asn1_wrapper:decode('Default','SetOS',[49,0]), + roundtrip(<<48,0>>, + 'SeqInts', + #'SeqInts'{a=asn1_DEFAULT,b=asn1_DEFAULT, + c=asn1_DEFAULT,d=asn1_DEFAULT}, + #'SeqInts'{a=1,b=-1,c=3,d=1}), + roundtrip(<<48,0>>, + 'SeqInts', + #'SeqInts'{a=1,b=-1,c=three,d=1}, + #'SeqInts'{a=1,b=-1,c=3,d=1}), + + roundtrip(<<49,0>>, + 'SetInts', + #'SetInts'{a=asn1_DEFAULT,b=asn1_DEFAULT, + c=asn1_DEFAULT,d=asn1_DEFAULT}, + #'SetInts'{a=1,b=-1,c=3,d=1}), + roundtrip(<<49,0>>, + 'SetInts', + #'SetInts'{a=1,b=-1,c=three,d=1}, + #'SetInts'{a=1,b=-1,c=3,d=1}), + + + roundtrip(<<48,0>>, + 'SeqBS', + #'SeqBS'{a=2#1010110,b=16#A8A,c=[second],d=[1,0,0,1]}, + #'SeqBS'{a=[1,0,1,0,1,1,0],b=16#A8A,c=[second],d=[1,0,0,1]}), + roundtrip(<<48,0>>, + 'SeqBS', + #'SeqBS'{a=[1,0,1,0,1,1,0], + b=[1,0,1,0,1,0,0,0,1,0,1,0], + c={5,<<64>>}, + d=2#1001}, + #'SeqBS'{a=[1,0,1,0,1,1,0],b=16#A8A,c=[second],d=[1,0,0,1]}), + roundtrip(<<48,3,131,1,0>>, + 'SeqBS', + #'SeqBS'{a=[1,0,1,0,1,1,0], + b=[1,0,1,0,1,0,0,0,1,0,1,0], + c={5,<<64>>}, + d=0}, + #'SeqBS'{a=[1,0,1,0,1,1,0], + b=16#A8A, + c=[second], + d = <<>>}), + + roundtrip(<<49,0>>, + 'SetBS', + #'SetBS'{a=2#1010110,b=16#A8A,c=[second],d=[1,0,0,1]}, + #'SetBS'{a=[1,0,1,0,1,1,0],b=16#A8A,c=[second],d=[1,0,0,1]}), + roundtrip(<<49,0>>, + 'SetBS', + #'SetBS'{a=[1,0,1,0,1,1,0], + b=[1,0,1,0,1,0,0,0,1,0,1,0], + c={5,<<64>>}, + d=9}, + #'SetBS'{a=[1,0,1,0,1,1,0], + b=16#A8A, + c=[second], + d=[1,0,0,1]}), + roundtrip(<<49,3,131,1,0>>, + 'SetBS', + #'SetBS'{a=[1,0,1,0,1,1,0], + b=[1,0,1,0,1,0,0,0,1,0,1,0], + c={5,<<64>>}, + d=0}, + #'SetBS'{a=[1,0,1,0,1,1,0], + b=16#A8A, + c=[second], + d = <<>>}), + + roundtrip(<<48,0>>, 'SeqOS', + #'SeqOS'{a=[172],b=[16#A8,16#A0],c='NULL'}), + roundtrip(<<48,0>>, + 'SeqOS', + #'SeqOS'{a=172,b=43168,c='NULL'}, + #'SeqOS'{a=[172],b=[16#A8,16#A0],c='NULL'}), + + roundtrip(<<49,0>>, 'SetOS', #'SetOS'{a=[172],b=[16#A8,16#A0],c='NULL'}), + roundtrip(<<49,0>>, + 'SetOS', + #'SetOS'{a=172,b=43168,c='NULL'}, + #'SetOS'{a=[172],b=[16#A8,16#A0],c='NULL'}), + + roundtrip(<<48,0>>, + 'SeqOI', + #'SeqOI'{a={1,2,14,15}, + b={iso,'member-body',250,3,4}, + c={iso,standard,8571,2,250,4}}, + #'SeqOI'{a={1,2,14,15}, + b={1,2,250,3,4}, + c={1,0,8571,2,250,4}}), + + roundtrip(<<49,0>>, + 'SetOI', + #'SetOI'{a={1,2,14,15}, + b={iso,'member-body',250,3,4}, + c={iso,standard,8571,2,250,4}}, + #'SetOI'{a={1,2,14,15}, + b={1,2,250,3,4}, + c={1,0,8571,2,250,4}}), + + roundtrip(<<48,0>>, 'SeqEnum', #'SeqEnum'{a=b4,b=b2}), + roundtrip(<<49,0>>, 'SetEnum', #'SetEnum'{a=b4,b=b2}), + + roundtrip(<<48,0>>, + 'SeqIntBool', + #'SeqIntBool'{a=#'SeqIntBool_a'{aa=12,ab=13}, + b=#'S2'{a=14,b=true}, + c=#'S2'{a=15,b=false}}), + roundtrip(<<48,0>>, + 'SeqIntBool', + #'SeqIntBool'{a=asn1_DEFAULT,b=asn1_DEFAULT,c=asn1_DEFAULT}, + #'SeqIntBool'{a=#'SeqIntBool_a'{aa=12,ab=13}, + b=#'S2'{a=14,b=true}, + c=#'S2'{a=15,b=false}}), + + roundtrip(<<49,0>>, + 'SetIntBool', + #'SetIntBool'{a=#'SetIntBool_a'{aa=12,ab=13}, + b=#'S2'{a=14,b=true}, + c=#'S2'{a=15,b=false}}), + roundtrip(<<49,0>>, + 'SetIntBool', + #'SetIntBool'{a=asn1_DEFAULT,b=asn1_DEFAULT,c=asn1_DEFAULT}, + #'SetIntBool'{a=#'SetIntBool_a'{aa=12,ab=13}, + b=#'S2'{a=14,b=true}, + c=#'S2'{a=15,b=false}}), + + roundtrip(<<48,0>>, + 'SeqStrings', + #'SeqStrings'{a="123456789",b1="abcdef", + b2={0,13}, + b3={"First line",{0,13},"Second line"}, + c="Printable string", + d={0,0,1,14}}, + #'SeqStrings'{a="123456789",b1="abcdef", + b2=[0,13], + b3=["First line",[0,13],"Second line"], + c="Printable string", + d=[0,0,1,14]}), + + roundtrip(<<49,0>>, + 'SetStrings', + #'SetStrings'{a="123456789",b1="abcdef", + b2={0,13}, + b3={"First line",{0,13},"Second line"}, + c="Printable string", + d={0,0,1,14}}, + #'SetStrings'{a="123456789",b1="abcdef", + b2=[0,13], + b3=["First line",[0,13],"Second line"], + c="Printable string", + d=[0,0,1,14]}), + + roundtrip(<<48,0>>, + 'S1', + #'S1'{a=#'S1_a'{aa=1,ab=#'S2'{a=2,b=true}}, + b=#'S4'{a=#'S2'{a=2,b=true},b=#'S4_b'{ba=true,bb=5}}}), + + roundtrip(<<48,3,129,1,255>>, 'S2', #'S2'{a=1,b=true}), + + roundtrip(<<48,0>>, + 'S3', + #'S3'{a="\v\f\r", + b=[{a,11},{b,true},{c,13}], + c=[1,2,3,4], + d=[#'S2'{a=20,b=true},#'S2'{a=30,b=false}]}), + roundtrip(<<48,0>>, + 'S3', + #'S3'{a=[11,13,12], + b=[{b,true},{a,11},{c,13}], + c=[3,4,1,2], + d=[#'S2'{a=30,b=false},#'S2'{a=20,b=true}]}, + #'S3'{a=[11,12,13], + b=[{a,11},{b,true},{c,13}], + c=[1,2,3,4], + d=[#'S2'{a=20,b=true},#'S2'{a=30,b=false}]}), + roundtrip(<<48,0>>, + 'S3', + #'S3'{a=asn1_DEFAULT,b=asn1_DEFAULT, + c=asn1_DEFAULT,d=asn1_DEFAULT}, + #'S3'{a=[11,12,13], + b=[{a,11},{b,true},{c,13}], + c=[1,2,3,4], + d=[#'S2'{a=20,b=true},#'S2'{a=30,b=false}]}), + + roundtrip(<<49,0>>, + 'S3set', + #'S3set'{a=[{c,#'S2'{a=3,b=true}},{b,17},{a,false}], + b=[1,2,3,4]}), + roundtrip(<<49,0>>, + 'S3set', + #'S3set'{a=[{b,17},{c,#'S2'{a=3,b=true}},{a,false}], + b=[1,3,4,2]}, + #'S3set'{a=[{c,#'S2'{a=3,b=true}},{b,17},{a,false}], + b=[1,2,3,4]}), + roundtrip(<<49,0>>, + 'S3set', + #'S3set'{a=asn1_DEFAULT,b=asn1_DEFAULT}, + #'S3set'{a=[{c,#'S2'{a=3,b=true}},{b,17},{a,false}], + b=[1,2,3,4]}), + + roundtrip(<<48,0>>, + 'S4', + #'S4'{a=#'S2'{a=1,b=asn1_NOVALUE},b=#'S4_b'{ba=true,bb=0}}, + #'S4'{a=#'S2'{a=1,b=asn1_NOVALUE},b=#'S4_b'{ba=true,bb=0}}), - ?line {ok,[48,0]} = - asn1_wrapper:encode('Default','SeqOI', - #'SeqOI'{a={1,2,14,15}, - b={iso,'member-body',250,3,4}, - c={iso,standard,8571,2,250,4}}), - - ?line {ok,{'SeqOI',{1,2,14,15},{1,2,250,3,4},{1,0,8571,2,250,4}}} = - asn1_wrapper:decode('Default','SeqOI',[48,0]), - - ?line {ok,[49,0]} = - asn1_wrapper:encode('Default','SetOI', - #'SetOI'{a={1,2,14,15}, - b={iso,'member-body',250,3,4}, - c={iso,standard,8571,2,250,4}}), - - ?line {ok,{'SetOI',{1,2,14,15},{1,2,250,3,4},{1,0,8571,2,250,4}}} = - asn1_wrapper:decode('Default','SetOI',[49,0]), - - ?line {ok,[48,0]} = - asn1_wrapper:encode('Default','SeqEnum',#'SeqEnum'{a=b4,b=b2}), - - ?line {ok,{'SeqEnum',b4,b2}} = - asn1_wrapper:decode('Default','SeqEnum',[48,0]), - - ?line {ok,[49,0]} = - asn1_wrapper:encode('Default','SetEnum',#'SetEnum'{a=b4,b=b2}), - - ?line {ok,{'SetEnum',b4,b2}} = - asn1_wrapper:decode('Default','SetEnum',[49,0]), - - ?line {ok,[48,0]} = - asn1_wrapper:encode('Default','SeqIntBool', - #'SeqIntBool'{a=#'SeqIntBool_a'{aa=12,ab=13}, - b=#'S2'{a=14,b=true}, - c=#'S2'{a=15,b=false}}), - - ?line {ok,[48,0]} = - asn1_wrapper:encode('Default','SeqIntBool', - #'SeqIntBool'{}), - - ?line {ok,{'SeqIntBool',{'SeqIntBool_a',12,13}, - {'S2',14,true},{'S2',15,false}}} = - asn1_wrapper:decode('Default','SeqIntBool',[48,0]), - - ?line {ok,[49,0]} = - asn1_wrapper:encode('Default','SetIntBool', - #'SetIntBool'{a=#'SetIntBool_a'{aa=12,ab=13}, - b=#'S2'{a=14,b=true}, - c=#'S2'{a=15,b=false}}), - - ?line {ok,[49,0]} = - asn1_wrapper:encode('Default','SetIntBool', - #'SetIntBool'{}), - - ?line {ok,{'SetIntBool',{'SetIntBool_a',12,13}, - {'S2',14,true},{'S2',15,false}}} = - asn1_wrapper:decode('Default','SetIntBool',[49,0]), - - ?line {ok,[48,0]} = - asn1_wrapper:encode('Default','SeqStrings', - #'SeqStrings'{a="123456789", - b1="abcdef", - b2={0,13}, - b3={"First line",{0,13},"Second line"}, - c="Printable string", - d={0,0,1,14}}), - - ?line {ok,{'SeqStrings',"123456789","abcdef",[0,13], - ["First line",[0,13],"Second line"],"Printable string", - [0,0,1,14]}} = - asn1_wrapper:decode('Default','SeqStrings',[48,0]), - - ?line {ok,[49,0]} = - asn1_wrapper:encode('Default','SetStrings', - #'SetStrings'{a="123456789", - b1="abcdef", - b2={0,13}, - b3={"First line",{0,13},"Second line"}, - c="Printable string", - d={0,0,1,14}}), - - ?line {ok,{'SetStrings',"123456789","abcdef",[0,13], - ["First line",[0,13],"Second line"],"Printable string", - [0,0,1,14]}} = - asn1_wrapper:decode('Default','SetStrings',[49,0]), - - - ?line {ok,[48,0]} = - asn1_wrapper:encode('Default','S1', - #'S1'{a=#'S1_a'{aa=1, - ab=#'S2'{a=2,b=true}}, - b=#'S4'{a=#'S2'{a=2,b=true}, - b=#'S4_b'{ba=true, - bb=5}}}), - - ?line {ok,{'S1',{'S1_a',1,{'S2',2,true}}, - {'S4',{'S2',2,true},{'S4_b',true,5}}}} = - asn1_wrapper:decode('Default','S1',[48,0]), - - ?line {ok,[48,3,129,1,255]} = - asn1_wrapper:encode('Default','S2', - #'S2'{a=1,b=true}), - - ?line {ok,[48,0]} = - asn1_wrapper:encode('Default','S3', - #'S3'{a=[11,12,13], - b=[{a,11},{b,true},{c,13}], - c=[1,2,3,4], - d=[#'S2'{a=20,b=true},#'S2'{a=30,b=false}]}), - - ?line {ok,[48,0]} = - asn1_wrapper:encode('Default','S3', - #'S3'{a=[11,13,12], - b=[{b,true},{a,11},{c,13}], - c=[3,4,1,2], - d=[#'S2'{a=30,b=false},#'S2'{a=20,b=true}]}), - - ?line {ok,[48,0]} = asn1_wrapper:encode('Default','S3',#'S3'{}), - - ?line {ok,[49,0]} = - asn1_wrapper:encode('Default','S3set', - #'S3set'{a=[{c,#'S2'{a=3,b=true}}, - {b,17},{a,false}], - b=[1,2,3,4]}), + ok. - ?line {ok,[49,0]} = - asn1_wrapper:encode('Default','S3set', - #'S3set'{a=[{b,17},{c,#'S2'{a=3,b=true}}, - {a,false}], - b=[1,3,4,2]}), +roundtrip(Encoded, Type, Value) -> + roundtrip(Encoded, Type, Value, Value). - ?line {ok,[49,0]} = asn1_wrapper:encode('Default','S3set',#'S3set'{}), - - ?line {ok,[48,0]} = - asn1_wrapper:encode('Default','S4',#'S4'{a={'S2',1,asn1_NOVALUE}, - b=#'S4_b'{ba=true,bb=0}}), +roundtrip(Encoded, Type, Value, ExpectedValue) -> + Encoded = asn1_test_lib:roundtrip_enc('Default', Type, + Value, ExpectedValue), ok. diff --git a/lib/asn1/test/testSeqSetIndefinite.erl b/lib/asn1/test/testSeqSetIndefinite.erl new file mode 100644 index 0000000000..6becf84e77 --- /dev/null +++ b/lib/asn1/test/testSeqSetIndefinite.erl @@ -0,0 +1,52 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2013. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +%% +-module(testSeqSetIndefinite). +-export([main/0]). + +-include_lib("test_server/include/test_server.hrl"). + +main() -> + seq_indefinite(), + set_indefinite(). + +seq_indefinite() -> + %% normal encoding + B = <<48,20,1,1,255,48,9,1,1,255,2,4,251,35,238,194,2,4,251,55,236,161>>, + %% indefinite length encoding + Bi = <<48,22,1,1,255,48,128,1,1,255,2,4,251,35,238,194,0,0,2,4,251,55,236,161>>, + %% the value which is encoded + V = {'SeqS3',true,{'SeqS3_seqS3',true,-81531198},-80221023}, + {ok,V} = 'SeqSetIndefinite':decode('SeqS3', B), + {ok,V} = 'SeqSetIndefinite':decode('SeqS3', Bi), + + ok. + +set_indefinite() -> + %% normal encoding + B = <<49,20,1,1,255,49,9,1,1,255,2,4,251,35,238,194,2,4,251,55,236,161>>, + %% indefinite length encoding + Bi = <<49,22,1,1,255,49,128,1,1,255,2,4,251,35,238,194,0,0,2,4,251,55,236,161>>, + + %% the value which is encoded + V = {'SetS3',true,{'SetS3_setS3',true,-81531198},-80221023}, + {ok,V} = 'SeqSetIndefinite':decode('SetS3', B), + {ok,V} = 'SeqSetIndefinite':decode('SetS3', Bi), + + ok. diff --git a/lib/asn1/test/testSeqTag.erl b/lib/asn1/test/testSeqTag.erl index 9fdaae35dd..2f127b3e97 100644 --- a/lib/asn1/test/testSeqTag.erl +++ b/lib/asn1/test/testSeqTag.erl @@ -35,69 +35,25 @@ -record('Exp',{os, bool}). main(_Rules) -> - - - ?line {ok,Bytes11} = - asn1_wrapper:encode('SeqTag','SeqTag',#'SeqTag'{nt = #'NT'{bool = true, os = "kalle"}, - imp = #'Imp'{bool = true, os = "kalle"}, - exp = #'Exp'{bool = true, os = "kalle"}}), - ?line {ok,{'SeqTag',{'NT',"kalle",true},{'Imp',"kalle",true},{'Exp',"kalle",true}}} = - asn1_wrapper:decode('SeqTag','SeqTag',lists:flatten(Bytes11)), - - - ?line {ok,Bytes12} = - asn1_wrapper:encode('SeqTag','SeqTagImp',#'SeqTagImp'{nt = #'NT'{bool = true, os = "kalle"}, - imp = #'Imp'{bool = true, os = "kalle"}, - exp = #'Exp'{bool = true, os = "kalle"}}), - ?line {ok,{'SeqTagImp',{'NT',"kalle",true},{'Imp',"kalle",true},{'Exp',"kalle",true}}} = - asn1_wrapper:decode('SeqTag','SeqTagImp',lists:flatten(Bytes12)), - - - ?line {ok,Bytes13} = - asn1_wrapper:encode('SeqTag','SeqTagExp',#'SeqTagExp'{nt = #'NT'{bool = true, os = "kalle"}, - imp = #'Imp'{bool = true, os = "kalle"}, - exp = #'Exp'{bool = true, os = "kalle"}}), - ?line {ok,{'SeqTagExp',{'NT',"kalle",true},{'Imp',"kalle",true},{'Exp',"kalle",true}}} = - asn1_wrapper:decode('SeqTag','SeqTagExp',lists:flatten(Bytes13)), - - - - - - ?line {ok,Bytes21} = - asn1_wrapper:encode('SeqTag','SeqTagX', - #'SeqTagX'{xnt = #'XSeqNT'{bool = true, os = "kalle"}, - ximp = #'XSeqImp'{bool = true, os = "kalle"}, - xexp = #'XSeqExp'{bool = true, os = "kalle"}}), - ?line {ok,{'SeqTagX',{'XSeqNT',"kalle",true}, - {'XSeqImp',"kalle",true}, - {'XSeqExp',"kalle",true}}} = - asn1_wrapper:decode('SeqTag','SeqTagX',lists:flatten(Bytes21)), - - - ?line {ok,Bytes22} = - asn1_wrapper:encode('SeqTag','SeqTagImpX', - #'SeqTagImpX'{xnt = #'XSeqNT'{bool = true, os = "kalle"}, - ximp = #'XSeqImp'{bool = true, os = "kalle"}, - xexp = #'XSeqExp'{bool = true, os = "kalle"}}), - ?line {ok,{'SeqTagImpX',{'XSeqNT',"kalle",true}, - {'XSeqImp',"kalle",true}, - {'XSeqExp',"kalle",true}}} = - asn1_wrapper:decode('SeqTag','SeqTagImpX',lists:flatten(Bytes22)), - - - ?line {ok,Bytes23} = - asn1_wrapper:encode('SeqTag','SeqTagExpX', - #'SeqTagExpX'{xnt = #'XSeqNT'{bool = true, os = "kalle"}, - ximp = #'XSeqImp'{bool = true, os = "kalle"}, - xexp = #'XSeqExp'{bool = true, os = "kalle"}}), - ?line {ok,{'SeqTagExpX',{'XSeqNT',"kalle",true}, - {'XSeqImp',"kalle",true}, - {'XSeqExp',"kalle",true}}} = - asn1_wrapper:decode('SeqTag','SeqTagExpX',lists:flatten(Bytes23)), - - - - - + roundtrip('SeqTag', #'SeqTag'{nt=#'NT'{os="kalle",bool=true}, + imp=#'Imp'{os="kalle",bool=true}, + exp=#'Exp'{os="kalle",bool=true}}), + roundtrip('SeqTagImp', #'SeqTagImp'{nt=#'NT'{os="kalle",bool=true}, + imp=#'Imp'{os="kalle",bool=true}, + exp=#'Exp'{os="kalle",bool=true}}), + roundtrip('SeqTagExp', #'SeqTagExp'{nt=#'NT'{os="kalle",bool=true}, + imp=#'Imp'{os="kalle",bool=true}, + exp=#'Exp'{os="kalle",bool=true}}), + roundtrip('SeqTagX', #'SeqTagX'{xnt=#'XSeqNT'{os="kalle",bool=true}, + ximp=#'XSeqImp'{os="kalle",bool=true}, + xexp=#'XSeqExp'{os="kalle",bool=true}}), + roundtrip('SeqTagImpX', #'SeqTagImpX'{xnt=#'XSeqNT'{os="kalle",bool=true}, + ximp=#'XSeqImp'{os="kalle",bool=true}, + xexp=#'XSeqExp'{os="kalle",bool=true}}), + roundtrip('SeqTagExpX', #'SeqTagExpX'{xnt=#'XSeqNT'{os="kalle",bool=true}, + ximp=#'XSeqImp'{os="kalle",bool=true}, + xexp=#'XSeqExp'{os="kalle",bool=true}}), ok. + +roundtrip(T, V) -> + asn1_test_lib:roundtrip('SeqTag', T, V). diff --git a/lib/asn1/test/testSeqTypeRefCho.erl b/lib/asn1/test/testSeqTypeRefCho.erl index 4b9eac7034..b008bc46b8 100644 --- a/lib/asn1/test/testSeqTypeRefCho.erl +++ b/lib/asn1/test/testSeqTypeRefCho.erl @@ -27,17 +27,12 @@ -record('SeqTRcho',{seqCho, seqChoE, 'seqCho-E', 'seqChoE-E'}). main(_Rules) -> - - - ?line {ok,Bytes11} = - asn1_wrapper:encode('SeqTypeRefCho','SeqTRcho', - #'SeqTRcho'{'seqCho' = {choOs,"A string 1"}, - 'seqChoE' = {choOs,"A string 3"}, - 'seqCho-E' = {choOs,"A string 7"}, - 'seqChoE-E' = {choOs,"A string 9"}}), - ?line {ok,{'SeqTRcho',{choOs,"A string 1"},{choOs,"A string 3"},{choOs,"A string 7"},{choOs,"A string 9"}}} = - asn1_wrapper:decode('SeqTypeRefCho','SeqTRcho',lists:flatten(Bytes11)), - - - + roundtrip('SeqTRcho', + #'SeqTRcho'{'seqCho' = {choOs,"A string 1"}, + 'seqChoE' = {choOs,"A string 3"}, + 'seqCho-E' = {choOs,"A string 7"}, + 'seqChoE-E' = {choOs,"A string 9"}}), ok. + +roundtrip(T, V) -> + asn1_test_lib:roundtrip('SeqTypeRefCho', T, V). diff --git a/lib/asn1/test/testSeqTypeRefPrim.erl b/lib/asn1/test/testSeqTypeRefPrim.erl index 7d4c2acc0e..b63882ae99 100644 --- a/lib/asn1/test/testSeqTypeRefPrim.erl +++ b/lib/asn1/test/testSeqTypeRefPrim.erl @@ -18,40 +18,24 @@ %% %% -module(testSeqTypeRefPrim). - --export([compile/3]). -export([main/1]). -include_lib("test_server/include/test_server.hrl"). -record('SeqTR',{octStr, octStrI, octStrE, 'octStr-I', 'octStrI-I', 'octStrE-I', 'octStr-E', 'octStrI-E', 'octStrE-E'}). - -compile(Config,Rules,Options) -> - - ?line DataDir = ?config(data_dir,Config), - ?line OutDir = ?config(priv_dir,Config), - ?line true = code:add_patha(?config(priv_dir,Config)), - ?line ok = asn1ct:compile(DataDir ++ "SeqTypeRefPrim",[Rules,{outdir,OutDir}]++Options). - - - main(_Rules) -> - - - ?line {ok,Bytes11} = - asn1_wrapper:encode('SeqTypeRefPrim','SeqTR',#'SeqTR'{'octStr' = "A string 1", - 'octStrI' = "A string 2", - 'octStrE' = "A string 3", - 'octStr-I' = "A string 4", - 'octStrI-I' = "A string 5", - 'octStrE-I' = "A string 6", - 'octStr-E' = "A string 7", - 'octStrI-E' = "A string 8", - 'octStrE-E' = "A string 9"}) , - ?line {ok,{'SeqTR',"A string 1","A string 2","A string 3","A string 4","A string 5","A string 6","A string 7","A string 8","A string 9"}} = - asn1_wrapper:decode('SeqTypeRefPrim','SeqTR',lists:flatten(Bytes11)), - - - + roundtrip('SeqTR', + #'SeqTR'{'octStr' = "A string 1", + 'octStrI' = "A string 2", + 'octStrE' = "A string 3", + 'octStr-I' = "A string 4", + 'octStrI-I' = "A string 5", + 'octStrE-I' = "A string 6", + 'octStr-E' = "A string 7", + 'octStrI-E' = "A string 8", + 'octStrE-E' = "A string 9"}), ok. + +roundtrip(T, V) -> + asn1_test_lib:roundtrip('SeqTypeRefPrim', T, V). diff --git a/lib/asn1/test/testSeqTypeRefSeq.erl b/lib/asn1/test/testSeqTypeRefSeq.erl index 57ec6c19b1..fc2e0a67c9 100644 --- a/lib/asn1/test/testSeqTypeRefSeq.erl +++ b/lib/asn1/test/testSeqTypeRefSeq.erl @@ -44,133 +44,43 @@ -record('SeqSeqExp',{seqInt, seqOs}). - main(_Rules) -> - - - ?line {ok,Bytes11} = - asn1_wrapper:encode('SeqTypeRefSeq','Seq1',#'Seq1'{bool1 = true, - int1 = 15, - seq1 = #'SeqIn'{boolIn = true, - intIn = 66}}), - ?line {ok,{'Seq1',true,15,{'SeqIn',true,66}}} = - asn1_wrapper:decode('SeqTypeRefSeq','Seq1',lists:flatten(Bytes11)), - - - - ?line {ok,Bytes12} = - asn1_wrapper:encode('SeqTypeRefSeq','Seq2',#'Seq2'{seq2 = #'SeqIn'{boolIn = true, - intIn = 66}, - bool2 = true, - int2 = 15}), - ?line {ok,{'Seq2',{'SeqIn',true,66},true,15}} = - asn1_wrapper:decode('SeqTypeRefSeq','Seq2',lists:flatten(Bytes12)), - - - ?line {ok,Bytes13} = - asn1_wrapper:encode('SeqTypeRefSeq','Seq3',#'Seq3'{bool3 = true, - seq3 = #'SeqIn'{boolIn = true, - intIn = 66}, - int3 = 15}), - ?line {ok,{'Seq3',true,{'SeqIn',true,66},15}} = - asn1_wrapper:decode('SeqTypeRefSeq','Seq3',lists:flatten(Bytes13)), - - - - ?line {ok,Bytes14} = - asn1_wrapper:encode('SeqTypeRefSeq','Seq4',#'Seq4'{seq41 = #'SeqIn'{boolIn = true, - intIn = 66}, - seq42 = #'SeqIn'{boolIn = true, - intIn = 66}, - seq43 = #'SeqIn'{boolIn = true, - intIn = 66}}), - ?line {ok,{'Seq4',{'SeqIn',true,66},{'SeqIn',true,66},{'SeqIn',true,66}}} = - asn1_wrapper:decode('SeqTypeRefSeq','Seq4',lists:flatten(Bytes14)), - - - - - - - - - ?line {ok,Bytes21} = - asn1_wrapper:encode('SeqTypeRefSeq','SeqS1',#'SeqS1'{boolS1 = true, - intS1 = 15, - seqS1 = #'SeqS1_seqS1'{boolIn = true, - intIn = 66}}), - ?line {ok,{'SeqS1',true,15,{'SeqS1_seqS1',true,66}}} = - asn1_wrapper:decode('SeqTypeRefSeq','SeqS1',lists:flatten(Bytes21)), - - - ?line {ok,Bytes22} = - asn1_wrapper:encode('SeqTypeRefSeq','SeqS2',#'SeqS2'{seqS2 = #'SeqS2_seqS2'{boolIn = true, - intIn = 66}, - boolS2 = true, - intS2 = 15}), - ?line {ok,{'SeqS2',{'SeqS2_seqS2',true,66},true,15}} = - asn1_wrapper:decode('SeqTypeRefSeq','SeqS2',lists:flatten(Bytes22)), - - - - ?line {ok,Bytes23} = - asn1_wrapper:encode('SeqTypeRefSeq','SeqS3',#'SeqS3'{boolS3 = true, - seqS3 = #'SeqS3_seqS3'{boolIn = true, - intIn = 66}, - intS3 = 15}), - ?line {ok,{'SeqS3',true,{'SeqS3_seqS3',true,66},15}} = - asn1_wrapper:decode('SeqTypeRefSeq','SeqS3',lists:flatten(Bytes23)), - - - - - - - ?line {ok,Bytes31} = - asn1_wrapper:encode('SeqTypeRefSeq','SeqSTag',#'SeqSTag'{seqS1 = #'SeqSTag_seqS1'{b1 = true, - i1 = 11}, - seqS2 = #'SeqSTag_seqS2'{b2 = true, - i2 = 22}, - seqS3 = #'SeqSTag_seqS3'{b3 = true, - i3 = 33}}), - ?line {ok,{'SeqSTag',{'SeqSTag_seqS1',true,11}, - {'SeqSTag_seqS2',true,22}, - {'SeqSTag_seqS3',true,33}}} = - asn1_wrapper:decode('SeqTypeRefSeq','SeqSTag',lists:flatten(Bytes31)), - - - - - - ?line {ok,Bytes41} = - asn1_wrapper:encode('SeqTypeRefSeq','SeqTRseq', - #'SeqTRseq'{'seqSeq' = #'SeqSeq'{seqOs = "A1", - seqInt = 2}, - 'seqSeqI' = #'SeqSeq'{seqOs = "A2", - seqInt = 2}, - 'seqSeqE' = #'SeqSeq'{seqOs = "A3", - seqInt = 2}, - 'seqSeq-I' = #'SeqSeqImp'{seqOs = "A4", - seqInt = 2}, - 'seqSeqI-I' = #'SeqSeqImp'{seqOs = "A5", - seqInt = 2}, - 'seqSeqE-I' = #'SeqSeqImp'{seqOs = "A6", - seqInt = 2}, - 'seqSeq-E' = #'SeqSeqExp'{seqOs = "A7", - seqInt = 2}, - 'seqSeqI-E' = #'SeqSeqExp'{seqOs = "A8", - seqInt = 2}, - 'seqSeqE-E' = #'SeqSeqExp'{seqOs = "A9", - seqInt = 2}}), - ?line {ok,{'SeqTRseq',{'SeqSeq',2,"A1"}, - {'SeqSeq',2,"A2"}, - {'SeqSeq',2,"A3"}, - {'SeqSeqImp',2,"A4"}, - {'SeqSeqImp',2,"A5"}, - {'SeqSeqImp',2,"A6"}, - {'SeqSeqExp',2,"A7"}, - {'SeqSeqExp',2,"A8"}, - {'SeqSeqExp',2,"A9"}}} = - asn1_wrapper:decode('SeqTypeRefSeq','SeqTRseq',lists:flatten(Bytes41)), - + roundtrip('Seq1', + #'Seq1'{bool1=true,int1=15, + seq1=#'SeqIn'{boolIn=true,intIn=66}}), + roundtrip('Seq2', + #'Seq2'{seq2=#'SeqIn'{boolIn=true,intIn=66}, + bool2=true,int2=15}), + roundtrip('Seq3', + #'Seq3'{bool3=true,seq3=#'SeqIn'{boolIn=true,intIn=66},int3=15}), + roundtrip('Seq4', + #'Seq4'{seq41=#'SeqIn'{boolIn=true,intIn=66}, + seq42=#'SeqIn'{boolIn=true,intIn=66}, + seq43=#'SeqIn'{boolIn=true,intIn=66}}), + roundtrip('SeqS1', + #'SeqS1'{boolS1=true,intS1=15, + seqS1=#'SeqS1_seqS1'{boolIn=true,intIn=66}}), + roundtrip('SeqS2', + #'SeqS2'{seqS2=#'SeqS2_seqS2'{boolIn=true,intIn=66}, + boolS2=true,intS2=15}), + roundtrip('SeqS3', + #'SeqS3'{boolS3=true,seqS3=#'SeqS3_seqS3'{boolIn=true,intIn=66}, + intS3=15}), + roundtrip('SeqSTag', + #'SeqSTag'{seqS1=#'SeqSTag_seqS1'{b1=true,i1=11}, + seqS2=#'SeqSTag_seqS2'{b2=true,i2=22}, + seqS3=#'SeqSTag_seqS3'{b3=true,i3=33}}), + roundtrip('SeqTRseq', + #'SeqTRseq'{seqSeq=#'SeqSeq'{seqInt=2,seqOs="A1"}, + seqSeqI=#'SeqSeq'{seqInt=2,seqOs="A2"}, + seqSeqE=#'SeqSeq'{seqInt=2,seqOs="A3"}, + 'seqSeq-I'=#'SeqSeqImp'{seqInt=2,seqOs="A4"}, + 'seqSeqI-I'=#'SeqSeqImp'{seqInt=2,seqOs="A5"}, + 'seqSeqE-I'=#'SeqSeqImp'{seqInt=2,seqOs="A6"}, + 'seqSeq-E'=#'SeqSeqExp'{seqInt=2,seqOs="A7"}, + 'seqSeqI-E'=#'SeqSeqExp'{seqInt=2,seqOs="A8"}, + 'seqSeqE-E'=#'SeqSeqExp'{seqInt=2,seqOs="A9"}}), ok. + +roundtrip(T, V) -> + asn1_test_lib:roundtrip('SeqTypeRefSeq', T, V). diff --git a/lib/asn1/test/testSeqTypeRefSet.erl b/lib/asn1/test/testSeqTypeRefSet.erl index c06a0e7a2b..911a4b7a47 100644 --- a/lib/asn1/test/testSeqTypeRefSet.erl +++ b/lib/asn1/test/testSeqTypeRefSet.erl @@ -31,36 +31,17 @@ main(_Rules) -> - - ?line {ok,Bytes41} = - asn1_wrapper:encode('SeqTypeRefSet','SeqTRset', - #'SeqTRset'{'seqSet' = #'SeqSet'{setOs = "A1", - setInt = 2}, - 'seqSetI' = #'SeqSet'{setOs = "A2", - setInt = 2}, - 'seqSetE' = #'SeqSet'{setOs = "A3", - setInt = 2}, - 'seqSet-I' = #'SeqSetImp'{setOs = "A4", - setInt = 2}, - 'seqSetI-I' = #'SeqSetImp'{setOs = "A5", - setInt = 2}, - 'seqSetE-I' = #'SeqSetImp'{setOs = "A6", - setInt = 2}, - 'seqSet-E' = #'SeqSetExp'{setOs = "A7", - setInt = 2}, - 'seqSetI-E' = #'SeqSetExp'{setOs = "A8", - setInt = 2}, - 'seqSetE-E' = #'SeqSetExp'{setOs = "A9", - setInt = 2}}), - ?line {ok,{'SeqTRset',{'SeqSet',2,"A1"}, - {'SeqSet',2,"A2"}, - {'SeqSet',2,"A3"}, - {'SeqSetImp',2,"A4"}, - {'SeqSetImp',2,"A5"}, - {'SeqSetImp',2,"A6"}, - {'SeqSetExp',2,"A7"}, - {'SeqSetExp',2,"A8"}, - {'SeqSetExp',2,"A9"}}} = - asn1_wrapper:decode('SeqTypeRefSet','SeqTRset',lists:flatten(Bytes41)), - + roundtrip('SeqTRset', + #'SeqTRset'{seqSet=#'SeqSet'{setInt=2,setOs="A1"}, + seqSetI=#'SeqSet'{setInt=2,setOs="A2"}, + seqSetE=#'SeqSet'{setInt=2,setOs="A3"}, + 'seqSet-I'=#'SeqSetImp'{setInt=2,setOs="A4"}, + 'seqSetI-I'=#'SeqSetImp'{setInt=2,setOs="A5"}, + 'seqSetE-I'=#'SeqSetImp'{setInt=2,setOs="A6"}, + 'seqSet-E'=#'SeqSetExp'{setInt=2,setOs="A7"}, + 'seqSetI-E'=#'SeqSetExp'{setInt=2,setOs="A8"}, + 'seqSetE-E'=#'SeqSetExp'{setInt=2,setOs="A9"}}), ok. + +roundtrip(T, V) -> + asn1_test_lib:roundtrip('SeqTypeRefSet', T, V). diff --git a/lib/asn1/test/testSetDefault.erl b/lib/asn1/test/testSetDefault.erl index 8aa205e0f0..055dc6cecf 100644 --- a/lib/asn1/test/testSetDefault.erl +++ b/lib/asn1/test/testSetDefault.erl @@ -26,58 +26,34 @@ -record('SetDef1',{bool1 = asn1_DEFAULT, int1, set1 = asn1_DEFAULT}). -record('SetDef2',{set2 = asn1_DEFAULT, bool2, int2}). -record('SetDef3',{bool3 = asn1_DEFAULT, set3 = asn1_DEFAULT, int3 = asn1_DEFAULT}). --record('SetIn',{boolIn, intIn}). +-record('SetIn', {boolIn = asn1_NOVALUE, intIn = 12}). main(_Rules) -> - - ?line {ok,Bytes11} = - asn1_wrapper:encode('SetDefault','SetDef1',#'SetDef1'{bool1 = true, - int1 = 15, - set1 = #'SetIn'{boolIn = true, - intIn = 66}}), - ?line {ok,{'SetDef1',true,15,{'SetIn',true,66}}} = - asn1_wrapper:decode('SetDefault','SetDef1',lists:flatten(Bytes11)), - - - ?line {ok,Bytes12} = asn1_wrapper:encode('SetDefault','SetDef1',#'SetDef1'{int1 = 15}), - ?line {ok,{'SetDef1',true,15,{'SetIn',asn1_NOVALUE,12}}} = - asn1_wrapper:decode('SetDefault','SetDef1',lists:flatten(Bytes12)), - - - ?line {ok,Bytes21} = - asn1_wrapper:encode('SetDefault','SetDef2',#'SetDef2'{bool2 = true, - int2 = 15, - set2 = #'SetIn'{boolIn = true, - intIn = 66}}), - ?line {ok,{'SetDef2',{'SetIn',true,66},true,15}} = - asn1_wrapper:decode('SetDefault','SetDef2',lists:flatten(Bytes21)), - - - ?line {ok,Bytes22} = asn1_wrapper:encode('SetDefault','SetDef2',#'SetDef2'{bool2 = true, - int2 = 15}), - ?line {ok,{'SetDef2',{'SetIn',asn1_NOVALUE,12},true,15}} = - asn1_wrapper:decode('SetDefault','SetDef2',lists:flatten(Bytes22)), - - - - ?line {ok,Bytes31} = - asn1_wrapper:encode('SetDefault','SetDef3',#'SetDef3'{bool3 = true, - int3 = 15, - set3 = #'SetIn'{boolIn = true, - intIn = 66}}), - ?line {ok,{'SetDef3',true,{'SetIn',true,66},15}} = - asn1_wrapper:decode('SetDefault','SetDef3',lists:flatten(Bytes31)), - - - ?line {ok,Bytes32} = asn1_wrapper:encode('SetDefault','SetDef3',#'SetDef3'{int3 = 15}), - ?line {ok,{'SetDef3',true,{'SetIn',asn1_NOVALUE,12},15}} = - asn1_wrapper:decode('SetDefault','SetDef3',lists:flatten(Bytes32)), - - - - + roundtrip('SetDef1', + #'SetDef1'{bool1=true,int1=15, + set1=#'SetIn'{boolIn=true,intIn=66}}), + roundtrip('SetDef1', + #'SetDef1'{bool1=asn1_DEFAULT,int1=15,set1=asn1_DEFAULT}, + #'SetDef1'{bool1=true,int1=15,set1=#'SetIn'{}}), - - + roundtrip('SetDef2', + #'SetDef2'{set2=#'SetIn'{boolIn=true,intIn=66}, + bool2=true,int2=15}), + roundtrip('SetDef2', + #'SetDef2'{set2=asn1_DEFAULT,bool2=true,int2=15}, + #'SetDef2'{set2=#'SetIn'{},bool2=true,int2=15}), + + roundtrip('SetDef3', + #'SetDef3'{bool3=true,set3=#'SetIn'{boolIn=true,intIn=66}, + int3=15}), + roundtrip('SetDef3', + #'SetDef3'{bool3=asn1_DEFAULT,set3=asn1_DEFAULT,int3=15}, + #'SetDef3'{bool3=true,set3=#'SetIn'{},int3=15}), ok. + +roundtrip(Type, Value) -> + roundtrip(Type, Value, Value). + +roundtrip(Type, Value, ExpectedValue) -> + asn1_test_lib:roundtrip('SetDefault', Type, Value, ExpectedValue). diff --git a/lib/asn1/test/testSetExtension.erl b/lib/asn1/test/testSetExtension.erl index c7fb3b42c4..4e2463326b 100644 --- a/lib/asn1/test/testSetExtension.erl +++ b/lib/asn1/test/testSetExtension.erl @@ -18,10 +18,7 @@ %% %% -module(testSetExtension). - - -include("External.hrl"). --export([compile/3]). -export([main/1]). -include_lib("test_server/include/test_server.hrl"). @@ -31,76 +28,20 @@ -record('SetExt3',{bool, int}). -record('SetExt4',{bool, int}). - -compile(Config,Rules,Options) -> - - ?line DataDir = ?config(data_dir,Config), - ?line OutDir = ?config(priv_dir,Config), - ?line true = code:add_patha(?config(priv_dir,Config)), - ?line ok = asn1ct:compile(DataDir ++ "SetExtension", - [Rules,{outdir,OutDir}]++Options). - - - main(_Rules) -> - - ?line {ok,Bytes11} = - asn1_wrapper:encode('SetExtension','SetExt1',#'SetExt1'{}), - ?line {ok,{'SetExt1'}} = - asn1_wrapper:decode('SetExtension','SetExt1',lists:flatten(Bytes11)), - - ?line {ok,Bytes21} = - asn1_wrapper:encode('SetExtension','SetExt2',#'SetExt2'{bool = true,int = 99}), - ?line {ok,{'SetExt2',true,99}} = - asn1_wrapper:decode('SetExtension','SetExt2',lists:flatten(Bytes21)), - - ?line {ok,Bytes22} = - asn1_wrapper:encode('SetExtension','SetExt2',#'SetExt2'{int = 99,bool = true}), - ?line {ok,{'SetExt2',true,99}} = - asn1_wrapper:decode('SetExtension','SetExt2',lists:flatten(Bytes22)), - - ?line {ok,Bytes31} = - asn1_wrapper:encode('SetExtension','SetExt3',#'SetExt3'{bool = true,int = 99}), - ?line {ok,{'SetExt3',true,99}} = - asn1_wrapper:decode('SetExtension','SetExt3',lists:flatten(Bytes31)), - - ?line {ok,Bytes32} = - asn1_wrapper:encode('SetExtension','SetExt3',#'SetExt3'{int = 99,bool = true}), - ?line {ok,{'SetExt3',true,99}} = - asn1_wrapper:decode('SetExtension','SetExt3',lists:flatten(Bytes32)), - - ?line {ok,Bytes41} = - asn1_wrapper:encode('SetExtension','SetExt4',#'SetExt4'{bool = true,int = 99}), - ?line {ok,{'SetExt4',true,99}} = - asn1_wrapper:decode('SetExtension','SetExt4',lists:flatten(Bytes41)), - - ?line {ok,Bytes42} = - asn1_wrapper:encode('SetExtension','SetExt4',#'SetExt4'{int = 99,bool = true}), - ?line {ok,{'SetExt4',true,99}} = - asn1_wrapper:decode('SetExtension','SetExt4',lists:flatten(Bytes42)), - - - %% Test of extension , needs to be improved and extended - - ?line {ok,BytesX11} = - asn1_wrapper:encode('SetExtension','SetExt1',#'SetExt1'{}), - ?line {ok,{'SetExt1'}} = - asn1_wrapper:decode('SetExtension','SetExt1',lists:flatten(BytesX11)), - - ?line {ok,BytesX21} = - asn1_wrapper:encode('SetExtension','SetExt2',#'SetExt2'{bool = true,int = 99}), - ?line {ok,{'SetExt2',true,99}} = - asn1_wrapper:decode('SetExtension','SetExt2',lists:flatten(BytesX21)), - - ?line {ok,BytesX22} = - asn1_wrapper:encode('SetExtension','SetExt2',#'SetExt2'{int = 99,bool = true}), - ?line {ok,{'SetExt2',true,99}} = - asn1_wrapper:decode('SetExtension','SetExt2',lists:flatten(BytesX22)), - - - - - + roundtrip('SetExt1', #'SetExt1'{}), + roundtrip('SetExt2', #'SetExt2'{bool=true,int=99}), + roundtrip('SetExt2', #'SetExt2'{bool=true,int=99}), + roundtrip('SetExt3', #'SetExt3'{bool=true,int=99}), + roundtrip('SetExt3', #'SetExt3'{bool=true,int=99}), + roundtrip('SetExt4', #'SetExt4'{bool=true,int=99}), + roundtrip('SetExt4', #'SetExt4'{bool=true,int=99}), + roundtrip('SetExt1', #'SetExt1'{}), + roundtrip('SetExt2', #'SetExt2'{bool=true,int=99}), + roundtrip('SetExt2', #'SetExt2'{bool=true,int=99}), ok. +roundtrip(T, V) -> + asn1_test_lib:roundtrip('SetExtension', T, V). + diff --git a/lib/asn1/test/testSetExternal.erl b/lib/asn1/test/testSetExternal.erl index 30cddcacfb..e17d7053aa 100644 --- a/lib/asn1/test/testSetExternal.erl +++ b/lib/asn1/test/testSetExternal.erl @@ -18,111 +18,36 @@ %% %% -module(testSetExternal). - --include("External.hrl"). -export([main/1]). +-include("External.hrl"). -include_lib("test_server/include/test_server.hrl"). - -record('SetXSeq1',{seq, bool, int}). -record('SetXSeq2',{bool, seq, int}). -record('SetXSeq3',{bool, int, seq}). -%-record('NT',{os, bool}). -%-record('Imp',{os, bool}). -%-record('Exp',{os, bool}). main(_Rules) -> - - ?line {ok,Bytes11} = - asn1_wrapper:encode('SetExternal','XNTNT',#'XSetNT'{bool = true, os = "kalle"}), - ?line {ok,{'XSetNT',[107,97,108,108,101],true}} = - asn1_wrapper:decode('SetExternal','XNTNT',lists:flatten(Bytes11)), - - ?line {ok,Bytes12} = - asn1_wrapper:encode('SetExternal','XImpNT',#'XSetNT'{bool = true, os = "kalle"}), - ?line {ok,{'XSetNT',[107,97,108,108,101],true}} = - asn1_wrapper:decode('SetExternal','XImpNT',lists:flatten(Bytes12)), - - ?line {ok,Bytes13} = - asn1_wrapper:encode('SetExternal','XExpNT',#'XSetNT'{bool = true, os = "kalle"}), - ?line {ok,{'XSetNT',[107,97,108,108,101],true}} = - asn1_wrapper:decode('SetExternal','XExpNT',lists:flatten(Bytes13)), - - - - ?line {ok,Bytes21} = - asn1_wrapper:encode('SetExternal','XNTImp',#'XSetImp'{bool = true, os = "kalle"}), - ?line {ok,{'XSetImp',[107,97,108,108,101],true}} = - asn1_wrapper:decode('SetExternal','XNTImp',lists:flatten(Bytes21)), - - ?line {ok,Bytes22} = - asn1_wrapper:encode('SetExternal','XImpImp',#'XSetImp'{bool = true, os = "kalle"}), - ?line {ok,{'XSetImp',[107,97,108,108,101],true}} = - asn1_wrapper:decode('SetExternal','XImpImp',lists:flatten(Bytes22)), - - ?line {ok,Bytes23} = - asn1_wrapper:encode('SetExternal','XExpImp',#'XSetImp'{bool = true, os = "kalle"}), - ?line {ok,{'XSetImp',[107,97,108,108,101],true}} = - asn1_wrapper:decode('SetExternal','XExpImp',lists:flatten(Bytes23)), - - - - ?line {ok,Bytes31} = - asn1_wrapper:encode('SetExternal','XNTExp',#'XSetExp'{bool = true, os = "kalle"}), - ?line {ok,{'XSetExp',[107,97,108,108,101],true}} = - asn1_wrapper:decode('SetExternal','XNTExp',lists:flatten(Bytes31)), - - ?line {ok,Bytes32} = - asn1_wrapper:encode('SetExternal','XImpExp',#'XSetExp'{bool = true, os = "kalle"}), - ?line {ok,{'XSetExp',[107,97,108,108,101],true}} = - asn1_wrapper:decode('SetExternal','XImpExp',lists:flatten(Bytes32)), - - ?line {ok,Bytes33} = - asn1_wrapper:encode('SetExternal','XExpExp',#'XSetExp'{bool = true, os = "kalle"}), - ?line {ok,{'XSetExp',[107,97,108,108,101],true}} = - asn1_wrapper:decode('SetExternal','XExpExp',lists:flatten(Bytes33)), - - - - ?line {ok,Bytes41} = - asn1_wrapper:encode('SetExternal','SetXSeq1', - #'SetXSeq1'{bool = true, - int = 66, - seq = #'XSeq1'{bool1 = true, - int1 = 77, - seq1 = #'XSeqIn'{boolIn = false, - intIn = 88}}}), - ?line {ok,{'SetXSeq1',{'XSeq1',true,77,{'XSeqIn',false,88}},true,66}} = - asn1_wrapper:decode('SetExternal','SetXSeq1',lists:flatten(Bytes41)), - - - - ?line {ok,Bytes42} = - asn1_wrapper:encode('SetExternal','SetXSeq2', - #'SetXSeq2'{bool = true, - int = 66, - seq = #'XSeq1'{bool1 = true, - int1 = 77, - seq1 = #'XSeqIn'{boolIn = false, - intIn = 88}}}), - ?line {ok,{'SetXSeq2',true,{'XSeq1',true,77,{'XSeqIn',false,88}},66}} = - asn1_wrapper:decode('SetExternal','SetXSeq2',lists:flatten(Bytes42)), - - ?line {ok,Bytes43} = - asn1_wrapper:encode('SetExternal','SetXSeq3', - #'SetXSeq3'{bool = true, - int = 66, - seq = #'XSeq1'{bool1 = true, - int1 = 77, - seq1 = #'XSeqIn'{boolIn = false, - intIn = 88}}}), - ?line {ok,{'SetXSeq3',true,66,{'XSeq1',true,77,{'XSeqIn',false,88}}}} = - asn1_wrapper:decode('SetExternal','SetXSeq3',lists:flatten(Bytes43)), - - - - + roundtrip('XNTNT', #'XSetNT'{os="kalle",bool=true}), + roundtrip('XImpNT', #'XSetNT'{os="kalle",bool=true}), + roundtrip('XExpNT', #'XSetNT'{os="kalle",bool=true}), + roundtrip('XNTImp', #'XSetImp'{os="kalle",bool=true}), + roundtrip('XImpImp', #'XSetImp'{os="kalle",bool=true}), + roundtrip('XExpImp', #'XSetImp'{os="kalle",bool=true}), + roundtrip('XNTExp', #'XSetExp'{os="kalle",bool=true}), + roundtrip('XImpExp', #'XSetExp'{os="kalle",bool=true}), + roundtrip('XExpExp', #'XSetExp'{os="kalle",bool=true}), + roundtrip('SetXSeq1', #'SetXSeq1'{seq=#'XSeq1'{bool1=true,int1=77, + seq1=#'XSeqIn'{boolIn=false,intIn=88}}, + bool=true,int=66}), + roundtrip('SetXSeq2', #'SetXSeq2'{bool=true, + seq=#'XSeq1'{bool1=true,int1=77, + seq1=#'XSeqIn'{boolIn=false,intIn=88}}, + int=66}), + roundtrip('SetXSeq3', #'SetXSeq3'{bool=true,int=66, + seq=#'XSeq1'{bool1=true,int1=77, + seq1=#'XSeqIn'{boolIn=false,intIn=88}}}), ok. - +roundtrip(T, V) -> + asn1_test_lib:roundtrip('SetExternal', T, V). diff --git a/lib/asn1/test/testSetIndefinite.erl b/lib/asn1/test/testSetIndefinite.erl deleted file mode 100644 index 73006da62b..0000000000 --- a/lib/asn1/test/testSetIndefinite.erl +++ /dev/null @@ -1,41 +0,0 @@ -%% -%% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1999-2012. All Rights Reserved. -%% -%% The contents of this file are subject to the Erlang Public License, -%% Version 1.1, (the "License"); you may not use this file except in -%% compliance with the License. You should have received a copy of the -%% Erlang Public License along with this software. If not, it can be -%% retrieved online at http://www.erlang.org/. -%% -%% Software distributed under the License is distributed on an "AS IS" -%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See -%% the License for the specific language governing rights and limitations -%% under the License. -%% -%% %CopyrightEnd% -%% -%% --module(testSetIndefinite). - --export([main/1]). - --include_lib("test_server/include/test_server.hrl"). - - -main(per) -> ok; -main(ber) -> - - %% normal encoding - B = [49,20,1,1,255,49,9,1,1,255,2,4,251,35,238,194,2,4,251,55,236,161], - %% indefinite length encoding - Bi = [49,22,1,1,255,49,128,1,1,255,2,4,251,35,238,194,0,0,2,4,251,55,236,161], - %% the value which is encoded - V = {'SetS3',true,{'SetS3_setS3',true,-81531198},-80221023}, - ?line {ok,V} = asn1_wrapper:decode('SeqSetIndefinite','SetS3',B), - ?line {ok,V} = asn1_wrapper:decode('SeqSetIndefinite','SetS3',Bi), - ok. - - - diff --git a/lib/asn1/test/testSetOf.erl b/lib/asn1/test/testSetOf.erl index 08723fb468..54c42c1f21 100644 --- a/lib/asn1/test/testSetOf.erl +++ b/lib/asn1/test/testSetOf.erl @@ -28,198 +28,108 @@ -record('Set3',{bool3, set3 = asn1_DEFAULT, int3}). -record('Set4',{set41 = asn1_DEFAULT, set42 = asn1_DEFAULT, set43 = asn1_DEFAULT}). -record('SetIn',{boolIn, intIn}). -%-record('SetCho',{bool1, int1, set1 = asn1_DEFAULT}). -%-record('SetChoInline',{bool1, int1, set1 = asn1_DEFAULT}). -%-record('SetChoOfInline_SETOF',{bool1, int1, set1 = asn1_DEFAULT}). -record('SetEmp',{set1}). -record('Empty',{}). main(_Rules) -> + roundtrip('Set1', + #'Set1'{bool1=true,int1=17,set1=asn1_DEFAULT}, + #'Set1'{bool1=true,int1=17,set1=[]}), + roundtrip('Set1', + #'Set1'{bool1=true,int1=17, + set1=[#'SetIn'{boolIn=true,intIn=25}]}), + roundtrip('Set1', #'Set1'{bool1=true,int1=17, + set1=[#'SetIn'{boolIn=true,intIn=25}, + #'SetIn'{boolIn=false,intIn=125}, + #'SetIn'{boolIn=false,intIn=225}]}), + + roundtrip('Set2', + #'Set2'{set2=asn1_DEFAULT,bool2=true,int2=17}, + #'Set2'{set2=[],bool2=true,int2=17}), + roundtrip('Set2', + #'Set2'{set2=[#'SetIn'{boolIn=true,intIn=25}], + bool2=true,int2=17}), + roundtrip('Set2', + #'Set2'{set2=[#'SetIn'{boolIn=true,intIn=25}, + #'SetIn'{boolIn=false,intIn=125}, + #'SetIn'{boolIn=false,intIn=225}], + bool2=true,int2=17}), + + roundtrip('Set3', + #'Set3'{bool3=true,set3=asn1_DEFAULT,int3=17}, + #'Set3'{bool3=true,set3=[],int3=17}), + roundtrip('Set3', + #'Set3'{bool3=true,set3=[#'SetIn'{boolIn=true,intIn=25}], + int3=17}), + roundtrip('Set3', + #'Set3'{bool3=true, + set3=[#'SetIn'{boolIn=true,intIn=25}, + #'SetIn'{boolIn=false,intIn=125}, + #'SetIn'{boolIn=false,intIn=225}], + int3=17}), + + roundtrip('Set4', + #'Set4'{set41=asn1_DEFAULT,set42=asn1_DEFAULT, + set43=asn1_DEFAULT}, + #'Set4'{set41=[],set42=[],set43=[]}), + roundtrip('Set4', + #'Set4'{set41=[#'SetIn'{boolIn=true,intIn=25}], + set42=asn1_DEFAULT,set43=asn1_DEFAULT}, + #'Set4'{set41=[#'SetIn'{boolIn=true,intIn=25}], + set42=[],set43=[]}), + roundtrip('Set4', + #'Set4'{set41=[#'SetIn'{boolIn=true,intIn=25}, + #'SetIn'{boolIn=false,intIn=125}, + #'SetIn'{boolIn=false,intIn=225}], + set42=asn1_DEFAULT,set43=asn1_DEFAULT}, + #'Set4'{set41=[#'SetIn'{boolIn=true,intIn=25}, + #'SetIn'{boolIn=false,intIn=125}, + #'SetIn'{boolIn=false,intIn=225}], + set42=[],set43=[]}), + roundtrip('Set4', + #'Set4'{set41=asn1_DEFAULT, + set42=[#'SetIn'{boolIn=true,intIn=25}], + set43=asn1_DEFAULT}, + #'Set4'{set41=[], + set42=[#'SetIn'{boolIn=true,intIn=25}], + set43=[]}), + roundtrip('Set4', + #'Set4'{set41=asn1_DEFAULT, + set42=[#'SetIn'{boolIn=true,intIn=25}, + #'SetIn'{boolIn=false,intIn=125}, + #'SetIn'{boolIn=false,intIn=225}], + set43=asn1_DEFAULT}, + #'Set4'{set41=[], + set42=[#'SetIn'{boolIn=true,intIn=25}, + #'SetIn'{boolIn=false,intIn=125}, + #'SetIn'{boolIn=false,intIn=225}], + set43=[]}), + roundtrip('Set4', + #'Set4'{set41=asn1_DEFAULT,set42=asn1_DEFAULT, + set43=[#'SetIn'{boolIn=true,intIn=25}]}, + #'Set4'{set41=[],set42=[], + set43=[#'SetIn'{boolIn=true,intIn=25}]}), + roundtrip('Set4', + #'Set4'{set41=asn1_DEFAULT,set42=asn1_DEFAULT, + set43=[#'SetIn'{boolIn=true,intIn=25}, + #'SetIn'{boolIn=false,intIn=125}, + #'SetIn'{boolIn=false,intIn=225}]}, + #'Set4'{set41=[],set42=[], + set43=[#'SetIn'{boolIn=true,intIn=25}, + #'SetIn'{boolIn=false,intIn=125}, + #'SetIn'{boolIn=false,intIn=225}]}), + + roundtrip('SetOs', ["First","Second","Third"]), + roundtrip('SetOsImp', ["First","Second","Third"]), + roundtrip('SetOsExp', ["First","Second","Third"]), + roundtrip('SetEmp', #'SetEmp'{set1=[#'Empty'{}]}), - ?line {ok,Bytes11} = - asn1_wrapper:encode('SetOf','Set1',#'Set1'{bool1 = true, - int1 = 17}), - ?line {ok,{'Set1',true,17,[]}} = - asn1_wrapper:decode('SetOf','Set1',lists:flatten(Bytes11)), - - - ?line {ok,Bytes12} = - asn1_wrapper:encode('SetOf','Set1',#'Set1'{bool1 = true, - int1 = 17, - set1 = [#'SetIn'{boolIn = true, - intIn = 25}]}), - ?line {ok,{'Set1',true,17,[{'SetIn',true,25}]}} = - asn1_wrapper:decode('SetOf','Set1',lists:flatten(Bytes12)), - - - - ?line {ok,Bytes13} = - asn1_wrapper:encode('SetOf','Set1',#'Set1'{bool1 = true, - int1 = 17, - set1 = [#'SetIn'{boolIn = true, - intIn = 25}, - #'SetIn'{boolIn = false, - intIn = 125}, - #'SetIn'{boolIn = false, - intIn = 225}]}), - ?line {ok,{'Set1',true,17,[{'SetIn',true,25},{'SetIn',false,125},{'SetIn',false,225}]}} = - asn1_wrapper:decode('SetOf','Set1',lists:flatten(Bytes13)), - - - - - - - ?line {ok,Bytes21} = - asn1_wrapper:encode('SetOf','Set2',#'Set2'{bool2 = true, - int2 = 17}), - - ?line {ok,{'Set2',[],true,17}} = - asn1_wrapper:decode('SetOf','Set2',lists:flatten(Bytes21)), - - - ?line {ok,Bytes22} = - asn1_wrapper:encode('SetOf','Set2',#'Set2'{bool2 = true, - int2 = 17, - set2 = [#'SetIn'{boolIn = true, - intIn = 25}]}), - ?line {ok,{'Set2',[{'SetIn',true,25}],true,17}} = - asn1_wrapper:decode('SetOf','Set2',lists:flatten(Bytes22)), - - - ?line {ok,Bytes23} = - asn1_wrapper:encode('SetOf','Set2',#'Set2'{bool2 = true, - int2 = 17, - set2 = [#'SetIn'{boolIn = true, - intIn = 25}, - #'SetIn'{boolIn = false, - intIn = 125}, - #'SetIn'{boolIn = false, - intIn = 225}]}), - ?line {ok,{'Set2',[{'SetIn',true,25},{'SetIn',false,125},{'SetIn',false,225}],true,17}} = - asn1_wrapper:decode('SetOf','Set2',lists:flatten(Bytes23)), - - - - - - - ?line {ok,Bytes31} = - asn1_wrapper:encode('SetOf','Set3',#'Set3'{bool3 = true, - int3 = 17}), - ?line {ok,{'Set3',true,[],17}} = - asn1_wrapper:decode('SetOf','Set3',lists:flatten(Bytes31)), - - - ?line {ok,Bytes32} = - asn1_wrapper:encode('SetOf','Set3',#'Set3'{bool3 = true, - int3 = 17, - set3 = [#'SetIn'{boolIn = true, - intIn = 25}]}), - ?line {ok,{'Set3',true,[{'SetIn',true,25}],17}} = - asn1_wrapper:decode('SetOf','Set3',lists:flatten(Bytes32)), - - - ?line {ok,Bytes33} = - asn1_wrapper:encode('SetOf','Set3',#'Set3'{bool3 = true, - int3 = 17, - set3 = [#'SetIn'{boolIn = true, - intIn = 25}, - #'SetIn'{boolIn = false, - intIn = 125}, - #'SetIn'{boolIn = false, - intIn = 225}]}), - ?line {ok,{'Set3',true,[{'SetIn',true,25},{'SetIn',false,125},{'SetIn',false,225}],17}} = - asn1_wrapper:decode('SetOf','Set3',lists:flatten(Bytes33)), - - - - - - - - ?line {ok,Bytes41} = asn1_wrapper:encode('SetOf','Set4',#'Set4'{}), - ?line {ok,{'Set4',[],[],[]}} = asn1_wrapper:decode('SetOf','Set4',lists:flatten(Bytes41)), - - - ?line {ok,Bytes42} = - asn1_wrapper:encode('SetOf','Set4',#'Set4'{set41 = [#'SetIn'{boolIn = true, - intIn = 25}]}), - ?line {ok,{'Set4',[{'SetIn',true,25}],[],[]}} = - asn1_wrapper:decode('SetOf','Set4',lists:flatten(Bytes42)), - - - ?line {ok,Bytes43} = - asn1_wrapper:encode('SetOf','Set4',#'Set4'{set41 = [#'SetIn'{boolIn = true, - intIn = 25}, - #'SetIn'{boolIn = false, - intIn = 125}, - #'SetIn'{boolIn = false, - intIn = 225}]}), - ?line {ok,{'Set4',[{'SetIn',true,25},{'SetIn',false,125},{'SetIn',false,225}],[],[]}} = - asn1_wrapper:decode('SetOf','Set4',lists:flatten(Bytes43)), - - - ?line {ok,Bytes44} = - asn1_wrapper:encode('SetOf','Set4',#'Set4'{set42 = [#'SetIn'{boolIn = true, - intIn = 25}]}), - ?line {ok,{'Set4',[],[{'SetIn',true,25}],[]}} = - asn1_wrapper:decode('SetOf','Set4',lists:flatten(Bytes44)), - - - ?line {ok,Bytes45} = - asn1_wrapper:encode('SetOf','Set4',#'Set4'{set42 = [#'SetIn'{boolIn = true, - intIn = 25}, - #'SetIn'{boolIn = false, - intIn = 125}, - #'SetIn'{boolIn = false, - intIn = 225}]}), - ?line {ok,{'Set4',[],[{'SetIn',true,25},{'SetIn',false,125},{'SetIn',false,225}],[]}} = - asn1_wrapper:decode('SetOf','Set4',lists:flatten(Bytes45)), - - - ?line {ok,Bytes46} = - asn1_wrapper:encode('SetOf','Set4',#'Set4'{set43 = [#'SetIn'{boolIn = true, - intIn = 25}]}), - ?line {ok,{'Set4',[],[],[{'SetIn',true,25}]}} = - asn1_wrapper:decode('SetOf','Set4',lists:flatten(Bytes46)), - - - ?line {ok,Bytes47} = - asn1_wrapper:encode('SetOf','Set4',#'Set4'{set43 = [#'SetIn'{boolIn = true, - intIn = 25}, - #'SetIn'{boolIn = false, - intIn = 125}, - #'SetIn'{boolIn = false, - intIn = 225}]}), - ?line {ok,{'Set4',[],[],[{'SetIn',true,25},{'SetIn',false,125},{'SetIn',false,225}]}} = - asn1_wrapper:decode('SetOf','Set4',lists:flatten(Bytes47)), - - - - - ?line {ok,Bytes51} = asn1_wrapper:encode('SetOf','SetOs',["First","Second","Third"]), - ?line {ok,["First","Second","Third"]} = - asn1_wrapper:decode('SetOf','SetOs',lists:flatten(Bytes51)), - - ?line {ok,Bytes52} = asn1_wrapper:encode('SetOf','SetOsImp',["First","Second","Third"]), - ?line {ok,["First","Second","Third"]} = - asn1_wrapper:decode('SetOf','SetOsImp',lists:flatten(Bytes52)), - - ?line {ok,Bytes53} = asn1_wrapper:encode('SetOf','SetOsExp',["First","Second","Third"]), - ?line {ok,["First","Second","Third"]} = - asn1_wrapper:decode('SetOf','SetOsExp',lists:flatten(Bytes53)), - - - - - - - - ?line {ok,Bytes71} = asn1_wrapper:encode('SetOf','SetEmp',#'SetEmp'{set1 = [#'Empty'{}]}), - ?line {ok,{'SetEmp',[{'Empty'}]}} = asn1_wrapper:decode('SetOf','SetEmp',lists:flatten(Bytes71)), - ok. +roundtrip(T, V) -> + roundtrip(T, V, V). + +roundtrip(Type, Value, ExpectedValue) -> + asn1_test_lib:roundtrip('SetOf', Type, Value, ExpectedValue). diff --git a/lib/asn1/test/testSetOfCho.erl b/lib/asn1/test/testSetOfCho.erl index c89bf9596e..09c075e468 100644 --- a/lib/asn1/test/testSetOfCho.erl +++ b/lib/asn1/test/testSetOfCho.erl @@ -30,120 +30,46 @@ -record('SetOfChoEmbDef_SETOF',{bool1, int1, set1 = asn1_DEFAULT}). -record('SetOfChoEmbOpt_SETOF',{bool1, int1, set1 = asn1_NOVALUE}). +main(_Rules) -> + roundtrip('SetChoDef', + #'SetChoDef'{bool1=true,int1=17,set1=asn1_DEFAULT}, + #'SetChoDef'{bool1=true,int1=17,set1=[]}), + roundtrip('SetChoDef', + #'SetChoDef'{bool1=true,int1=17,set1=[{boolIn,true},{intIn,25}]}), + roundtrip('SetChoOpt', + #'SetChoOpt'{bool1=true,int1=17,set1=asn1_NOVALUE}), + roundtrip('SetChoOpt', + #'SetChoOpt'{bool1=true,int1=17,set1=[{boolIn,true},{intIn,25}]}), + roundtrip('SetChoEmbDef', + #'SetChoEmbDef'{bool1=true,int1=17,set1=asn1_DEFAULT}, + #'SetChoEmbDef'{bool1=true,int1=17,set1=[]}), + roundtrip('SetChoEmbDef', + #'SetChoEmbDef'{bool1=true,int1=17, + set1=[{boolIn,true},{intIn,25}]}), + roundtrip('SetChoEmbOpt', + #'SetChoEmbOpt'{bool1=true,int1=17,set1=asn1_NOVALUE}), + roundtrip('SetChoEmbOpt', + #'SetChoEmbOpt'{bool1=true,int1=17, + set1=[{boolIn,true},{intIn,25}]}), + + roundtrip('SetOfChoEmbDef', + [#'SetOfChoEmbDef_SETOF'{bool1=true,int1=17,set1=asn1_DEFAULT}], + [#'SetOfChoEmbDef_SETOF'{bool1=true,int1=17,set1=[]}]), + roundtrip('SetOfChoEmbDef', + [#'SetOfChoEmbDef_SETOF'{bool1=true,int1=17, + set1=[{boolIn,true},{intIn,25}]}]), + + roundtrip('SetOfChoEmbOpt', + [#'SetOfChoEmbOpt_SETOF'{bool1=true,int1=17,set1=asn1_NOVALUE}]), + roundtrip('SetOfChoEmbOpt', + [#'SetOfChoEmbOpt_SETOF'{bool1=true,int1=17, + set1=[{boolIn,true},{intIn,25}]}]), -main(_Rules) -> - - ?line {ok,Bytes11} = - asn1_wrapper:encode('SetOfCho','SetChoDef',#'SetChoDef'{bool1 = true, - int1 = 17}), - ?line {ok,{'SetChoDef',true,17,[]}} = - asn1_wrapper:decode('SetOfCho','SetChoDef',lists:flatten(Bytes11)), - - - ?line {ok,Bytes12} = - asn1_wrapper:encode('SetOfCho','SetChoDef',#'SetChoDef'{bool1 = true, - int1 = 17, - set1 = [{boolIn,true}, - {intIn,25}]}), - ?line {ok,{'SetChoDef',true,17,[{boolIn,true},{intIn,25}]}} = - asn1_wrapper:decode('SetOfCho','SetChoDef',lists:flatten(Bytes12)), - - - - ?line {ok,Bytes15} = - asn1_wrapper:encode('SetOfCho','SetChoOpt',#'SetChoOpt'{bool1 = true, - int1 = 17}), - ?line {ok,{'SetChoOpt',true,17,asn1_NOVALUE}} = - asn1_wrapper:decode('SetOfCho','SetChoOpt',lists:flatten(Bytes15)), - - - ?line {ok,Bytes16} = - asn1_wrapper:encode('SetOfCho','SetChoOpt',#'SetChoOpt'{bool1 = true, - int1 = 17, - set1 = [{boolIn,true}, - {intIn,25}]}), - ?line {ok,{'SetChoOpt',true,17,[{boolIn,true},{intIn,25}]}} = - asn1_wrapper:decode('SetOfCho','SetChoOpt',lists:flatten(Bytes16)), - - - - - - ?line {ok,Bytes21} = - asn1_wrapper:encode('SetOfCho','SetChoEmbDef',#'SetChoEmbDef'{bool1 = true, - int1 = 17}), - ?line {ok,{'SetChoEmbDef',true,17,[]}} = - asn1_wrapper:decode('SetOfCho','SetChoEmbDef',lists:flatten(Bytes21)), - - - ?line {ok,Bytes22} = - asn1_wrapper:encode('SetOfCho','SetChoEmbDef',#'SetChoEmbDef'{bool1 = true, - int1 = 17, - set1 = [{boolIn,true}, - {intIn,25}]}), - ?line {ok,{'SetChoEmbDef',true,17,[{boolIn,true},{intIn,25}]}} = - asn1_wrapper:decode('SetOfCho','SetChoEmbDef',lists:flatten(Bytes22)), - - - - ?line {ok,Bytes25} = - asn1_wrapper:encode('SetOfCho','SetChoEmbOpt',#'SetChoEmbOpt'{bool1 = true, - int1 = 17}), - ?line {ok,{'SetChoEmbOpt',true,17,asn1_NOVALUE}} = - asn1_wrapper:decode('SetOfCho','SetChoEmbOpt',lists:flatten(Bytes25)), - - - ?line {ok,Bytes26} = - asn1_wrapper:encode('SetOfCho','SetChoEmbOpt',#'SetChoEmbOpt'{bool1 = true, - int1 = 17, - set1 = [{boolIn,true}, - {intIn,25}]}), - ?line {ok,{'SetChoEmbOpt',true,17,[{boolIn,true},{intIn,25}]}} = - asn1_wrapper:decode('SetOfCho','SetChoEmbOpt',lists:flatten(Bytes26)), - - - - - - - ?line {ok,Bytes31} = - asn1_wrapper:encode('SetOfCho','SetOfChoEmbDef',[#'SetOfChoEmbDef_SETOF'{bool1 = true, - int1 = 17}]), - ?line {ok,[{'SetOfChoEmbDef_SETOF',true,17,[]}]} = - asn1_wrapper:decode('SetOfCho','SetOfChoEmbDef',lists:flatten(Bytes31)), - - - ?line {ok,Bytes32} = - asn1_wrapper:encode('SetOfCho','SetOfChoEmbDef', - [#'SetOfChoEmbDef_SETOF'{bool1 = true, - int1 = 17, - set1 = [{boolIn,true}, - {intIn,25}]}]), - ?line {ok,[{'SetOfChoEmbDef_SETOF',true,17,[{boolIn,true},{intIn,25}]}]} = - asn1_wrapper:decode('SetOfCho','SetOfChoEmbDef',lists:flatten(Bytes32)), - - - - ?line {ok,Bytes35} = - asn1_wrapper:encode('SetOfCho','SetOfChoEmbOpt',[#'SetOfChoEmbOpt_SETOF'{bool1 = true, - int1 = 17}]), - ?line {ok,[{'SetOfChoEmbOpt_SETOF',true,17,asn1_NOVALUE}]} = - asn1_wrapper:decode('SetOfCho','SetOfChoEmbOpt',lists:flatten(Bytes35)), - - - ?line {ok,Bytes36} = - asn1_wrapper:encode('SetOfCho','SetOfChoEmbOpt', - [#'SetOfChoEmbOpt_SETOF'{bool1 = true, - int1 = 17, - set1 = [{boolIn,true}, - {intIn,25}]}]), - ?line {ok,[{'SetOfChoEmbOpt_SETOF',true,17,[{boolIn,true},{intIn,25}]}]} = - asn1_wrapper:decode('SetOfCho','SetOfChoEmbOpt',lists:flatten(Bytes36)), - - - - ok. +roundtrip(T, V) -> + roundtrip(T, V, V). +roundtrip(Type, Value, ExpectedValue) -> + asn1_test_lib:roundtrip('SetOfCho', Type, Value, ExpectedValue). diff --git a/lib/asn1/test/testSetOfExternal.erl b/lib/asn1/test/testSetOfExternal.erl index 6b280a2595..a380ba5ac1 100644 --- a/lib/asn1/test/testSetOfExternal.erl +++ b/lib/asn1/test/testSetOfExternal.erl @@ -18,8 +18,6 @@ %% %% -module(testSetOfExternal). - - -export([main/1]). -include_lib("test_server/include/test_server.hrl"). @@ -29,133 +27,26 @@ -record('Imp',{os, bool}). -record('Exp',{os, bool}). - - main(_Rules) -> - - ?line {ok,Bytes11} = - asn1_wrapper:encode('SetOfExternal','NTNT',[#'NT'{bool = true, os = "kalle"}, - #'NT'{bool = true, os = "kalle"}]), - ?line {ok,[{'NT',[107,97,108,108,101],true},{'NT',[107,97,108,108,101],true}]} = - asn1_wrapper:decode('SetOfExternal','NTNT',lists:flatten(Bytes11)), - - ?line {ok,Bytes12} = - asn1_wrapper:encode('SetOfExternal','ImpNT',[#'NT'{bool = true, os = "kalle"}, - #'NT'{bool = true, os = "kalle"}]), - ?line {ok,[{'NT',[107,97,108,108,101],true},{'NT',[107,97,108,108,101],true}]} = - asn1_wrapper:decode('SetOfExternal','ImpNT',lists:flatten(Bytes12)), - - ?line {ok,Bytes13} = - asn1_wrapper:encode('SetOfExternal','ExpNT',[#'NT'{bool = true, os = "kalle"}, - #'NT'{bool = true, os = "kalle"}]), - ?line {ok,[{'NT',[107,97,108,108,101],true},{'NT',[107,97,108,108,101],true}]} = - asn1_wrapper:decode('SetOfExternal','ExpNT',lists:flatten(Bytes13)), - - - - ?line {ok,Bytes21} = - asn1_wrapper:encode('SetOfExternal','NTImp',[#'Imp'{bool = true, os = "kalle"}, - #'Imp'{bool = true, os = "kalle"}]), - ?line {ok,[{'Imp',[107,97,108,108,101],true},{'Imp',[107,97,108,108,101],true}]} = - asn1_wrapper:decode('SetOfExternal','NTImp',lists:flatten(Bytes21)), - - ?line {ok,Bytes22} = - asn1_wrapper:encode('SetOfExternal','ImpImp',[#'Imp'{bool = true, os = "kalle"}, - #'Imp'{bool = true, os = "kalle"}]), - ?line {ok,[{'Imp',[107,97,108,108,101],true},{'Imp',[107,97,108,108,101],true}]} = - asn1_wrapper:decode('SetOfExternal','ImpImp',lists:flatten(Bytes22)), - - ?line {ok,Bytes23} = - asn1_wrapper:encode('SetOfExternal','ExpImp',[#'Imp'{bool = true, os = "kalle"}, - #'Imp'{bool = true, os = "kalle"}]), - ?line {ok,[{'Imp',[107,97,108,108,101],true},{'Imp',[107,97,108,108,101],true}]} = - asn1_wrapper:decode('SetOfExternal','ExpImp',lists:flatten(Bytes23)), - - - - ?line {ok,Bytes31} = - asn1_wrapper:encode('SetOfExternal','NTExp',[#'Exp'{bool = true, os = "kalle"}, - #'Exp'{bool = true, os = "kalle"}]), - ?line {ok,[{'Exp',[107,97,108,108,101],true},{'Exp',[107,97,108,108,101],true}]} = - asn1_wrapper:decode('SetOfExternal','NTExp',lists:flatten(Bytes31)), - - ?line {ok,Bytes32} = - asn1_wrapper:encode('SetOfExternal','ImpExp',[#'Exp'{bool = true, os = "kalle"}, - #'Exp'{bool = true, os = "kalle"}]), - ?line {ok,[{'Exp',[107,97,108,108,101],true},{'Exp',[107,97,108,108,101],true}]} = - asn1_wrapper:decode('SetOfExternal','ImpExp',lists:flatten(Bytes32)), - - ?line {ok,Bytes33} = - asn1_wrapper:encode('SetOfExternal','ExpExp',[#'Exp'{bool = true, os = "kalle"}, - #'Exp'{bool = true, os = "kalle"}]), - ?line {ok,[{'Exp',[107,97,108,108,101],true},{'Exp',[107,97,108,108,101],true}]} = - asn1_wrapper:decode('SetOfExternal','ExpExp',lists:flatten(Bytes33)), - - - - - - - - ?line {ok,Bytes41} = - asn1_wrapper:encode('SetOfExternal','XNTNT',[#'XSetNT'{bool = true, os = "kalle"}, - #'XSetNT'{bool = true, os = "kalle"}]), - ?line {ok,[{'XSetNT',[107,97,108,108,101],true},{'XSetNT',[107,97,108,108,101],true}]} = - asn1_wrapper:decode('SetOfExternal','XNTNT',lists:flatten(Bytes41)), - - ?line {ok,Bytes42} = - asn1_wrapper:encode('SetOfExternal','XImpNT',[#'XSetNT'{bool = true, os = "kalle"}, - #'XSetNT'{bool = true, os = "kalle"}]), - ?line {ok,[{'XSetNT',[107,97,108,108,101],true},{'XSetNT',[107,97,108,108,101],true}]} = - asn1_wrapper:decode('SetOfExternal','XImpNT',lists:flatten(Bytes42)), - - ?line {ok,Bytes43} = - asn1_wrapper:encode('SetOfExternal','XExpNT',[#'XSetNT'{bool = true, os = "kalle"}, - #'XSetNT'{bool = true, os = "kalle"}]), - ?line {ok,[{'XSetNT',[107,97,108,108,101],true},{'XSetNT',[107,97,108,108,101],true}]} = - asn1_wrapper:decode('SetOfExternal','XExpNT',lists:flatten(Bytes43)), - - - - ?line {ok,Bytes51} = - asn1_wrapper:encode('SetOfExternal','XNTImp',[#'XSetImp'{bool = true, os = "kalle"}, - #'XSetImp'{bool = true, os = "kalle"}]), - ?line {ok,[{'XSetImp',[107,97,108,108,101],true},{'XSetImp',[107,97,108,108,101],true}]} = - asn1_wrapper:decode('SetOfExternal','XNTImp',lists:flatten(Bytes51)), - - ?line {ok,Bytes52} = - asn1_wrapper:encode('SetOfExternal','XImpImp',[#'XSetImp'{bool = true, os = "kalle"}, - #'XSetImp'{bool = true, os = "kalle"}]), - ?line {ok,[{'XSetImp',[107,97,108,108,101],true},{'XSetImp',[107,97,108,108,101],true}]} = - asn1_wrapper:decode('SetOfExternal','XImpImp',lists:flatten(Bytes52)), - - ?line {ok,Bytes53} = - asn1_wrapper:encode('SetOfExternal','XExpImp',[#'XSetImp'{bool = true, os = "kalle"}, - #'XSetImp'{bool = true, os = "kalle"}]), - ?line {ok,[{'XSetImp',[107,97,108,108,101],true},{'XSetImp',[107,97,108,108,101],true}]} = - asn1_wrapper:decode('SetOfExternal','XExpImp',lists:flatten(Bytes53)), - - - - ?line {ok,Bytes61} = - asn1_wrapper:encode('SetOfExternal','XNTExp',[#'XSetExp'{bool = true, os = "kalle"}, - #'XSetExp'{bool = true, os = "kalle"}]), - ?line {ok,[{'XSetExp',[107,97,108,108,101],true},{'XSetExp',[107,97,108,108,101],true}]} = - asn1_wrapper:decode('SetOfExternal','XNTExp',lists:flatten(Bytes61)), - - ?line {ok,Bytes62} = - asn1_wrapper:encode('SetOfExternal','XImpExp',[#'XSetExp'{bool = true, os = "kalle"}, - #'XSetExp'{bool = true, os = "kalle"}]), - ?line {ok,[{'XSetExp',[107,97,108,108,101],true},{'XSetExp',[107,97,108,108,101],true}]} = - asn1_wrapper:decode('SetOfExternal','XImpExp',lists:flatten(Bytes62)), - - ?line {ok,Bytes63} = - asn1_wrapper:encode('SetOfExternal','XExpExp',[#'XSetExp'{bool = true, os = "kalle"}, - #'XSetExp'{bool = true, os = "kalle"}]), - ?line {ok,[{'XSetExp',[107,97,108,108,101],true},{'XSetExp',[107,97,108,108,101],true}]} = - asn1_wrapper:decode('SetOfExternal','XExpExp',lists:flatten(Bytes63)), - - - - + roundtrip('NTNT', [#'NT'{os="kalle",bool=true},#'NT'{os="kalle",bool=true}]), + roundtrip('ImpNT', [#'NT'{os="kalle",bool=true},#'NT'{os="kalle",bool=true}]), + roundtrip('ExpNT', [#'NT'{os="kalle",bool=true},#'NT'{os="kalle",bool=true}]), + roundtrip('NTImp', [#'Imp'{os="kalle",bool=true},#'Imp'{os="kalle",bool=true}]), + roundtrip('ImpImp', [#'Imp'{os="kalle",bool=true},#'Imp'{os="kalle",bool=true}]), + roundtrip('ExpImp', [#'Imp'{os="kalle",bool=true},#'Imp'{os="kalle",bool=true}]), + roundtrip('NTExp', [#'Exp'{os="kalle",bool=true},#'Exp'{os="kalle",bool=true}]), + roundtrip('ImpExp', [#'Exp'{os="kalle",bool=true},#'Exp'{os="kalle",bool=true}]), + roundtrip('ExpExp', [#'Exp'{os="kalle",bool=true},#'Exp'{os="kalle",bool=true}]), + roundtrip('XNTNT', [#'XSetNT'{os="kalle",bool=true},#'XSetNT'{os="kalle",bool=true}]), + roundtrip('XImpNT', [#'XSetNT'{os="kalle",bool=true},#'XSetNT'{os="kalle",bool=true}]), + roundtrip('XExpNT', [#'XSetNT'{os="kalle",bool=true},#'XSetNT'{os="kalle",bool=true}]), + roundtrip('XNTImp', [#'XSetImp'{os="kalle",bool=true},#'XSetImp'{os="kalle",bool=true}]), + roundtrip('XImpImp', [#'XSetImp'{os="kalle",bool=true},#'XSetImp'{os="kalle",bool=true}]), + roundtrip('XExpImp', [#'XSetImp'{os="kalle",bool=true},#'XSetImp'{os="kalle",bool=true}]), + roundtrip('XNTExp', [#'XSetExp'{os="kalle",bool=true},#'XSetExp'{os="kalle",bool=true}]), + roundtrip('XImpExp', [#'XSetExp'{os="kalle",bool=true},#'XSetExp'{os="kalle",bool=true}]), + roundtrip('XExpExp', [#'XSetExp'{os="kalle",bool=true},#'XSetExp'{os="kalle",bool=true}]), ok. + +roundtrip(T, V) -> + asn1_test_lib:roundtrip('SetOfExternal', T, V). diff --git a/lib/asn1/test/testSetOfTag.erl b/lib/asn1/test/testSetOfTag.erl index 2c7a2f5473..81bc467abb 100644 --- a/lib/asn1/test/testSetOfTag.erl +++ b/lib/asn1/test/testSetOfTag.erl @@ -18,14 +18,11 @@ %% %% -module(testSetOfTag). - - -export([main/1]). -include_lib("test_server/include/test_server.hrl"). -include("External.hrl"). - -record('SetTagNt',{nt}). -record('SetTagNtI',{imp}). -record('SetTagNtE',{exp}). @@ -44,148 +41,44 @@ -record('Imp',{os, bool}). -record('Exp',{os, bool}). - - main(_Rules) -> - - ?line {ok,Bytes11} = - asn1_wrapper:encode('SetOfTag','SetTagNt', - #'SetTagNt'{nt = [#'NT'{bool = true, os = "kalle"}, - #'NT'{bool = true, os = "kalle"}]}), - ?line {ok,{'SetTagNt', - [{'NT',[107,97,108,108,101],true},{'NT',[107,97,108,108,101],true}]}} = - asn1_wrapper:decode('SetOfTag','SetTagNt',lists:flatten(Bytes11)), - - ?line {ok,Bytes12} = - asn1_wrapper:encode('SetOfTag','SetTagNtI', - #'SetTagNtI'{imp = [#'Imp'{bool = true, os = "kalle"}, - #'Imp'{bool = true, os = "kalle"}]}), - ?line {ok,{'SetTagNtI', - [{'Imp',[107,97,108,108,101],true},{'Imp',[107,97,108,108,101],true}]}} = - asn1_wrapper:decode('SetOfTag','SetTagNtI',lists:flatten(Bytes12)), - - ?line {ok,Bytes13} = - asn1_wrapper:encode('SetOfTag','SetTagNtE', - #'SetTagNtE'{exp = [#'Exp'{bool = true, os = "kalle"}, - #'Exp'{bool = true, os = "kalle"}]}), - ?line {ok,{'SetTagNtE', - [{'Exp',[107,97,108,108,101],true},{'Exp',[107,97,108,108,101],true}]}} = - asn1_wrapper:decode('SetOfTag','SetTagNtE',lists:flatten(Bytes13)), - - - - ?line {ok,Bytes21} = - asn1_wrapper:encode('SetOfTag','SetTagI', - #'SetTagI'{nt = [#'NT'{bool = true, os = "kalle"}, - #'NT'{bool = true, os = "kalle"}]}), - ?line {ok,{'SetTagI', - [{'NT',[107,97,108,108,101],true},{'NT',[107,97,108,108,101],true}]}} = - asn1_wrapper:decode('SetOfTag','SetTagI',lists:flatten(Bytes21)), - - ?line {ok,Bytes22} = - asn1_wrapper:encode('SetOfTag','SetTagII', - #'SetTagII'{imp = [#'Imp'{bool = true, os = "kalle"}, - #'Imp'{bool = true, os = "kalle"}]}), - ?line {ok,{'SetTagII', - [{'Imp',[107,97,108,108,101],true},{'Imp',[107,97,108,108,101],true}]}} = - asn1_wrapper:decode('SetOfTag','SetTagII',lists:flatten(Bytes22)), - - ?line {ok,Bytes23} = - asn1_wrapper:encode('SetOfTag','SetTagIE', - #'SetTagIE'{exp = [#'Exp'{bool = true, os = "kalle"}, - #'Exp'{bool = true, os = "kalle"}]}), - ?line {ok,{'SetTagIE', - [{'Exp',[107,97,108,108,101],true},{'Exp',[107,97,108,108,101],true}]}} = - asn1_wrapper:decode('SetOfTag','SetTagIE',lists:flatten(Bytes23)), - - - - ?line {ok,Bytes31} = - asn1_wrapper:encode('SetOfTag','SetTagE', - #'SetTagE'{nt = [#'NT'{bool = true, os = "kalle"}, - #'NT'{bool = true, os = "kalle"}]}), - ?line {ok,{'SetTagE', - [{'NT',[107,97,108,108,101],true},{'NT',[107,97,108,108,101],true}]}} = - asn1_wrapper:decode('SetOfTag','SetTagE',lists:flatten(Bytes31)), - - ?line {ok,Bytes32} = - asn1_wrapper:encode('SetOfTag','SetTagEI', - #'SetTagEI'{imp = [#'Imp'{bool = true, os = "kalle"}, - #'Imp'{bool = true, os = "kalle"}]}), - ?line {ok,{'SetTagEI', - [{'Imp',[107,97,108,108,101],true},{'Imp',[107,97,108,108,101],true}]}} = - asn1_wrapper:decode('SetOfTag','SetTagEI',lists:flatten(Bytes32)), - - ?line {ok,Bytes33} = - asn1_wrapper:encode('SetOfTag','SetTagEE', - #'SetTagEE'{exp = [#'Exp'{bool = true, os = "kalle"}, - #'Exp'{bool = true, os = "kalle"}]}), - ?line {ok,{'SetTagEE', - [{'Exp',[107,97,108,108,101],true},{'Exp',[107,97,108,108,101],true}]}} = - asn1_wrapper:decode('SetOfTag','SetTagEE',lists:flatten(Bytes33)), - - - - - - - - ?line {ok,Bytes41} = - asn1_wrapper:encode('SetOfTag','SetTagXNt', - #'SetTagXNt'{xnt = [#'XSetNT'{bool = true, os = "kalle"}, - #'XSetNT'{bool = true, os = "kalle"}]}), - ?line {ok,{'SetTagXNt', - [{'XSetNT',[107,97,108,108,101],true},{'XSetNT',[107,97,108,108,101],true}]}} = - asn1_wrapper:decode('SetOfTag','SetTagXNt',lists:flatten(Bytes41)), - - ?line {ok,Bytes42} = - asn1_wrapper:encode('SetOfTag','SetTagXI', - #'SetTagXI'{ximp = [#'XSetImp'{bool = true, os = "kalle"}, - #'XSetImp'{bool = true, os = "kalle"}]}), - ?line {ok,{'SetTagXI', - [{'XSetImp',[107,97,108,108,101],true},{'XSetImp',[107,97,108,108,101],true}]}} = - asn1_wrapper:decode('SetOfTag','SetTagXI',lists:flatten(Bytes42)), - - ?line {ok,Bytes43} = - asn1_wrapper:encode('SetOfTag','SetTagXE', - #'SetTagXE'{xexp = [#'XSetExp'{bool = true, os = "kalle"}, - #'XSetExp'{bool = true, os = "kalle"}]}), - ?line {ok,{'SetTagXE', - [{'XSetExp',[107,97,108,108,101],true},{'XSetExp',[107,97,108,108,101],true}]}} = - asn1_wrapper:decode('SetOfTag','SetTagXE',lists:flatten(Bytes43)), - - - - - - ?line {ok,Bytes51} = - asn1_wrapper:encode('SetOfTag','SetTagImpX', - #'SetTagImpX'{xnt = [#'XSetNT'{bool = true, os = "kalle"}, - #'XSetNT'{bool = true, os = "kalle"}], - ximp = [#'XSetImp'{bool = true, os = "kalle"}, - #'XSetImp'{bool = true, os = "kalle"}], - xexp = [#'XSetExp'{bool = true, os = "kalle"}, - #'XSetExp'{bool = true, os = "kalle"}]}), - ?line {ok,{'SetTagImpX', - [{'XSetNT',[107,97,108,108,101],true},{'XSetNT',[107,97,108,108,101],true}], - [{'XSetImp',[107,97,108,108,101],true},{'XSetImp',[107,97,108,108,101],true}], - [{'XSetExp',[107,97,108,108,101],true},{'XSetExp',[107,97,108,108,101],true}]}} = - asn1_wrapper:decode('SetOfTag','SetTagImpX',lists:flatten(Bytes51)), - - - - ?line {ok,Bytes52} = - asn1_wrapper:encode('SetOfTag','SetTagExpX', - #'SetTagExpX'{xnt = [#'XSetNT'{bool = true, os = "kalle"}, - #'XSetNT'{bool = true, os = "kalle"}], - ximp = [#'XSetImp'{bool = true, os = "kalle"}, - #'XSetImp'{bool = true, os = "kalle"}], - xexp = [#'XSetExp'{bool = true, os = "kalle"}, - #'XSetExp'{bool = true, os = "kalle"}]}), - ?line {ok,{'SetTagExpX', - [{'XSetNT',[107,97,108,108,101],true},{'XSetNT',[107,97,108,108,101],true}], - [{'XSetImp',[107,97,108,108,101],true},{'XSetImp',[107,97,108,108,101],true}], - [{'XSetExp',[107,97,108,108,101],true},{'XSetExp',[107,97,108,108,101],true}]}} = - asn1_wrapper:decode('SetOfTag','SetTagExpX',lists:flatten(Bytes52)), - + roundtrip('SetTagNt', #'SetTagNt'{nt=[#'NT'{os="kalle",bool=true}, + #'NT'{os="kalle",bool=true}]}), + roundtrip('SetTagNtI', #'SetTagNtI'{imp=[#'Imp'{os="kalle",bool=true}, + #'Imp'{os="kalle",bool=true}]}), + roundtrip('SetTagNtE', #'SetTagNtE'{exp=[#'Exp'{os="kalle",bool=true}, + #'Exp'{os="kalle",bool=true}]}), + roundtrip('SetTagI', #'SetTagI'{nt=[#'NT'{os="kalle",bool=true}, + #'NT'{os="kalle",bool=true}]}), + roundtrip('SetTagII', #'SetTagII'{imp=[#'Imp'{os="kalle",bool=true}, + #'Imp'{os="kalle",bool=true}]}), + roundtrip('SetTagIE', #'SetTagIE'{exp=[#'Exp'{os="kalle",bool=true}, + #'Exp'{os="kalle",bool=true}]}), + roundtrip('SetTagE', #'SetTagE'{nt=[#'NT'{os="kalle",bool=true}, + #'NT'{os="kalle",bool=true}]}), + roundtrip('SetTagEI', #'SetTagEI'{imp=[#'Imp'{os="kalle",bool=true}, + #'Imp'{os="kalle",bool=true}]}), + roundtrip('SetTagEE', #'SetTagEE'{exp=[#'Exp'{os="kalle",bool=true}, + #'Exp'{os="kalle",bool=true}]}), + roundtrip('SetTagXNt', #'SetTagXNt'{xnt=[#'XSetNT'{os="kalle",bool=true}, + #'XSetNT'{os="kalle",bool=true}]}), + roundtrip('SetTagXI', #'SetTagXI'{ximp=[#'XSetImp'{os="kalle",bool=true}, + #'XSetImp'{os="kalle",bool=true}]}), + roundtrip('SetTagXE', #'SetTagXE'{xexp=[#'XSetExp'{os="kalle",bool=true}, + #'XSetExp'{os="kalle",bool=true}]}), + roundtrip('SetTagImpX', #'SetTagImpX'{xnt=[#'XSetNT'{os="kalle",bool=true}, + #'XSetNT'{os="kalle",bool=true}], + ximp=[#'XSetImp'{os="kalle",bool=true}, + #'XSetImp'{os="kalle",bool=true}], + xexp=[#'XSetExp'{os="kalle",bool=true}, + #'XSetExp'{os="kalle",bool=true}]}), + roundtrip('SetTagExpX', #'SetTagExpX'{xnt=[#'XSetNT'{os="kalle",bool=true}, + #'XSetNT'{os="kalle",bool=true}], + ximp=[#'XSetImp'{os="kalle",bool=true}, + #'XSetImp'{os="kalle",bool=true}], + xexp=[#'XSetExp'{os="kalle",bool=true}, + #'XSetExp'{os="kalle",bool=true}]}), ok. + +roundtrip(T, V) -> + asn1_test_lib:roundtrip('SetOfTag', T, V). diff --git a/lib/asn1/test/testSetOptional.erl b/lib/asn1/test/testSetOptional.erl index bb43ff0a96..eb095fd480 100644 --- a/lib/asn1/test/testSetOptional.erl +++ b/lib/asn1/test/testSetOptional.erl @@ -93,6 +93,4 @@ ticket_7533(_) -> ok. roundtrip(Type, Value) -> - {ok,Encoded} = 'SetOptional':encode(Type, Value), - {ok,Value} = 'SetOptional':decode(Type, Encoded), - ok. + asn1_test_lib:roundtrip('SetOptional', Type, Value). diff --git a/lib/asn1/test/testSetPrim.erl b/lib/asn1/test/testSetPrim.erl index 3234b65135..f417f343a7 100644 --- a/lib/asn1/test/testSetPrim.erl +++ b/lib/asn1/test/testSetPrim.erl @@ -27,59 +27,17 @@ -record('Empty',{}). main(_Rules) -> - - - - ?line {ok,Bytes11} = - asn1_wrapper:encode('SetPrim','Set',#'Set'{bool = true, - boolCon = true, - boolPri = true, - boolApp = true, - boolExpCon = true, - boolExpPri = true, - boolExpApp = true}), - ?line {ok,{'Set',true,true,true,true,true,true,true}} = - asn1_wrapper:decode('SetPrim','Set',lists:flatten(Bytes11)), - - - - - ?line {ok,Bytes12} = - asn1_wrapper:encode('SetPrim','Set',#'Set'{bool = false, - boolCon = false, - boolPri = false, - boolApp = false, - boolExpCon = false, - boolExpPri = false, - boolExpApp = false}), - ?line {ok,{'Set',false,false,false,false,false,false,false}} = - asn1_wrapper:decode('SetPrim','Set',lists:flatten(Bytes12)), - - - - - ?line {ok,Bytes13} = - asn1_wrapper:encode('SetPrim','Set',#'Set'{bool = false, - boolCon = true, - boolPri = false, - boolApp = true, - boolExpCon = false, - boolExpPri = true, - boolExpApp = false}), - ?line {ok,{'Set',false,true,false,true,false,true,false}} = - asn1_wrapper:decode('SetPrim','Set',lists:flatten(Bytes13)), - - - - - - ?line {ok,Bytes21} = - asn1_wrapper:encode('SetPrim','Empty',#'Empty'{}), - ?line {ok,{'Empty'}} = - asn1_wrapper:decode('SetPrim','Empty',lists:flatten(Bytes21)), - - - + roundtrip('Set', + #'Set'{bool=true,boolCon=true,boolPri=true,boolApp=true, + boolExpCon=true,boolExpPri=true,boolExpApp=true}), + roundtrip('Set', + #'Set'{bool=false,boolCon=false,boolPri=false,boolApp=false, + boolExpCon=false,boolExpPri=false,boolExpApp=false}), + roundtrip('Set', + #'Set'{bool=false,boolCon=true,boolPri=false,boolApp=true, + boolExpCon=false,boolExpPri=true,boolExpApp=false}), + roundtrip('Empty', #'Empty'{}), ok. - +roundtrip(T, V) -> + asn1_test_lib:roundtrip('SetPrim', T, V). diff --git a/lib/asn1/test/testSetTag.erl b/lib/asn1/test/testSetTag.erl index 8b9364d603..5863a149b9 100644 --- a/lib/asn1/test/testSetTag.erl +++ b/lib/asn1/test/testSetTag.erl @@ -18,7 +18,6 @@ %% %% -module(testSetTag). - -export([main/1]). -include_lib("test_server/include/test_server.hrl"). @@ -35,69 +34,25 @@ -record('Exp',{os, bool}). main(_Rules) -> - - - ?line {ok,Bytes11} = - asn1_wrapper:encode('SetTag','SetTag',#'SetTag'{nt = #'NT'{bool = true, os = "kalle"}, - imp = #'Imp'{bool = true, os = "kalle"}, - exp = #'Exp'{bool = true, os = "kalle"}}), - ?line {ok,{'SetTag',{'NT',"kalle",true},{'Imp',"kalle",true},{'Exp',"kalle",true}}} = - asn1_wrapper:decode('SetTag','SetTag',lists:flatten(Bytes11)), - - - ?line {ok,Bytes12} = - asn1_wrapper:encode('SetTag','SetTagImp',#'SetTagImp'{nt = #'NT'{bool = true, os = "kalle"}, - imp = #'Imp'{bool = true, os = "kalle"}, - exp = #'Exp'{bool = true, os = "kalle"}}), - ?line {ok,{'SetTagImp',{'NT',"kalle",true},{'Imp',"kalle",true},{'Exp',"kalle",true}}} = - asn1_wrapper:decode('SetTag','SetTagImp',lists:flatten(Bytes12)), - - - ?line {ok,Bytes13} = - asn1_wrapper:encode('SetTag','SetTagExp',#'SetTagExp'{nt = #'NT'{bool = true, os = "kalle"}, - imp = #'Imp'{bool = true, os = "kalle"}, - exp = #'Exp'{bool = true, os = "kalle"}}), - ?line {ok,{'SetTagExp',{'NT',"kalle",true},{'Imp',"kalle",true},{'Exp',"kalle",true}}} = - asn1_wrapper:decode('SetTag','SetTagExp',lists:flatten(Bytes13)), - - - - - - ?line {ok,Bytes21} = - asn1_wrapper:encode('SetTag','SetTagX', - #'SetTagX'{xnt = #'XSetNT'{bool = true, os = "kalle"}, - ximp = #'XSetImp'{bool = true, os = "kalle"}, - xexp = #'XSetExp'{bool = true, os = "kalle"}}), - ?line {ok,{'SetTagX',{'XSetNT',"kalle",true}, - {'XSetImp',"kalle",true}, - {'XSetExp',"kalle",true}}} = - asn1_wrapper:decode('SetTag','SetTagX',lists:flatten(Bytes21)), - - - ?line {ok,Bytes22} = - asn1_wrapper:encode('SetTag','SetTagImpX', - #'SetTagImpX'{xnt = #'XSetNT'{bool = true, os = "kalle"}, - ximp = #'XSetImp'{bool = true, os = "kalle"}, - xexp = #'XSetExp'{bool = true, os = "kalle"}}), - ?line {ok,{'SetTagImpX',{'XSetNT',"kalle",true}, - {'XSetImp',"kalle",true}, - {'XSetExp',"kalle",true}}} = - asn1_wrapper:decode('SetTag','SetTagImpX',lists:flatten(Bytes22)), - - - ?line {ok,Bytes23} = - asn1_wrapper:encode('SetTag','SetTagExpX', - #'SetTagExpX'{xnt = #'XSetNT'{bool = true, os = "kalle"}, - ximp = #'XSetImp'{bool = true, os = "kalle"}, - xexp = #'XSetExp'{bool = true, os = "kalle"}}), - ?line {ok,{'SetTagExpX',{'XSetNT',"kalle",true}, - {'XSetImp',"kalle",true}, - {'XSetExp',"kalle",true}}} = - asn1_wrapper:decode('SetTag','SetTagExpX',lists:flatten(Bytes23)), - - - - - + roundtrip('SetTag', #'SetTag'{nt=#'NT'{os="kalle",bool=true}, + imp=#'Imp'{os="kalle",bool=true}, + exp=#'Exp'{os="kalle",bool=true}}), + roundtrip('SetTagImp', #'SetTagImp'{nt=#'NT'{os="kalle",bool=true}, + imp=#'Imp'{os="kalle",bool=true}, + exp=#'Exp'{os="kalle",bool=true}}), + roundtrip('SetTagExp', #'SetTagExp'{nt=#'NT'{os="kalle",bool=true}, + imp=#'Imp'{os="kalle",bool=true}, + exp=#'Exp'{os="kalle",bool=true}}), + roundtrip('SetTagX', #'SetTagX'{xnt=#'XSetNT'{os="kalle",bool=true}, + ximp=#'XSetImp'{os="kalle",bool=true}, + xexp=#'XSetExp'{os="kalle",bool=true}}), + roundtrip('SetTagImpX', #'SetTagImpX'{xnt=#'XSetNT'{os="kalle",bool=true}, + ximp=#'XSetImp'{os="kalle",bool=true}, + xexp=#'XSetExp'{os="kalle",bool=true}}), + roundtrip('SetTagExpX', #'SetTagExpX'{xnt=#'XSetNT'{os="kalle",bool=true}, + ximp=#'XSetImp'{os="kalle",bool=true}, + xexp=#'XSetExp'{os="kalle",bool=true}}), ok. + +roundtrip(T, V) -> + asn1_test_lib:roundtrip('SetTag', T, V). diff --git a/lib/asn1/test/testSetTypeRefCho.erl b/lib/asn1/test/testSetTypeRefCho.erl index a0989926c7..8d62f45bfa 100644 --- a/lib/asn1/test/testSetTypeRefCho.erl +++ b/lib/asn1/test/testSetTypeRefCho.erl @@ -28,17 +28,12 @@ main(_Rules) -> - - - ?line {ok,Bytes11} = - asn1_wrapper:encode('SetTypeRefCho','SetTRcho', - #'SetTRcho'{'setCho' = {choOs,"A string 1"}, - 'setChoE' = {choOs,"A string 3"}, - 'setCho-E' = {choOs,"A string 7"}, - 'setChoE-E' = {choOs,"A string 9"}}), - ?line {ok,{'SetTRcho',{choOs,"A string 1"},{choOs,"A string 3"},{choOs,"A string 7"},{choOs,"A string 9"}}} = - asn1_wrapper:decode('SetTypeRefCho','SetTRcho',lists:flatten(Bytes11)), - - - + roundtrip('SetTRcho', + #'SetTRcho'{'setCho' = {choOs,"A string 1"}, + 'setChoE' = {choOs,"A string 3"}, + 'setCho-E' = {choOs,"A string 7"}, + 'setChoE-E' = {choOs,"A string 9"}}), ok. + +roundtrip(T, V) -> + asn1_test_lib:roundtrip('SetTypeRefCho', T, V). diff --git a/lib/asn1/test/testSetTypeRefPrim.erl b/lib/asn1/test/testSetTypeRefPrim.erl index 9c7fbd803e..cc2e157e68 100644 --- a/lib/asn1/test/testSetTypeRefPrim.erl +++ b/lib/asn1/test/testSetTypeRefPrim.erl @@ -27,21 +27,17 @@ main(_Rules) -> - - - ?line {ok,Bytes11} = - asn1_wrapper:encode('SetTypeRefPrim','SetTR',#'SetTR'{'octStr' = "A string 1", - 'octStrI' = "A string 2", - 'octStrE' = "A string 3", - 'octStr-I' = "A string 4", - 'octStrI-I' = "A string 5", - 'octStrE-I' = "A string 6", - 'octStr-E' = "A string 7", - 'octStrI-E' = "A string 8", - 'octStrE-E' = "A string 9"}), - ?line {ok,{'SetTR',"A string 1","A string 2","A string 3","A string 4","A string 5","A string 6","A string 7","A string 8","A string 9"}} = - asn1_wrapper:decode('SetTypeRefPrim','SetTR',lists:flatten(Bytes11)), - - - + roundtrip('SetTR', + #'SetTR'{'octStr' = "A string 1", + 'octStrI' = "A string 2", + 'octStrE' = "A string 3", + 'octStr-I' = "A string 4", + 'octStrI-I' = "A string 5", + 'octStrE-I' = "A string 6", + 'octStr-E' = "A string 7", + 'octStrI-E' = "A string 8", + 'octStrE-E' = "A string 9"}), ok. + +roundtrip(T, V) -> + asn1_test_lib:roundtrip('SetTypeRefPrim', T, V). diff --git a/lib/asn1/test/testSetTypeRefSeq.erl b/lib/asn1/test/testSetTypeRefSeq.erl index a3ef4b188d..17af5c2922 100644 --- a/lib/asn1/test/testSetTypeRefSeq.erl +++ b/lib/asn1/test/testSetTypeRefSeq.erl @@ -28,12 +28,8 @@ -record('SetSeqImp',{seqInt, seqOs}). -record('SetSeqExp',{seqInt, seqOs}). - - main(_Rules) -> - - ?line {ok,Bytes41} = - asn1_wrapper:encode('SetTypeRefSeq','SetTRseq', + roundtrip('SetTRseq', #'SetTRseq'{'setSeq' = #'SetSeq'{seqOs = "A1", seqInt = 2}, 'setSeqI' = #'SetSeq'{seqOs = "A2", @@ -52,15 +48,7 @@ main(_Rules) -> seqInt = 2}, 'setSeqE-E' = #'SetSeqExp'{seqOs = "A9", seqInt = 2}}), - ?line {ok,{'SetTRseq',{'SetSeq',2,"A1"}, - {'SetSeq',2,"A2"}, - {'SetSeq',2,"A3"}, - {'SetSeqImp',2,"A4"}, - {'SetSeqImp',2,"A5"}, - {'SetSeqImp',2,"A6"}, - {'SetSeqExp',2,"A7"}, - {'SetSeqExp',2,"A8"}, - {'SetSeqExp',2,"A9"}}} = - asn1_wrapper:decode('SetTypeRefSeq','SetTRseq',lists:flatten(Bytes41)), - ok. + +roundtrip(T, V) -> + asn1_test_lib:roundtrip('SetTypeRefSeq', T, V). diff --git a/lib/asn1/test/testSetTypeRefSet.erl b/lib/asn1/test/testSetTypeRefSet.erl index ce77316ef8..8786e0fb4d 100644 --- a/lib/asn1/test/testSetTypeRefSet.erl +++ b/lib/asn1/test/testSetTypeRefSet.erl @@ -46,131 +46,42 @@ main(_Rules) -> - - - ?line {ok,Bytes11} = - asn1_wrapper:encode('SetTypeRefSet','Set1',#'Set1'{bool1 = true, - int1 = 15, - set1 = #'SetIn'{boolIn = true, - intIn = 66}}), - ?line {ok,{'Set1',true,15,{'SetIn',true,66}}} = - asn1_wrapper:decode('SetTypeRefSet','Set1',lists:flatten(Bytes11)), - - - - ?line {ok,Bytes12} = - asn1_wrapper:encode('SetTypeRefSet','Set2',#'Set2'{set2 = #'SetIn'{boolIn = true, - intIn = 66}, - bool2 = true, - int2 = 15}), - ?line {ok,{'Set2',{'SetIn',true,66},true,15}} = - asn1_wrapper:decode('SetTypeRefSet','Set2',lists:flatten(Bytes12)), - - - ?line {ok,Bytes13} = - asn1_wrapper:encode('SetTypeRefSet','Set3',#'Set3'{bool3 = true, - set3 = #'SetIn'{boolIn = true, - intIn = 66}, - int3 = 15}), - ?line {ok,{'Set3',true,{'SetIn',true,66},15}} = - asn1_wrapper:decode('SetTypeRefSet','Set3',lists:flatten(Bytes13)), - - - - ?line {ok,Bytes14} = - asn1_wrapper:encode('SetTypeRefSet','Set4',#'Set4'{set41 = #'SetIn'{boolIn = true, - intIn = 66}, - set42 = #'SetIn'{boolIn = true, - intIn = 66}, - set43 = #'SetIn'{boolIn = true, - intIn = 66}}), - ?line {ok,{'Set4',{'SetIn',true,66},{'SetIn',true,66},{'SetIn',true,66}}} = - asn1_wrapper:decode('SetTypeRefSet','Set4',lists:flatten(Bytes14)), - - - - - - - - - ?line {ok,Bytes21} = - asn1_wrapper:encode('SetTypeRefSet','SetS1',#'SetS1'{boolS1 = true, - intS1 = 15, - setS1 = #'SetS1_setS1'{boolIn = true, - intIn = 66}}), - ?line {ok,{'SetS1',true,15,{'SetS1_setS1',true,66}}} = - asn1_wrapper:decode('SetTypeRefSet','SetS1',lists:flatten(Bytes21)), - - - ?line {ok,Bytes22} = - asn1_wrapper:encode('SetTypeRefSet','SetS2',#'SetS2'{setS2 = #'SetS2_setS2'{boolIn = true, - intIn = 66}, - boolS2 = true, - intS2 = 15}), - ?line {ok,{'SetS2',{'SetS2_setS2',true,66},true,15}} = - asn1_wrapper:decode('SetTypeRefSet','SetS2',lists:flatten(Bytes22)), - - - - ?line {ok,Bytes23} = - asn1_wrapper:encode('SetTypeRefSet','SetS3',#'SetS3'{boolS3 = true, - setS3 = #'SetS3_setS3'{boolIn = true, - intIn = 66}, - intS3 = 15}), - ?line {ok,{'SetS3',true,{'SetS3_setS3',true,66},15}} = - asn1_wrapper:decode('SetTypeRefSet','SetS3',lists:flatten(Bytes23)), - - - - - - - ?line {ok,Bytes31} = - asn1_wrapper:encode('SetTypeRefSet','SetSTag',#'SetSTag'{setS1 = #'SetSTag_setS1'{b1 = true, - i1 = 11}, - setS2 = #'SetSTag_setS2'{b2 = true, - i2 = 22}, - setS3 = #'SetSTag_setS3'{b3 = true, - i3 = 33}}), - ?line {ok,{'SetSTag',{'SetSTag_setS1',true,11}, - {'SetSTag_setS2',true,22}, - {'SetSTag_setS3',true,33}}} = - asn1_wrapper:decode('SetTypeRefSet','SetSTag',lists:flatten(Bytes31)), - - - - - - ?line {ok,Bytes41} = - asn1_wrapper:encode('SetTypeRefSet','SetTRset', - #'SetTRset'{'setSet' = #'SetSet'{setOs = "A1", - setInt = 2}, - 'setSetI' = #'SetSet'{setOs = "A2", - setInt = 2}, - 'setSetE' = #'SetSet'{setOs = "A3", - setInt = 2}, - 'setSet-I' = #'SetSetImp'{setOs = "A4", - setInt = 2}, - 'setSetI-I' = #'SetSetImp'{setOs = "A5", - setInt = 2}, - 'setSetE-I' = #'SetSetImp'{setOs = "A6", - setInt = 2}, - 'setSet-E' = #'SetSetExp'{setOs = "A7", - setInt = 2}, - 'setSetI-E' = #'SetSetExp'{setOs = "A8", - setInt = 2}, - 'setSetE-E' = #'SetSetExp'{setOs = "A9", - setInt = 2}}), - ?line {ok,{'SetTRset',{'SetSet',2,"A1"}, - {'SetSet',2,"A2"}, - {'SetSet',2,"A3"}, - {'SetSetImp',2,"A4"}, - {'SetSetImp',2,"A5"}, - {'SetSetImp',2,"A6"}, - {'SetSetExp',2,"A7"}, - {'SetSetExp',2,"A8"}, - {'SetSetExp',2,"A9"}}} = - asn1_wrapper:decode('SetTypeRefSet','SetTRset',lists:flatten(Bytes41)), + roundtrip('Set1', + #'Set1'{bool1=true,int1=15,set1=#'SetIn'{boolIn=true,intIn=66}}), + roundtrip('Set2', + #'Set2'{set2=#'SetIn'{boolIn=true,intIn=66},bool2=true,int2=15}), + roundtrip('Set3', + #'Set3'{bool3=true,set3=#'SetIn'{boolIn=true,intIn=66},int3=15}), + roundtrip('Set4', + #'Set4'{set41=#'SetIn'{boolIn=true,intIn=66}, + set42=#'SetIn'{boolIn=true,intIn=66}, + set43=#'SetIn'{boolIn=true,intIn=66}}), + roundtrip('SetS1', + #'SetS1'{boolS1=true,intS1=15, + setS1=#'SetS1_setS1'{boolIn=true,intIn=66}}), + roundtrip('SetS2', + #'SetS2'{setS2=#'SetS2_setS2'{boolIn=true,intIn=66}, + boolS2=true,intS2=15}), + roundtrip('SetS3', + #'SetS3'{boolS3=true, + setS3=#'SetS3_setS3'{boolIn=true,intIn=66}, + intS3=15}), + roundtrip('SetSTag', + #'SetSTag'{setS1=#'SetSTag_setS1'{b1=true,i1=11}, + setS2=#'SetSTag_setS2'{b2=true,i2=22}, + setS3=#'SetSTag_setS3'{b3=true,i3=33}}), + roundtrip('SetTRset', + #'SetTRset'{setSet=#'SetSet'{setInt=2,setOs="A1"}, + setSetI=#'SetSet'{setInt=2,setOs="A2"}, + setSetE=#'SetSet'{setInt=2,setOs="A3"}, + 'setSet-I'=#'SetSetImp'{setInt=2,setOs="A4"}, + 'setSetI-I'=#'SetSetImp'{setInt=2,setOs="A5"}, + 'setSetE-I'=#'SetSetImp'{setInt=2,setOs="A6"}, + 'setSet-E'=#'SetSetExp'{setInt=2,setOs="A7"}, + 'setSetI-E'=#'SetSetExp'{setInt=2,setOs="A8"}, + 'setSetE-E'=#'SetSetExp'{setInt=2,setOs="A9"}}), ok. + +roundtrip(T, V) -> + asn1_test_lib:roundtrip('SetTypeRefSet', T, V). diff --git a/lib/asn1/test/testTCAP.erl b/lib/asn1/test/testTCAP.erl index aba13c94de..17511dc2b7 100644 --- a/lib/asn1/test/testTCAP.erl +++ b/lib/asn1/test/testTCAP.erl @@ -40,25 +40,26 @@ compile_asn1config(Config, Options) -> test(Erule,_Config) -> % ?line OutDir = ?config(priv_dir,Config), %% testing OTP-4798, open type encoded with indefinite length - ?line {ok,_Res} = asn1_wrapper:decode('TCAPMessages-simple','MessageType', val_OTP_4798(Erule)), + {ok,_Res} = 'TCAPMessages-simple':decode('MessageType', + val_OTP_4798(Erule)), + %% testing OTP-4799, absent optional open type - ?line {ok,_Res2} = asn1_wrapper:decode('TCAPMessages-simple','MessageType',val_OTP_4799(Erule)), + {ok,_Res2} = 'TCAPMessages-simple':decode('MessageType', + val_OTP_4799(Erule)), + %% testing vance shipley's problems. Parameterized object sets. ?line Val3 = 'TCAPPackage_msg':val('PackageType',unidirectional), - ?line {ok,Bytes3} = asn1_wrapper:encode('TCAPPackage','PackageType',Val3), - ?line {ok,Res3} = asn1_wrapper:decode('TCAPPackage','PackageType',Bytes3), + Res3 = enc_dec('PackageType', Val3), ?line ok = 'TCAPPackage_msg':check_result('PackageType',unidirectional,Res3), %% ?line io:format("Res3:~n~p~n~n",[Res3]), ?line Val4 = 'TCAPPackage_msg':val('PackageType',abort), - ?line {ok,Bytes4} = asn1_wrapper:encode('TCAPPackage','PackageType',Val4), - ?line {ok,Res4} = asn1_wrapper:decode('TCAPPackage','PackageType',Bytes4), + Res4 = enc_dec('PackageType', Val4), ?line ok = 'TCAPPackage_msg':check_result('PackageType',abort,Res4), %% ?line io:format("Res4:~n~p~n~n",[Res4]), ?line Val5 = 'TCAPPackage_msg':val('PackageType',response), - ?line {ok,Bytes5} = asn1_wrapper:encode('TCAPPackage','PackageType',Val5), - ?line {ok,Res5} = asn1_wrapper:decode('TCAPPackage','PackageType',Bytes5), + Res5 = enc_dec('PackageType', Val5), ?line ok = 'TCAPPackage_msg':check_result('PackageType',response,Res5). %% ?line io:format("Res5:~n~p~n~n",[Res5]). @@ -73,21 +74,26 @@ val_OTP_4799(_) -> <<100,16,73,4,41,182,36,0,108,8,163,6,2,1,29,2,1,27>>. test_asn1config() -> - ?line Val = 'TCAPPackage_msg':val('PackageType',queryWithPerm), - ?line {ok,B} = asn1_wrapper:encode('TCAPPackage','PackageType',Val), - ?line {ok,ExMsg}='TCAPPackage':decode_PackageType(list_to_binary(B)), - ?line {_,{_,_,_,{Key,ExVal}}}=ExMsg, - ?line {ok,_Parts}='TCAPPackage':decode_part(Key,ExVal), + Val = 'TCAPPackage_msg':val('PackageType', queryWithPerm), + {ok,B} = 'TCAPPackage':encode('PackageType', Val), + {ok,ExMsg}='TCAPPackage':decode_PackageType(B), + {_,{_,_,_,{Key,ExVal}}} = ExMsg, + {ok,_Parts} = 'TCAPPackage':decode_part(Key, ExVal), - ?line Val2 = 'TCAPPackage_msg':val('TransactionPDU'), - ?line {ok,B2} = 'TCAPPackage':encode('TransactionPDU',Val2), - {ok,ExMsg2}='TCAPPackage':decode_TransactionPDU(B2), - ?line {_,_,_,{Key2,ExVal2}}=ExMsg2, - ?line {ok,_Parts2}='TCAPPackage':decode_part(Key2,ExVal2), + Val2 = 'TCAPPackage_msg':val('TransactionPDU'), + {ok,B2} = 'TCAPPackage':encode('TransactionPDU', Val2), + {ok,ExMsg2} = 'TCAPPackage':decode_TransactionPDU(B2), + {_,_,_,{Key2,ExVal2}} = ExMsg2, + {ok,_Parts2} = 'TCAPPackage':decode_part(Key2, ExVal2), - ?line Val3 = 'TCAPPackage_msg':val('PackageType',response), - ?line {ok,B3} = asn1_wrapper:encode('TCAPPackage','PackageType',Val3), - ?line {ok,ExMsg3}='TCAPPackage':decode_PackageType(list_to_binary(B3)), - ?line {_,{_,_,_,{Key3,ExVal3}}}=ExMsg3, - ?line {ok,_Parts3}='TCAPPackage':decode_part(Key3,ExVal3). + Val3 = 'TCAPPackage_msg':val('PackageType', response), + {ok,B3} = 'TCAPPackage':encode('PackageType', Val3), + {ok,ExMsg3} = 'TCAPPackage':decode_PackageType(B3), + {_,{_,_,_,{Key3,ExVal3}}} = ExMsg3, + {ok,_Parts3}='TCAPPackage':decode_part(Key3, ExVal3). +enc_dec(T, V0) -> + M = 'TCAPPackage', + {ok,Enc} = M:encode(T, V0), + {ok,V} = M:decode(T, Enc), + V. diff --git a/lib/asn1/test/testTimer.erl b/lib/asn1/test/testTimer.erl index cd7ceb5630..0f02bab6e0 100644 --- a/lib/asn1/test/testTimer.erl +++ b/lib/asn1/test/testTimer.erl @@ -18,9 +18,7 @@ %% %% -module(testTimer). - --compile(export_all). -%%-export([Function/Arity, ...]). +-export([go/2]). -include_lib("test_server/include/test_server.hrl"). @@ -127,7 +125,7 @@ val() -> {'H323-UserInformation_user-data',24,"O"}}. -go(Config,Enc) -> +go(Config, _Enc) -> ?line true = code:add_patha(?config(priv_dir,Config)), Module = 'H323-MESSAGES', @@ -137,13 +135,12 @@ go(Config,Enc) -> CompileOptions = compile_options(), - ?line {ValWr, done} = timer:tc(?MODULE, encode, [?times, Module, Type, Value]), + {ValWr,done} = timer:tc(fun() -> encode(?times, Module, Type, Value) end), ?line io:format("ASN1 encode ~p: ~p micro~n", [CompileOptions, ValWr / ?times]), - ?line done = decode(2,Module,Type,Bytes,Enc), + done = decode(2, Module, Type, Bytes), - ?line {ValRead, done} = timer:tc(?MODULE, decode, [?times, Module, - Type, Bytes,Enc]), + {ValRead,done} = timer:tc(fun() -> decode(?times, Module, Type, Bytes) end), ?line io:format("ASN1 decode ~p: ~p micro~n", [CompileOptions, ValRead /?times]), @@ -162,11 +159,11 @@ encode(N, Module,Type,Value) -> end, encode(N-1, Module,Type,Value). -decode(0, _Module,_Type,_Value,_Erule) -> +decode(0, _Module, _Type, _Value) -> done; -decode(N, Module,Type,Value,Erule) -> - {ok,_B} = asn1rt:decode(Module,Type,Value), - decode(N-1, Module,Type,Value,Erule). +decode(N, Module, Type, Value) -> + {ok,_B} = asn1rt:decode(Module, Type, Value), + decode(N-1, Module, Type, Value). compile_options() -> {ok,Info} = asn1rt:info('H323-MESSAGES'), diff --git a/lib/asn1/test/testTypeValueNotation.erl b/lib/asn1/test/testTypeValueNotation.erl index 61d69edd0e..b46d7177f5 100644 --- a/lib/asn1/test/testTypeValueNotation.erl +++ b/lib/asn1/test/testTypeValueNotation.erl @@ -24,13 +24,15 @@ -record('Seq', {octstr, int, bool, enum, bitstr, null, oid, vstr}). main(_Rule, _Option) -> - Value1 = #'Seq'{octstr = [1, 2, 3, 4], - int = 12, - bool = true, - enum = a, - bitstr = <<2#1010:4>>, - null = 'NULL', - oid = {1, 2, 55}, - vstr = "Hello World"}, - {ok, Bytes} = asn1_wrapper:encode('SeqTypeRefPrim', 'Seq', Value1), - {ok, Value1} = asn1_wrapper:decode('SeqTypeRefPrim', 'Seq', Bytes). + Value = #'Seq'{octstr = [1, 2, 3, 4], + int = 12, + bool = true, + enum = a, + bitstr = <<2#1010:4>>, + null = 'NULL', + oid = {1, 2, 55}, + vstr = "Hello World"}, + roundtrip('Seq', Value). + +roundtrip(T, V) -> + asn1_test_lib:roundtrip('SeqTypeRefPrim', T, V). diff --git a/lib/asn1/test/testWSParamClass.erl b/lib/asn1/test/testWSParamClass.erl index ae67ca8b81..66ba56a6d8 100644 --- a/lib/asn1/test/testWSParamClass.erl +++ b/lib/asn1/test/testWSParamClass.erl @@ -11,7 +11,4 @@ main(_) -> ok. roundtrip(Data) -> - IF = 'InformationFramework', - {ok,Enc} = asn1_wrapper:encode(IF, 'Attribute', Data), - {ok,Data} = IF:decode('Attribute', Enc), - ok. + asn1_test_lib:roundtrip('InformationFramework', 'Attribute', Data). diff --git a/lib/asn1/test/testX420.erl b/lib/asn1/test/testX420.erl index 70bdb0640d..4ddc55dc16 100644 --- a/lib/asn1/test/testX420.erl +++ b/lib/asn1/test/testX420.erl @@ -27,21 +27,11 @@ compile(Erule, Options, Config) -> - Specs = specs(), - 99 = length(Specs), - ok = compile_loop(Erule,Specs,Options,Config). - -compile_loop(_Erule, [], _Options, _Config) -> - ok; -compile_loop(Erule, [Spec|Specs], Options, Config) - when Erule =:= ber; Erule =:= per -> + Specs0 = specs(), + 99 = length(Specs0), CaseDir = ?config(case_dir, Config), - asn1_test_lib:compile(filename:join([x420, Spec]), Config, - [Erule, {i, CaseDir} | Options]), - compile_loop(Erule, Specs, Options, Config); -compile_loop(_Erule, _Specs, _Options, _Config) -> - ok. - + Specs = [filename:join(x420, Spec) || Spec <- Specs0], + asn1_test_lib:compile_all(Specs, Config, [Erule,{i,CaseDir}|Options]). specs() -> ["ACSE-1", "AuthenticationFramework", "BasicAccessControl", @@ -93,9 +83,9 @@ specs() -> ticket7759(_Erule,_Config) -> Encoded = encoded_msg(), io:format("Testing ticket7759 ...~n",[]), - ?line {ok, ContentInfo} = asn1_wrapper:decode('PKCS7','ContentInfo',Encoded), - ?line {'ContentInfo',_Id,PKCS7_content} = ContentInfo, - ?line {ok,_} = asn1_wrapper:decode('PKCS7','SignedData',PKCS7_content), + {ok, ContentInfo} = 'PKCS7':decode('ContentInfo',Encoded), + {'ContentInfo',_Id,PKCS7_content} = ContentInfo, + {ok,_} = 'PKCS7':decode('SignedData',PKCS7_content), ok. diff --git a/lib/asn1/test/test_driver_load.erl b/lib/asn1/test/test_driver_load.erl deleted file mode 100644 index e0e6602046..0000000000 --- a/lib/asn1/test/test_driver_load.erl +++ /dev/null @@ -1,45 +0,0 @@ -%% -%% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2003-2012. All Rights Reserved. -%% -%% The contents of this file are subject to the Erlang Public License, -%% Version 1.1, (the "License"); you may not use this file except in -%% compliance with the License. You should have received a copy of the -%% Erlang Public License along with this software. If not, it can be -%% retrieved online at http://www.erlang.org/. -%% -%% Software distributed under the License is distributed on an "AS IS" -%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See -%% the License for the specific language governing rights and limitations -%% under the License. -%% -%% %CopyrightEnd% -%% -%% --module(test_driver_load). - --export([test/1,encode/0]). - --include_lib("test_server/include/test_server.hrl"). - - -test(0) -> - ok; -test(N) -> - spawn(?MODULE,encode,[]), - test(N-1). - -encode() -> - ?line Msg = msg(), - ?line {ok,_}=asn1_wrapper:encode('P-Record','PersonnelRecord',Msg), - ok. - -msg() -> - {'PersonnelRecord',{'Name',"John","P","Smith"}, - "Director", - 51, - "19710917", - {'Name',"Mary","T","Smith"}, - [{'ChildInformation',{'Name',"Ralph","T","Smith"},"19571111"},{'ChildInformation',{'Name',"Susan","B","Jones"},"19590717"}]}. - diff --git a/lib/asn1/test/test_modified_x420.erl b/lib/asn1/test/test_modified_x420.erl index a525fd6ae1..0df72a1831 100644 --- a/lib/asn1/test/test_modified_x420.erl +++ b/lib/asn1/test/test_modified_x420.erl @@ -26,8 +26,9 @@ test(Config) -> DataDir = ?config(data_dir,Config), Der = read_pem(filename:join([DataDir,modified_x420,"p7_signed_data.pem"])), - {ok,{_,_,SignedData}} = asn1_wrapper:decode('PKCS7', 'ContentInfo', Der), - {ok,_} = asn1_wrapper:decode('PKCS7', 'SignedData', SignedData). + {ok,{_,_,SignedData}} = 'PKCS7':decode( 'ContentInfo', Der), + {ok,_} = 'PKCS7':decode('SignedData', SignedData), + ok. read_pem(File) -> {ok,Bin} = file:read_file(File), diff --git a/lib/asn1/test/test_partial_incomplete_decode.erl b/lib/asn1/test/test_partial_incomplete_decode.erl index 8ede06938d..4a8a4cd74c 100644 --- a/lib/asn1/test/test_partial_incomplete_decode.erl +++ b/lib/asn1/test/test_partial_incomplete_decode.erl @@ -25,84 +25,57 @@ test(Config) -> FMsg = msg('F'), - ?line {ok,Bytes} = asn1_wrapper:encode('PartialDecSeq','F',FMsg), - ?line {ok,_} = asn1_wrapper:decode('PartialDecSeq','F',Bytes), - ?line {ok,IncFMsg} = - 'PartialDecSeq':decode_F_fb_incomplete(list_to_binary(Bytes)), - ?line decode_parts('F',IncFMsg), + Bytes1 = roundtrip('PartialDecSeq', 'F', FMsg), + {ok,IncFMsg} = 'PartialDecSeq':decode_F_fb_incomplete(Bytes1), + decode_parts('F', IncFMsg), + {ok,IncF2Msg} = 'PartialDecSeq':decode_F_fb_exclusive2(Bytes1), + decode_parts('F2', IncF2Msg), DMsg = msg('D'), - ?line {ok,Bytes2} = asn1_wrapper:encode('PartialDecSeq','D',DMsg), - ?line {ok,_} = asn1_wrapper:decode('PartialDecSeq','D',Bytes2), - ?line {ok,IncDMsg} = - 'PartialDecSeq':decode_D_incomplete(list_to_binary(Bytes2)), - ?line decode_parts('D',IncDMsg), - - ?line {ok,IncF2Msg} = - 'PartialDecSeq':decode_F_fb_exclusive2(list_to_binary(Bytes)), - ?line decode_parts('F2',IncF2Msg), + Bytes2 = roundtrip('PartialDecSeq', 'D', DMsg), + {ok,IncDMsg} = 'PartialDecSeq':decode_D_incomplete(Bytes2), + decode_parts('D', IncDMsg), F3Msg = msg('F3'), - ?line {ok,BytesF3} = asn1_wrapper:encode('PartialDecSeq','F',F3Msg), - ?line {ok,_} = asn1_wrapper:decode('PartialDecSeq','F',BytesF3), - ?line {ok,IncF3Msg} = - 'PartialDecSeq':decode_F_fb_exclusive3(list_to_binary(BytesF3)), - ?line decode_parts('F3',IncF3Msg), - - - AMsg =msg('A'), - ?line {ok,Bytes3} = asn1_wrapper:encode('PartialDecSeq2','A',AMsg), - ?line {ok,_} = asn1_wrapper:decode('PartialDecSeq2','A',Bytes3), - ?line {ok,IncFMsg3} = - 'PartialDecSeq2':decode_A_c_b_incomplete(list_to_binary(Bytes3)), - ?line decode_parts('A',IncFMsg3), + BytesF3 = roundtrip('PartialDecSeq', 'F', F3Msg), + {ok,IncF3Msg} = 'PartialDecSeq':decode_F_fb_exclusive3(BytesF3), + decode_parts('F3', IncF3Msg), + + AMsg = msg('A'), + Bytes3 = roundtrip('PartialDecSeq2', 'A', AMsg), + {ok,IncFMsg3} = 'PartialDecSeq2':decode_A_c_b_incomplete(Bytes3), + decode_parts('A', IncFMsg3), MyHTTPMsg = msg('GetRequest'), - ?line {ok,Bytes4} = asn1_wrapper:encode('PartialDecMyHTTP', - 'GetRequest',MyHTTPMsg), - ?line {ok,_} = asn1_wrapper:decode('PartialDecMyHTTP','GetRequest', - Bytes4), - ?line {ok,IncFMsg4} = - 'PartialDecMyHTTP':decode_GetRequest_incomplete(list_to_binary(Bytes4)), - ?line decode_parts('GetRequest',IncFMsg4), + Bytes4 = roundtrip('PartialDecMyHTTP', 'GetRequest', MyHTTPMsg), + {ok,IncFMsg4} = 'PartialDecMyHTTP':decode_GetRequest_incomplete(Bytes4), + decode_parts('GetRequest', IncFMsg4), MsgS1_1 = msg('S1_1'), - ?line {ok,Bytes5} = asn1_wrapper:encode('PartialDecSeq3','S1',MsgS1_1), - ?line {ok,_} = asn1_wrapper:decode('PartialDecSeq3','S1',Bytes5), - ?line {ok,IncFMsg5} = - 'PartialDecSeq3':decode_S1_incomplete(list_to_binary(Bytes5)), - ?line decode_parts('S1_1',IncFMsg5), + Bytes5 = roundtrip('PartialDecSeq3', 'S1', MsgS1_1), + {ok,IncFMsg5} = 'PartialDecSeq3':decode_S1_incomplete(Bytes5), + decode_parts('S1_1', IncFMsg5), MsgS1_2 = msg('S1_2'), - ?line {ok,Bytes6} = asn1_wrapper:encode('PartialDecSeq3','S1',MsgS1_2), - ?line {ok,IncFMsg6} = - 'PartialDecSeq3':decode_S1_incomplete(list_to_binary(Bytes6)), - ?line ok = decode_parts('S1_2',IncFMsg6), + Bytes6 = roundtrip('PartialDecSeq3', 'S1', MsgS1_2), + {ok,IncFMsg6} = 'PartialDecSeq3':decode_S1_incomplete(Bytes6), + decode_parts('S1_2', IncFMsg6), %% test of MEDIA-GATEWAY-CONTROL test_megaco(Config), ok. test_megaco(Config) -> - ?line DataDir = ?config(data_dir,Config), - Mod='MEDIA-GATEWAY-CONTROL', - ?line {ok,FilenameList} = file:list_dir(filename:join([DataDir, - megacomessages])), - %% remove any junk files that may be in the megacomessage directory - Pred = fun(X) -> - case lists:reverse(X) of - [$l,$a,$v,$.|_R] ->true; - _ -> false - end - end, - MegacoMsgFilenameList = lists:filter(Pred,FilenameList), - Fun = fun(F) -> - M = read_msg(filename:join([DataDir,megacomessages,F])), - ?line {ok,B} = asn1_wrapper:encode(Mod,element(1,M),M), - ?line exclusive_decode(list_to_binary(B),F) - end, - ?line lists:foreach(Fun,MegacoMsgFilenameList), - ok. + DataDir = ?config(data_dir, Config), + Files = filelib:wildcard(filename:join([DataDir,megacomessages,"*.val"])), + Mod = 'MEDIA-GATEWAY-CONTROL', + lists:foreach(fun(File) -> + {ok,Bin} = file:read_file(File), + V = binary_to_term(Bin), + T = element(1, V), + Enc = roundtrip(Mod, T, V), + exclusive_decode(Enc, File) + end, Files). exclusive_decode(Bin,F) -> Mod='MEDIA-GATEWAY-CONTROL', @@ -113,15 +86,6 @@ exclusive_decode(Bin,F) -> ?line {ok,_} = Mod:decode_part(MsgMBodyKey,MsgMBody), ok. - -read_msg(File) -> - case file:read_file(File) of - {ok,Bin} -> - binary_to_term(Bin); - _ -> - io:format("couldn't read file ~p~n",[File]) - end. - decode_parts('F',PartDecMsg) -> ?line {fb,{'E',35,{NameE_b,ListBinE_b},false,{NameE_d,BinE_d}}} = PartDecMsg, ?line {ok,[{'D',3,true}|_]} = 'PartialDecSeq':decode_part(NameE_b,ListBinE_b), @@ -200,7 +164,10 @@ msg('A') -> {'A',12,{c,{'S',true,false}},{b,{'A_c_b',false,false}}}; msg('GetRequest') -> - {'GetRequest',true,false,{'AcceptTypes',[1,1,1,1],["hell","othe","reho","peyo","uare","fine"]},"IamfineThankYOu"}; + {'GetRequest',true,false, + {'AcceptTypes',[html,'plain-text',gif,jpeg], + ["hell","othe","reho","peyo","uare","fine"]}, + "IamfineThankYOu"}; msg('S1_1') -> {'S1',14,msg('S2'),msg('C1_a'),msg('SO1')}; @@ -213,10 +180,13 @@ msg('C1_a') -> msg('C1_b') -> {b,{'C1_b',11,true,msg('S4')}}; msg('S3') -> - {'S3',10,"PrintableString","OCTETSTRING",[1,1,1,1]}; + {'S3',10,"PrintableString","OCTETSTRING",[one,two,three,four]}; msg('S4') -> {'S4',msg('Name'),"MSc"}; msg('SO1') -> [msg('Name'),msg('Name'),msg('Name')]; msg('Name') -> {'Name',"Hans","HCA","Andersen"}. + +roundtrip(M, T, V) -> + asn1_test_lib:roundtrip_enc(M, T, V). diff --git a/lib/asn1/test/test_selective_decode.erl b/lib/asn1/test/test_selective_decode.erl index ebe1296cf3..f42f24e0e3 100644 --- a/lib/asn1/test/test_selective_decode.erl +++ b/lib/asn1/test/test_selective_decode.erl @@ -18,39 +18,39 @@ %% %% -module(test_selective_decode). - -export([test/0]). -include_lib("test_server/include/test_server.hrl"). - test() -> FMsg = msg('F'), - ?line {ok,Bytes} = asn1_wrapper:encode('PartialDecSeq','F',FMsg), - ?line {ok,3} = - 'PartialDecSeq':selected_decode_F1(list_to_binary(Bytes)), - ?line {ok,[{'D',3,true},{'D',4,false},{'D',5,true},{'D',6,true},{'D',7,false},{'D',8,true},{'D',9,true},{'D',10,false},{'D',11,true},{'D',12,true},{'D',13,false},{'D',14,true}]} = 'PartialDecSeq':selected_decode_F2(list_to_binary(Bytes)), - ?line {ok,{'D',3,true}} = 'PartialDecSeq':selected_decode_F3(list_to_binary(Bytes)), - - ?line {ok,17} = 'PartialDecSeq':selected_decode_F4(list_to_binary(Bytes)), + Bytes = roundtrip('PartialDecSeq', 'F', FMsg), + {ok,3} = 'PartialDecSeq':selected_decode_F1(Bytes), + {ok,[{'D',3,true},{'D',4,false},{'D',5,true},{'D',6,true}, + {'D',7,false},{'D',8,true},{'D',9,true},{'D',10,false}, + {'D',11,true},{'D',12,true},{'D',13,false},{'D',14,true}]} = + 'PartialDecSeq':selected_decode_F2(Bytes), + {ok,{'D',3,true}} = 'PartialDecSeq':selected_decode_F3(Bytes), + {ok,17} = 'PartialDecSeq':selected_decode_F4(Bytes), EMsg = msg('E'), - ?line {ok,Bytes2} = asn1_wrapper:encode('PartialDecSeq','E',EMsg), - ?line {ok,14} = 'PartialDecSeq':selected_decode_E1(list_to_binary(Bytes2)), + Bytes2 = roundtrip('PartialDecSeq', 'E', EMsg), + {ok,14} = 'PartialDecSeq':selected_decode_E1(Bytes2), + MGCMsg = msg('M-G-C'), - ?line {ok,Bytes3} = asn1_wrapper:encode('MEDIA-GATEWAY-CONTROL', - 'MegacoMessage',MGCMsg), - ?line {ok,1} = 'MEDIA-GATEWAY-CONTROL':decode_MegacoMessage_selective(list_to_binary(Bytes3)), + Bytes3 = roundtrip('MEDIA-GATEWAY-CONTROL', 'MegacoMessage', MGCMsg), + {ok,1} = 'MEDIA-GATEWAY-CONTROL':decode_MegacoMessage_selective(Bytes3), PRecMsg = {'PersonnelRecord',{'Name',"Sven","S","Svensson"}, "manager",123,"20000202",{'Name',"Inga","K","Svensson"}, asn1_DEFAULT}, - ?line {ok,Bytes4} = asn1_wrapper:encode('P-Record','PersonnelRecord', - PRecMsg), - ?line {ok,_} = 'P-Record':sel_dec(list_to_binary(Bytes4)), - ok. - + PRecMsgDec = {'PersonnelRecord',{'Name',"Sven","S","Svensson"}, + "manager",123,"20000202",{'Name',"Inga","K","Svensson"}, + []}, + Bytes4 = roundtrip('P-Record', 'PersonnelRecord', PRecMsg, PRecMsgDec), + {ok,_} = 'P-Record':sel_dec(Bytes4), + ok. msg('F') -> {fb,{'E',35,[{'D',3,true},{'D',4,false},{'D',5,true},{'D',6,true},{'D',7,false},{'D',8,true},{'D',9,true},{'D',10,false},{'D',11,true},{'D',12,true},{'D',13,false},{'D',14,true}],false,{da,[{'A',16,{'D',17,true}}]}}}; @@ -60,3 +60,10 @@ msg('E') -> msg('M-G-C') -> {'MegacoMessage',asn1_NOVALUE,{'Message',1,{ip4Address,{'IP4Address',[125,125,125,111],55555}},{transactions,[{transactionReply,{'TransactionReply',50007,asn1_NOVALUE,{actionReplies,[{'ActionReply',0,asn1_NOVALUE,asn1_NOVALUE,[{auditValueReply,{auditResult,{'AuditResult',{'TerminationID',[],[255,255,255]},[{mediaDescriptor,{'MediaDescriptor',asn1_NOVALUE,{multiStream,[{'StreamDescriptor',1,{'StreamParms',{'LocalControlDescriptor',sendRecv,asn1_NOVALUE,asn1_NOVALUE,[{'PropertyParm',[0,11,0,7],[[52,48]],asn1_NOVALUE}]},{'LocalRemoteDescriptor',[[{'PropertyParm',[0,0,176,1],[[48]],asn1_NOVALUE},{'PropertyParm',[0,0,176,8],[[73,78,32,73,80,52,32,49,50,53,46,49,50,53,46,49,50,53,46,49,49,49]],asn1_NOVALUE},{'PropertyParm',[0,0,176,15],[[97,117,100,105,111,32,49,49,49,49,32,82,84,80,47,65,86,80,32,32,52]],asn1_NOVALUE},{'PropertyParm',[0,0,176,12],[[112,116,105,109,101,58,51,48]],asn1_NOVALUE}]]},{'LocalRemoteDescriptor',[[{'PropertyParm',[0,0,176,1],[[48]],asn1_NOVALUE},{'PropertyParm',[0,0,176,8],[[73,78,32,73,80,52,32,49,50,52,46,49,50,52,46,49,50,52,46,50,50,50]],asn1_NOVALUE},{'PropertyParm',[0,0,176,15],[[97,117,100,105,111,32,50,50,50,50,32,82,84,80,47,65,86,80,32,32,52]],asn1_NOVALUE},{'PropertyParm',[0,0,176,12],[[112,116,105,109,101,58,51,48]],asn1_NOVALUE}]]}}}]}}},{packagesDescriptor,[{'PackagesItem',[0,11],1},{'PackagesItem',[0,11],1}]},{statisticsDescriptor,[{'StatisticsParameter',[0,12,0,4],[[49,50,48,48]]},{'StatisticsParameter',[0,11,0,2],[[54,50,51,48,48]]},{'StatisticsParameter',[0,12,0,5],[[55,48,48]]},{'StatisticsParameter',[0,11,0,3],[[52,53,49,48,48]]},{'StatisticsParameter',[0,12,0,6],[[48,46,50]]},{'StatisticsParameter',[0,12,0,7],[[50,48]]},{'StatisticsParameter',[0,12,0,8],[[52,48]]}]}]}}}]}]}}}]}}}. + + +roundtrip(M, T, V) -> + asn1_test_lib:roundtrip_enc(M, T, V). + +roundtrip(M, T, V, E) -> + asn1_test_lib:roundtrip_enc(M, T, V, E). diff --git a/lib/asn1/test/test_special_decode_performance.erl b/lib/asn1/test/test_special_decode_performance.erl index 7dfab1f25a..0f52ae4cd2 100644 --- a/lib/asn1/test/test_special_decode_performance.erl +++ b/lib/asn1/test/test_special_decode_performance.erl @@ -19,7 +19,7 @@ %% -module(test_special_decode_performance). --export([go/1,loop2/4,loop1/5]). +-export([go/1]). -include_lib("test_server/include/test_server.hrl"). @@ -49,7 +49,7 @@ go1(_,_,[],_,_,AccTime) -> %% go1 for common decode go1(common,Mod,_,Bin,N,_) -> ?line TT=get_top_type(Mod), - ?line {Time,Result}=timer:tc(?MODULE,loop1,[Mod,decode,TT,Bin,N]), + {Time,Result} = timer:tc(fun() -> loop1(Mod, decode, TT, Bin, N) end), case Result of {ok,_R1} -> io:format("common Decode ~p:decode, ~p times on time ~p~n", @@ -59,7 +59,7 @@ go1(common,Mod,_,Bin,N,_) -> end, Time; go1(Dec,Mod,[F|Fs],Bin,N,AccTime) -> - ?line {Time,Result}=timer:tc(?MODULE,loop2,[Mod,F,Bin,N]), + {Time,Result}=timer:tc(fun() -> loop2(Mod, F, Bin, N) end), case Result of {ok,_R1} -> io:format("~p Decode ~p:~p, ~p times on time ~p~n",[Dec,Mod,F,N,Time]); diff --git a/lib/asn1/test/test_undecoded_rest.erl b/lib/asn1/test/test_undecoded_rest.erl index 36fd26ed59..91e614d38a 100644 --- a/lib/asn1/test/test_undecoded_rest.erl +++ b/lib/asn1/test/test_undecoded_rest.erl @@ -26,28 +26,42 @@ %% testing OTP-5104 -test(Opt, Config) -> - {ok, Msg} = asn1ct:value('P-Record', 'PersonnelRecord', - [{i, ?config(case_dir, Config)}]), - {ok, Bytes} = asn1_wrapper:encode('P-Record', 'PersonnelRecord', Msg), - Bytes2 = if is_list(Bytes) -> - Bytes ++ [55, 55, 55]; - is_binary(Bytes) -> - iolist_to_binary([Bytes, <<55, 55, 55>>]) - end, - case Opt of - undec_rest -> - {ok, Msg, R} = asn1_wrapper:decode('P-Record', 'PersonnelRecord', - Bytes2), +test(Opts, Config) -> + {ok,Msg} = asn1ct:value('P-Record', 'PersonnelRecord', + [{i,?config(case_dir, Config)}]), + Bytes0 = encode(Opts, 'PersonnelRecord', Msg), + Bytes1 = iolist_to_binary([Bytes0, <<55,55,55>>]), + case proplists:get_bool(undec_rest, Opts) of + true -> + {Msg,R} = decode(Opts, 'PersonnelRecord', Bytes1), case R of - <<55, 55, 55>> -> ok; - [55, 55, 55] -> ok; + <<55,55,55>> -> + ok; BStr when is_bitstring(BStr) -> PadLen = (8 - (bit_size(BStr) rem 8)) rem 8, - <<0, 55, 55, 55>> = <<0:PadLen, BStr/bitstring>> + <<0,55,55,55>> = <<0:PadLen, BStr/bitstring>> end; - _ -> - {ok, Msg} = asn1_wrapper:decode('P-Record', 'PersonnelRecord', - Bytes2) + false -> + Msg = decode(Opts, 'PersonnelRecord', Bytes1) end, ok. + +encode(Opts, T, V) -> + M = 'P-Record', + case proplists:get_bool(no_ok_wrapper, Opts) of + false -> + {ok,Enc} = M:encode(T, V), + Enc; + true -> + Enc = M:encode(T, V), + true = is_binary(Enc), + Enc + end. + +decode(Opts, T, E) -> + M = 'P-Record', + case {proplists:get_bool(no_ok_wrapper, Opts),M:decode(T, E)} of + {false,{ok,Val}} -> Val; + {false,{ok,Val,Rest}} -> {Val,Rest}; + {true,Result} -> Result + end. diff --git a/lib/asn1/test/test_x691.erl b/lib/asn1/test/test_x691.erl index dcfa211d80..9b141e2389 100644 --- a/lib/asn1/test/test_x691.erl +++ b/lib/asn1/test/test_x691.erl @@ -18,50 +18,25 @@ %% %% -module(test_x691). - --export([cases/2]). +-export([cases/1]). -include_lib("test_server/include/test_server.hrl"). -cases(Erule,Variant) -> - MsgA1 = a1(), - ?line {ok,B1} = asn1_wrapper:encode('P-RecordA1','PersonnelRecord',MsgA1), - ?line {ok,MsgA1} = asn1_wrapper:decode('P-RecordA1','PersonnelRecord',B1), - io:format("compare_format(~p,B1) ->~p~nencval(a1,~p,binary) ->~p~n", - [Erule, - compare_format(Erule,B1), - Variant, - encval(a1,Variant,binary)]), - ?line true = (compare_format(Erule,B1) == encval(a1,Variant,binary)), - - MsgA2 = a2(), - ?line {ok,B2} = asn1_wrapper:encode('P-RecordA2','PersonnelRecord',MsgA2), - ?line {ok,MsgA2} = asn1_wrapper:decode('P-RecordA2','PersonnelRecord',B2), - io:format("compare_format(~p,B2) ->~p~nencval(a2,~p,binary) ->~p~n", - [Erule, - compare_format(Erule,B2), - Variant, - encval(a2,Variant,binary)]), - ?line true = (compare_format(Erule,B2) == encval(a2,Variant,binary)), - - MsgA3 = a3(), - ?line {ok,B3} = asn1_wrapper:encode('P-RecordA3','PersonnelRecord',MsgA3), - ?line {ok,MsgA3} = asn1_wrapper:decode('P-RecordA3','PersonnelRecord',B3), - io:format("compare_format(~p,B3) ->~p~nencval(a3,~p,binary) ->~p~n", - [Erule, - compare_format(Erule,B3), - Variant, - encval(a3,Variant,binary)]), - ?line true = (compare_format(Erule,B3) == encval(a3,Variant,binary)). - -compare_format(Erule,Val) when is_list(Val) -> - compare_format(Erule,list_to_binary(Val)); -%% compare_format(per,Val) -> -%% binary_to_list(Val); -compare_format(_,Val) -> - Val. - -a1() -> +cases(Erule) -> + _ = [begin + Mod = module(Name), + Msg = msg(Name), + Hex = encval(Name, Erule), + Enc = asn1_test_lib:hex_to_bin(Hex), + Enc = asn1_test_lib:roundtrip_enc(Mod, 'PersonnelRecord', Msg) + end || Name <- [a1,a2,a3]], + ok. + +module(a1) -> 'P-RecordA1'; +module(a2) -> 'P-RecordA2'; +module(a3) -> 'P-RecordA3'. + +msg(a1) -> {'PersonnelRecord', {'Name',"John", "P", "Smith"}, "Director", @@ -73,12 +48,10 @@ a1() -> "19571111"}, {'ChildInformation', {'Name', "Susan", "B", "Jones"}, - "19590717"}]}. - -a2() -> - a1(). - -a3() -> + "19590717"}]}; +msg(a2) -> + msg(a1); +msg(a3) -> {'PersonnelRecord', {'Name',"John", "P", "Smith"}, "Director", @@ -94,119 +67,15 @@ a3() -> "19590717", female}]}. -encval(An,Variant,Encoding) when Encoding == hex; Encoding == binary -> - Msg = encval(An,Variant), - encoding(Encoding,Msg). - -encval(a1,aligned) -> +encval(a1, per) -> "80044A6F 686E0150 05536D69 74680133 08446972 6563746F 72083139 37313039 3137044D 61727901 5405536D 69746802 0552616C 70680154 05536D69 74680831 39353731 31313105 53757361 6E014205 4A6F6E65 73083139 35393037 3137"; -encval(a1,unaligned) -> +encval(a1, uper) -> "824ADFA3 700D005A 7B74F4D0 02661113 4F2CB8FA 6FE410C5 CB762C1C B16E0937 0F2F2035 0169EDD3 D340102D 2C3B3868 01A80B4F 6E9E9A02 18B96ADD 8B162C41 69F5E787 700C2059 5BF765E6 10C5CB57 2C1BB16E"; -encval(a2,aligned) -> +encval(a2, per) -> "864A6F68 6E501053 6D697468 01330844 69726563 746F7219 7109170C 4D617279 5410536D 69746802 1052616C 70685410 536D6974 68195711 11105375 73616E42 104A6F6E 65731959 0717"; -encval(a2,unaligned) -> +encval(a2, uper) -> "865D51D2 888A5125 F1809984 44D3CB2E 3E9BF90C B8848B86 7396E8A8 8A5125F1 81089B93 D71AA229 4497C632 AE222222 985CE521 885D54C1 70CAC838 B8"; -encval(a3,aligned) -> +encval(a3, per) -> "40C04A6F 686E5008 536D6974 68000033 08446972 6563746F 72001971 0917034D 61727954 08536D69 74680100 52616C70 68540853 6D697468 00195711 11820053 7573616E 42084A6F 6E657300 19590717 010140"; -encval(a3,unaligned) -> +encval(a3, uper) -> "40CBAA3A 5108A512 5F180330 889A7965 C7D37F20 CB8848B8 19CE5BA2 A114A24B E3011372 7AE35422 94497C61 95711118 22985CE5 21842EAA 60B832B2 0E2E0202 80". - -encoding(binary,Msg) -> - list_to_binary(bin(Msg)); -encoding(hex,Msg) -> - hex(Msg). - -bin(Msg) -> - HexList = hex(Msg), - Fun = fun([H1,H2|Rest],F) -> [(H1 bsl 4) + H2|F(Rest,F)];([],_) -> [] end, - Fun(HexList,Fun). - -hex(Msg) -> - [to_hex(X)||X <- Msg,X /= $ ]. - -to_hex(I) when I >= $0, I =< $9 -> - I-48; -to_hex(C) when C >= $A,C =< $F -> - C - 55. - -%% ex('EUTRA','BCCH-DL-SCH-Message',1) -> -%% {'BCCH-DL-SCH-Message', -%% {c1, -%% {systemInformation1, -%% {'SystemInformationBlockType1', -%% {'SystemInformationBlockType1_cellAccessRelatedInformation', -%% [{'SystemInformationBlockType1_cellAccessRelatedInformation_SOF', -%% {'PLMN-Identity'}, -%% true}, -%% {'SystemInformationBlockType1_cellAccessRelatedInformation_SOF', -%% {'PLMN-Identity'}, -%% false}, -%% {'SystemInformationBlockType1_cellAccessRelatedInformation_SOF', -%% {'PLMN-Identity'}, -%% true}], -%% {'TrackingAreaCode'}, -%% {'CellIdentity'}, -%% false, -%% true, -%% true, -%% true}, -%% {'SystemInformationBlockType1_cellSelectionInfo', -%% -50}, -%% 24, -%% [{'SystemInformationBlockType1_schedulinInformation_SOF', -%% {'SystemInformationBlockType1_schedulinInformation_SOF_si-MessageType'}, -%% ms320, -%% {'SystemInformationBlockType1_schedulinInformation_SOF_sib-MappingInfo'} -%% }], -%% 0 -%% } -%% } -%% } -%% }. - -%% eutra1(msg) -> -%% {'BCCH-BCH-Message',{'MasterInformationBlock',[0,1,0,1],[1,0,1,0],{'PHICH-Configuration',short,ffs},[1,0,1,0,0,0,0,0]}}; -%% eutra1(result) -> -%% <<90,80,0>>. - -%% eutra2(msg) -> -%% {'BCCH-DL-SCH-Message', -%% {c1, -%% {systemInformation1, -%% {'SystemInformationBlockType1', -%% {'SystemInformationBlockType1_cellAccessRelatedInformation', -%% [{'SystemInformationBlockType1_cellAccessRelatedInformation_plmn-IdentityList_SEQOF',{'PLMN-Identity'},true}, -%% {'SystemInformationBlockType1_cellAccessRelatedInformation_plmn-IdentityList_SEQOF',{'PLMN-Identity'},false}, -%% {'SystemInformationBlockType1_cellAccessRelatedInformation_plmn-IdentityList_SEQOF',{'PLMN-Identity'},true}], -%% {'TrackingAreaCode'}, -%% {'CellIdentity'}, -%% false, -%% true, -%% true, -%% true -%% }, -%% {'SystemInformationBlockType1_cellSelectionInfo',-50}, -%% 24, -%% [{'SystemInformationBlockType1_schedulinInformation_SEQOF', -%% {'SystemInformationBlockType1_schedulinInformation_SEQOF_si-MessageType'}, -%% ms320, -%% {'SystemInformationBlockType1_schedulinInformation_SEQOF_sib-MappingInfo'}}], -%% 0 -%% } -%% } -%% } -%% }; -%% eutra2(result) -> -%% %% 55 5C A5 E0 -%% <<85,92,165,224>>. - - - -%% compare([H|T1],[H|T2],Acc) -> -%% compare(T1,T2,[H|Acc]); -%% compare([],[],_Acc) -> -%% ok; -%% compare(L1,L2,Acc) -> -%% {miss_match,L1,L2,lists:reverse(Acc)}. - - diff --git a/lib/asn1/vsn.mk b/lib/asn1/vsn.mk index b75de179dc..0861fc2681 100644 --- a/lib/asn1/vsn.mk +++ b/lib/asn1/vsn.mk @@ -1,2 +1,2 @@ #next version number to use is 2.0 -ASN1_VSN = 2.0.2 +ASN1_VSN = 2.0.3 diff --git a/lib/common_test/doc/src/common_test_app.xml b/lib/common_test/doc/src/common_test_app.xml index 84adbb5723..ea4522c40b 100644 --- a/lib/common_test/doc/src/common_test_app.xml +++ b/lib/common_test/doc/src/common_test_app.xml @@ -99,11 +99,11 @@ be executed by Common Test. A test case is represented by an atom, the name of the test case function. A test case group is represented by a <c>group</c> tuple, where <c>GroupName</c>, - an atom, is the name of the group (defined in <c><seealso marker="#Module:groups-0">groups/0</seealso></c>). + an atom, is the name of the group (defined in <seealso marker="#Module:groups-0"><c>groups/0</c></seealso>). Execution properties for groups may also be specified, both for a top level group and for any of its sub-groups. Group execution properties specified here, will override - properties in the group definition (see <c><seealso marker="#Module:groups-0">groups/0</seealso></c>). + properties in the group definition (see <seealso marker="#Module:groups-0"><c>groups/0</c></seealso>). (With value <c>default</c>, the group definition properties will be used).</p> @@ -186,8 +186,8 @@ test cases in the suite).</p> <p>The <c>timetrap</c> tag sets the maximum time each - test case is allowed to execute (including <c><seealso marker="#Module:init_per_testcase-2">init_per_testcase/2</seealso></c> - and <c><seealso marker="#Module:end_per_testcase-2">end_per_testcase/2</seealso></c>). If the timetrap time is + test case is allowed to execute (including <seealso marker="#Module:init_per_testcase-2"><c>init_per_testcase/2</c></seealso> + and <seealso marker="#Module:end_per_testcase-2"><c>end_per_testcase/2</c></seealso>). If the timetrap time is exceeded, the test case fails with reason <c>timetrap_timeout</c>. A <c>TimeFunc</c> function can be used to set a new timetrap by returning a <c>TimeVal</c>. It may also be @@ -203,11 +203,11 @@ in any of the configuration files, all test cases are skipped. For more information about the 'require' functionality, see the reference manual for the function - <c><seealso marker="ct#require-1">ct:require/1/2</seealso></c>.</p> + <seealso marker="ct#require-1"><c>ct:require/1/2</c></seealso>.</p> <p>With <c>userdata</c>, it is possible for the user to specify arbitrary test suite related information which can be - read by calling <c><seealso marker="ct#userdata-2">ct:userdata/2</seealso></c>.</p> + read by calling <seealso marker="ct#userdata-2"><c>ct:userdata/2</c></seealso>.</p> <p>The <c>ct_hooks</c> tag specifies which <seealso marker="ct_hooks_chapter">Common Test Hooks</seealso> @@ -266,7 +266,7 @@ <p>This function is called as the last test case in the suite. It is meant to be used for cleaning up after - <c><seealso marker="#Module:init_per_suite-1">init_per_suite/1</seealso></c>. + <seealso marker="#Module:init_per_suite-1"><c>init_per_suite/1</c></seealso>. For information on <c>save_config</c>, please see <seealso marker="dependencies_chapter#save_config">Dependencies between Test Cases and Suites</seealso> in the User's Guide.</p> @@ -313,13 +313,13 @@ return a list of tagged tuples that specify various properties related to the execution of a test case group (i.e. its test cases and sub-groups). Properties set by - <c><seealso marker="#Module:group-1">group/1</seealso></c> override + <seealso marker="#Module:group-1"><c>group/1</c></seealso> override properties with the same key that have been previously set by - <c><seealso marker="#Module:suite-0">suite/0</seealso></c>.</p> + <seealso marker="#Module:suite-0"><c>suite/0</c></seealso>.</p> <p>The <c>timetrap</c> tag sets the maximum time each - test case is allowed to execute (including <c><seealso marker="#Module:init_per_testcase-2">init_per_testcase/2</seealso></c> - and <c><seealso marker="#Module:end_per_testcase-2">end_per_testcase/2</seealso></c>). If the timetrap time is + test case is allowed to execute (including <seealso marker="#Module:init_per_testcase-2"><c>init_per_testcase/2</c></seealso> + and <seealso marker="#Module:end_per_testcase-2"><c>end_per_testcase/2</c></seealso>). If the timetrap time is exceeded, the test case fails with reason <c>timetrap_timeout</c>. A <c>TimeFunc</c> function can be used to set a new timetrap by returning a <c>TimeVal</c>. It may also be @@ -334,11 +334,11 @@ in any of the configuration files, all test cases in this group are skipped. For more information about the 'require' functionality, see the reference manual for the function - <c><seealso marker="ct#require-1">ct:require/1/2</seealso></c>.</p> + <seealso marker="ct#require-1"><c>ct:require/1/2</c></seealso>.</p> <p>With <c>userdata</c>, it is possible for the user to specify arbitrary test case group related information which can be - read by calling <c><seealso marker="ct#userdata-2">ct:userdata/2</seealso></c>.</p> + read by calling <seealso marker="ct#userdata-2"><c>ct:userdata/2</c></seealso>.</p> <p>The <c>ct_hooks</c> tag specifies which <seealso marker="ct_hooks_chapter">Common Test Hooks</seealso> @@ -371,7 +371,7 @@ test case group. It typically contains initializations which are common for all test cases and sub-groups in the group, and which shall only be performed once. <c>GroupName</c> is the name of the - group, as specified in the group definition (see <c><seealso marker="#Module:groups-0">groups/0</seealso></c>). The + group, as specified in the group definition (see <seealso marker="#Module:groups-0"><c>groups/0</c></seealso>). The <c>Config</c> parameter is the configuration data which can be modified here. The return value of this function is given as <c>Config</c> to all test cases and sub-groups in the group. If <c>{skip,Reason}</c> @@ -400,10 +400,10 @@ <p> OPTIONAL </p> <p>This function is called after the execution of a test case group is finished. - It is meant to be used for cleaning up after <c><seealso marker="#Module:init_per_group-2">init_per_group/2</seealso></c>. + It is meant to be used for cleaning up after <seealso marker="#Module:init_per_group-2"><c>init_per_group/2</c></seealso>. By means of <c>{return_group_result,Status}</c>, it is possible to return a status value for a nested sub-group. The status can be retrieved in - <c><seealso marker="#Module:end_per_group-2">end_per_group/2</seealso></c> for the group on the level above. The status will also + <seealso marker="#Module:end_per_group-2"><c>end_per_group/2</c></seealso> for the group on the level above. The status will also be used by Common Test for deciding if execution of a group should proceed in case the property <c>sequence</c> or <c>repeat_until_*</c> is set.</p> @@ -454,7 +454,7 @@ <p> OPTIONAL </p> <p> This function is called after each test case, and can be used - to clean up after <c><seealso marker="#Module:init_per_testcase-2">init_per_testcase/2</seealso></c> and the test case. + to clean up after <seealso marker="#Module:init_per_testcase-2"><c>init_per_testcase/2</c></seealso> and the test case. Any return value (besides <c>{fail,Reason}</c> and <c>{save_config,SaveConfig}</c>) is ignored. By returning <c>{fail,Reason}</c>, <c>TestCase</c> will be marked as failed (even though it was actually successful in the sense that it returned @@ -496,15 +496,15 @@ <p>This is the test case info function. It is supposed to return a list of tagged tuples that specify various properties related to the execution of this particular test case. - Properties set by <c><seealso marker="#Module:Testcase-0">Testcase/0</seealso></c> override + Properties set by <seealso marker="#Module:Testcase-0"><c>Testcase/0</c></seealso> override properties that have been previously set for the test case - by <c><seealso marker="#Module:group-1">group/1</seealso></c> or <c><seealso marker="#Module:suite-0">suite/0</seealso></c>.</p> + by <seealso marker="#Module:group-1"><c>group/1</c></seealso> or <seealso marker="#Module:suite-0"><c>suite/0</c></seealso>.</p> <p>The <c>timetrap</c> tag sets the maximum time the test case is allowed to execute. If the timetrap time is exceeded, the test case fails with reason - <c>timetrap_timeout</c>. <c><seealso marker="#Module:init_per_testcase-2">init_per_testcase/2</seealso></c> - and <c><seealso marker="#Module:end_per_testcase-2">end_per_testcase/2</seealso></c> are included in the + <c>timetrap_timeout</c>. <seealso marker="#Module:init_per_testcase-2"><c>init_per_testcase/2</c></seealso> + and <seealso marker="#Module:end_per_testcase-2"><c>end_per_testcase/2</c></seealso> are included in the timetrap time. A <c>TimeFunc</c> function can be used to set a new timetrap by returning a <c>TimeVal</c>. It may also be used to trigger a timetrap timeout by, at some point, returning a @@ -518,15 +518,15 @@ configuration files, the test case is skipped. For more information about the 'require' functionality, see the reference manual for the function - <c><seealso marker="ct#require-1">ct:require/1/2</seealso></c>.</p> + <seealso marker="ct#require-1"><c>ct:require/1/2</c></seealso>.</p> <p>If <c>timetrap</c> and/or <c>require</c> is not set, the - default values specified by <c><seealso marker="#Module:suite-0">suite/0</seealso></c> (or - <c><seealso marker="#Module:group-1">group/1</seealso></c>) will be used.</p> + default values specified by <seealso marker="#Module:suite-0"><c>suite/0</c></seealso> (or + <seealso marker="#Module:group-1"><c>group/1</c></seealso>) will be used.</p> <p>With <c>userdata</c>, it is possible for the user to specify arbitrary test case related information which can be - read by calling <c><seealso marker="ct#userdata-3">ct:userdata/3</seealso></c>.</p> + read by calling <seealso marker="ct#userdata-3"><c>ct:userdata/3</c></seealso>.</p> <p>Other tuples than the ones defined will simply be ignored.</p> @@ -554,7 +554,7 @@ <p>This is the implementation of a test case. Here you must call the functions you want to test, and do whatever you need to check the result. If something fails, make sure the - function causes a runtime error, or call <c><seealso marker="ct#fail-1">ct:fail/1/2</seealso></c> + function causes a runtime error, or call <seealso marker="ct#fail-1"><c>ct:fail/1/2</c></seealso> (which also causes the test case process to terminate).</p> <p>Elements from the <c>Config</c> list can e.g. be read @@ -582,7 +582,7 @@ Test Cases and Suites</seealso> in the User's Guide.</p> </desc> </func> - + </funcs> </erlref> diff --git a/lib/common_test/doc/src/config_file_chapter.xml b/lib/common_test/doc/src/config_file_chapter.xml index 1849c17bb8..d3068db17b 100644 --- a/lib/common_test/doc/src/config_file_chapter.xml +++ b/lib/common_test/doc/src/config_file_chapter.xml @@ -80,7 +80,7 @@ test is skipped (unless a default value has been specified, see the <seealso marker="write_test_chapter#info_function">test case info function</seealso> chapter for details). There is also a function - <c><seealso marker="ct#require-1">ct:require/1/2</seealso></c> which can be called from a test case + <seealso marker="ct#require-1"><c>ct:require/1/2</c></seealso> which can be called from a test case in order to check if a specific variable is available. The return value from this function must be checked explicitly and appropriate action be taken depending on the result (e.g. to skip the test case @@ -90,7 +90,7 @@ info-list should look like this: <c>{require,CfgVarName}</c> or <c>{require,AliasName,CfgVarName}</c>. The arguments <c>AliasName</c> and <c>CfgVarName</c> are the same as the - arguments to <c><seealso marker="ct#require-1">ct:require/1/2</seealso></c> which are described in the + arguments to <seealso marker="ct#require-1"><c>ct:require/1/2</c></seealso> which are described in the reference manual for <seealso marker="ct">ct</seealso>. <c>AliasName</c> becomes an alias for the configuration variable, and can be used as reference to the configuration data value. @@ -103,7 +103,7 @@ (or test case) and improve readability.</item> </list> <p>To read the value of a config variable, use the function - <c><seealso marker="ct#get_config-1">get_config/1/2/3</seealso></c> + <seealso marker="ct#get_config-1"><c>get_config/1/2/3</c></seealso> which is also described in the reference manual for <seealso marker="ct">ct</seealso>.</p> <p>Example:</p> @@ -121,7 +121,7 @@ <section> <title>Using configuration variables defined in multiple files</title> <p>If a configuration variable is defined in multiple files and you - want to access all possible values, you may use the <c><seealso marker="ct#get_config-3">ct:get_config/3</seealso></c> + want to access all possible values, you may use the <seealso marker="ct#get_config-3"><c>ct:get_config/3</c></seealso> function and specify <c>all</c> in the options list. The values will then be returned in a list and the order of the elements corresponds to the order that the config files were specified at startup. Please see @@ -133,7 +133,7 @@ <marker id="encrypted_config_files"></marker> <p>It is possible to encrypt configuration files containing sensitive data if these files must be stored in open and shared directories.</p> - <p>Call <c><seealso marker="ct#encrypt_config_file-2">ct:encrypt_config_file/2/3</seealso></c> to have Common Test encrypt a + <p>Call <seealso marker="ct#encrypt_config_file-2"><c>ct:encrypt_config_file/2/3</c></seealso> to have Common Test encrypt a specified file using the DES3 function in the OTP <c>crypto</c> application. The encrypted file can then be used as a regular configuration file, in combination with other encrypted files or normal text files. The key @@ -142,7 +142,7 @@ <c>decrypt_file</c> flag/option, or a key file in a predefined location.</p> <p>Common Test also provides decryption functions, - <c><seealso marker="ct#decrypt_config_file-2">ct:decrypt_config_file/2/3</seealso></c>, for recreating the original text + <seealso marker="ct#decrypt_config_file-2"><c>ct:decrypt_config_file/2/3</c></seealso>, for recreating the original text files.</p> <p>Please see the <seealso marker="ct">ct</seealso> reference manual for @@ -152,8 +152,8 @@ <section> <title>Opening connections by using configuration data</title> <p>There are two different methods for opening a connection - by means of the support functions in e.g. <c><seealso marker="ct_ssh">ct_ssh</seealso></c>, <c><seealso marker="ct_ftp">ct_ftp</seealso></c>, - and <c><seealso marker="ct_telnet">ct_telnet</seealso></c>:</p> + by means of the support functions in e.g. <seealso marker="ct_ssh"><c>ct_ssh</c></seealso>, <seealso marker="ct_ftp"><c>ct_ftp</c></seealso>, + and <seealso marker="ct_telnet"><c>ct_telnet</c></seealso>:</p> <list> <item>Using a configuration target name (an alias) as reference.</item> <item>Using the configuration variable as reference.</item> diff --git a/lib/common_test/doc/src/cover_chapter.xml b/lib/common_test/doc/src/cover_chapter.xml index 2d504b485f..a215c8c2f3 100644 --- a/lib/common_test/doc/src/cover_chapter.xml +++ b/lib/common_test/doc/src/cover_chapter.xml @@ -94,7 +94,7 @@ <p><c>$ ct_run -dir $TESTOBJS/db -cover $TESTOBJS/db/config/db.coverspec</c></p> <p>You may also pass the cover specification file name in a - call to <c><seealso marker="ct#run_test-1">ct:run_test/1</seealso></c>, by adding a <c>{cover,CoverSpec}</c> + call to <seealso marker="ct#run_test-1"><c>ct:run_test/1</c></seealso>, by adding a <c>{cover,CoverSpec}</c> tuple to the <c>Opts</c> argument. Also, you can of course enable code coverage in your test specifications (read more in the chapter about @@ -102,8 +102,8 @@ specifications</seealso>).</p> </section> - <marker id="cover_stop"></marker> <section> + <marker id="cover_stop"></marker> <title>Stopping the cover tool when tests are completed</title> <p>By default the Cover tool is automatically stopped when the tests are completed. This causes the original (non cover @@ -120,8 +120,8 @@ <p>The option can be set by using the <c>-cover_stop</c> flag with <c>ct_run</c>, by adding <c>{cover_stop,true|false}</c> to the - Opts argument to <c><seealso - marker="ct#run_test-1">ct:run_test/1</seealso></c>, or by adding + Opts argument to <seealso + marker="ct#run_test-1"><c>ct:run_test/1</c></seealso>, or by adding a <c>cover_stop</c> term in your test specification (see chapter about <seealso marker="run_test_chapter#test_specifications">test @@ -189,8 +189,8 @@ specification file for Common Test).</p> </section> - <marker id="cross_cover"/> <section> + <marker id="cross_cover"/> <title>Cross cover analysis</title> <p>The cross cover mechanism allows cover analysis of modules across multiple tests. It is useful if some code, e.g. a library diff --git a/lib/common_test/doc/src/ct_hooks_chapter.xml b/lib/common_test/doc/src/ct_hooks_chapter.xml index fe871eb516..60cd9be918 100644 --- a/lib/common_test/doc/src/ct_hooks_chapter.xml +++ b/lib/common_test/doc/src/ct_hooks_chapter.xml @@ -192,12 +192,12 @@ <section> <title>External configuration data and Logging</title> <p>It's possible in the CTH to read configuration data values - by calling <c><seealso marker="ct#get_config-1">ct:get_config/1/2/3</seealso></c> (as explained in the + by calling <seealso marker="ct#get_config-1"><c>ct:get_config/1/2/3</c></seealso> (as explained in the <seealso marker="config_file_chapter#require_config_data"> External configuration data</seealso> chapter). The config variables in question must, as always, first have been <c>required</c> by means of a suite-, group-, or test case info function, - or the <c><seealso marker="ct#require-1">ct:require/1/2</seealso></c> function. Note that the latter can also be used + or the <seealso marker="ct#require-1"><c>ct:require/1/2</c></seealso> function. Note that the latter can also be used in CT hook functions.</p> <p>The CT hook functions may call any of the logging functions available in the <c>ct</c> interface to print information to the log files, or to @@ -252,13 +252,13 @@ {ok, Handle} -> {[{db_handle, Handle} | Config], CTHState#state{ handle = Handle }} end.</code> - <note>If using multiple CTHs, the first part of the return tuple will be + <note><p>If using multiple CTHs, the first part of the return tuple will be used as input for the next CTH. So in the case above the next CTH might get <c>{fail,Reason}</c> as the second parameter. If you have many CTHs which interact, it might be a good idea to not let each CTH return <c>fail</c> or <c>skip</c>. Instead return that an action should be taken through the <c>Config</c> list and implement a CTH which at the end takes - the correct action. </note> + the correct action.</p></note> </section> @@ -301,9 +301,9 @@ post_end_per_testcase(_TC, Config, Return, CTHState) -> %% Do nothing if tc does not crash. {Return, CTHState}.</code> - <note>Recovering from a testcase failure using CTHs should only be done as + <note><p>Recovering from a testcase failure using CTHs should only be done as a last resort. If used wrongly it could become very difficult to - determine which tests pass or fail in a test run</note> + determine which tests pass or fail in a test run</p></note> </section> @@ -322,6 +322,34 @@ post_end_per_testcase(_TC, Config, Return, CTHState) -> </section> + <marker id="synchronizing"/> + <section> + <title>Synchronizing external user applications with Common Test</title> + <p>CTHs can be used to synchronize test runs with external user applications. + The init function may e.g. start and/or communicate with an application that + has the purpose of preparing the SUT for an upcoming test run, or maybe + initialize a database for saving test data to during the test run. The + terminate function may similarly order such an application to reset the SUT + after the test run, and/or tell the application to finish active sessions + and terminate. + Any system error- or progress reports generated during the init- or + termination stage will be saved in the + <seealso marker="run_test_chapter#pre_post_test_io_log">Pre- + and post test I/O log</seealso>. (This is also true for any printouts made + with <c>ct:log/2</c> and <c>ct:pal/2</c>).</p> + <p>In order to ensure that Common Test doesn't start executing tests, or + closes its log files and shuts down, before the external application + is ready for it, Common Test may be synchronized with the application. + During startup and shutdown, Common Test can be suspended, simply by + having a CTH evaluate a <c>receive</c> expression in the init- or terminate + function. The macros <c>?CT_HOOK_INIT_PROCESS</c> (the process executing the hook + init function) and <c>?CT_HOOK_TERMINATE_PROCESS</c> (the process executing + the hook terminate function), each specifies the name of the correct Common Test + process to send a message to in order to return from the <c>receive</c>. + These macros are defined in <c>ct.hrl</c>. + </p> + </section> + <marker id="example"/> <section> <title>Example CTH</title> diff --git a/lib/common_test/doc/src/ct_master_chapter.xml b/lib/common_test/doc/src/ct_master_chapter.xml index e95823a560..37a0805055 100644 --- a/lib/common_test/doc/src/ct_master_chapter.xml +++ b/lib/common_test/doc/src/ct_master_chapter.xml @@ -220,6 +220,7 @@ <p>The default <seealso marker="ct_slave">ct_slave</seealso> callback module, which is part of the Common Test application, has the following features: + </p> <list> <item>Starting Erlang target nodes on local or remote hosts (ssh is used for communication). @@ -237,7 +238,6 @@ Functions can be given as a list of {Module, Function, Arguments} tuples. </item> </list> - </p> <p>Note that it is possible to specify an <c>eval</c> term for the node as well as <c>startup_functions</c> in the <c>node_start</c> options list. In this case first the node will be started, then the <c>startup_functions</c> are diff --git a/lib/common_test/doc/src/ct_run.xml b/lib/common_test/doc/src/ct_run.xml index a6e61984e6..39259b092a 100644 --- a/lib/common_test/doc/src/ct_run.xml +++ b/lib/common_test/doc/src/ct_run.xml @@ -36,8 +36,6 @@ OS command line. </comsummary> - <marker id="top"></marker> - <description> <p>The <c>ct_run</c> program is automatically installed with Erlang/OTP and Common Test (please see the Installation chapter in the Common @@ -48,7 +46,7 @@ particular mode.</p> <p>There is an interface function that corresponds to this program, - called <c><seealso marker="ct#run_test-1">ct:run_test/1</seealso></c>, for starting Common Test from the Erlang + called <seealso marker="ct#run_test-1"><c>ct:run_test/1</c></seealso>, for starting Common Test from the Erlang shell (or an Erlang program). Please see the <c>ct</c> man page for details.</p> @@ -83,9 +81,9 @@ <p>it prints all valid start flags to stdout.</p> </description> - <marker id="ct_run"></marker> <section> + <marker id="ct_run"></marker> <title>Run tests from command line</title> <pre> ct_run [-dir TestDir1 TestDir2 .. TestDirN] | diff --git a/lib/common_test/doc/src/event_handler_chapter.xml b/lib/common_test/doc/src/event_handler_chapter.xml index 824240ef7d..65cc2a4042 100644 --- a/lib/common_test/doc/src/event_handler_chapter.xml +++ b/lib/common_test/doc/src/event_handler_chapter.xml @@ -64,7 +64,7 @@ <marker id="usage"></marker> <title>Usage</title> <p>Event handlers may be installed by means of an <c>event_handler</c> - start flag (<c>ct_run</c>) or option (<c><seealso marker="ct#run_test-1">ct:run_test/1</seealso></c>), where the + start flag (<c>ct_run</c>) or option (<seealso marker="ct#run_test-1"><c>ct:run_test/1</c></seealso>), where the argument specifies the names of one or more event handler modules. Example:</p> <p><c>$ ct_run -suite test/my_SUITE -event_handler handlers/my_evh1 @@ -78,7 +78,7 @@ example).</p> <p>An event_handler tuple in the argument <c>Opts</c> has the following - definition (see also <c><seealso marker="ct#run_test-1">ct:run_test/1</seealso></c> in the reference manual):</p> + definition (see also <seealso marker="ct#run_test-1"><c>ct:run_test/1</c></seealso> in the reference manual):</p> <pre> {event_handler,EventHandlers} @@ -224,8 +224,9 @@ <c>end_per_testcase</c> for the case failed. </p></item> + <item> <marker id="tc_auto_skip"></marker> - <item><c>#event{name = tc_auto_skip, data = {Suite,Func,Reason}}</c> + <c>#event{name = tc_auto_skip, data = {Suite,Func,Reason}}</c> <p><c>Suite = atom()</c>, the name of the suite.</p> <p><c>Func = atom()</c>, the name of the test case or configuration function.</p> <p><c>Reason = {failed,FailReason} | @@ -251,8 +252,9 @@ the <c>tc_done</c> event. </p></item> + <item> <marker id="tc_user_skip"></marker> - <item><c>#event{name = tc_user_skip, data = {Suite,TestCase,Comment}}</c> + <c>#event{name = tc_user_skip, data = {Suite,TestCase,Comment}}</c> <p><c>Suite = atom()</c>, name of the suite.</p> <p><c>TestCase = atom()</c>, name of the test case.</p> <p><c>Comment = string()</c>, reason for skipping the test case.</p> @@ -308,7 +310,7 @@ manager can look like.</p> <note><p>To ensure that printouts to standard out (or printouts made with - <c><seealso marker="ct#log-2">ct:log/2/3</seealso></c> or <c><seealso marker="ct:pal-2">ct:pal/2/3</seealso></c>) get written to the test case log + <seealso marker="ct#log-2"><c>ct:log/2/3</c></seealso> or <seealso marker="ct:pal-2"><c>ct:pal/2/3</c></seealso>) get written to the test case log file, and not to the Common Test framework log, you can syncronize with the Common Test server by matching on the <c>tc_start</c> and <c>tc_done</c> events. In the period between these events, all IO gets directed to the diff --git a/lib/common_test/doc/src/getting_started_chapter.xml b/lib/common_test/doc/src/getting_started_chapter.xml index 06610bef25..445c731d01 100644 --- a/lib/common_test/doc/src/getting_started_chapter.xml +++ b/lib/common_test/doc/src/getting_started_chapter.xml @@ -61,13 +61,11 @@ <title>Test case execution</title> <p>Execution of test cases is handled this way:</p> - <p> <image file="tc_execution.gif"> <icaption> Successful vs unsuccessful test case execution. </icaption> </image> - </p> <p>For each test case that Common Test is told to execute, it spawns a dedicated process on which the test case function in question starts @@ -90,7 +88,7 @@ <p>As you can understand from the illustration above, Common Test requires that a test case generates a runtime error to indicate failure (e.g. by causing a bad match error or by calling <c>exit/1</c>, preferrably - through the <c><seealso marker="ct#fail-1">ct:fail/1,2</seealso></c> help function). A succesful execution is + through the <seealso marker="ct#fail-1"><c>ct:fail/1,2</c></seealso> help function). A succesful execution is indicated by means of a normal return from the test case function. </p> </section> @@ -100,13 +98,15 @@ <p>As you've seen in the basics chapter, the test suite module implements <seealso marker="common_test">callback functions</seealso> (mandatory or optional) for various purposes, e.g: + </p> <list> <item>Init/end configuration function for the test suite</item> <item>Init/end configuration function for a test case</item> <item>Init/end configuration function for a test case group</item> <item>Test cases</item> </list> - The configuration functions are optional and if you don't need them for + <p> + The configuration functions are optional and if you don't need them for your test, a test suite with one simple test case could look like this: </p> <pre> @@ -136,13 +136,11 @@ "lower level"). The data flow looks like this: </p> - <p> <image file="config.gif"> <icaption> Config data flow in the suite. </icaption> </image> - </p> <p> Here's an example of a test suite which uses configuration functions @@ -203,13 +201,11 @@ shows the log file structure: </p> - <p> <image file="html_logs.gif"> <icaption> HTML log file structure. </icaption> </image> - </p> </section> <section> diff --git a/lib/common_test/doc/src/install_chapter.xml b/lib/common_test/doc/src/install_chapter.xml index ca15cba511..7f8c606324 100644 --- a/lib/common_test/doc/src/install_chapter.xml +++ b/lib/common_test/doc/src/install_chapter.xml @@ -56,13 +56,13 @@ shell script version run_test, however, this script needs to be generated first, according to the instructions below.</p> - <p><note>Before reading on, please note that since Common Test version + <note><p>Before reading on, please note that since Common Test version 1.5, the run_test shell script is no longer required for starting tests with Common Test from the OS command line. The ct_run program (descibed above) is the new recommended command line interface for Common Test. The shell script exists mainly for legacy reasons and may not be updated in future releases of Common Test. It may even be removed. - </note></p> + </p></note> <p>Optional step to generate a shell script for starting Common Test:</p> <p>To generate the run_test shell script, navigate to the diff --git a/lib/common_test/doc/src/notes.xml b/lib/common_test/doc/src/notes.xml index cc3c5231a5..b4a5c610cf 100644 --- a/lib/common_test/doc/src/notes.xml +++ b/lib/common_test/doc/src/notes.xml @@ -32,6 +32,99 @@ <file>notes.xml</file> </header> +<section><title>Common_Test 1.7.3</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Documentation is added for ct_netconfc:send and + ct_netconfc:send_rpc.</p> + <p> + Own Id: OTP-11132</p> + </item> + <item> + <p> + ct_netconfc:create_subscription only allowed one XML + element inside the 'filter' element. According to RFC5277 + it should be allowed to add any number of elements inside + the filter, so this is now corrected.</p> + <p> + Own Id: OTP-11166</p> + </item> + <item> + <p> + The error handler installed by the Common Test hook + cth_log_redirect did not respond to init:stop/1/2. This + has been corrected.</p> + <p> + Own Id: OTP-11175 Aux Id: seq12356 </p> + </item> + <item> + <p> + Calling ct:pal/2 or ct:print/2 when Common Test was not + running, would cause an exit. This has been changed and + the string is now simply printed to stdout instead.</p> + <p> + Own Id: OTP-11176</p> + </item> + <item> + <p> + Fixed problem with the cth_log_redirect hook making calls + to an undefined function in ct_logs.</p> + <p> + Own Id: OTP-11238</p> + </item> + <item> + <p> + When running tests with the 'repeat' option, the Common + Test utility process did not always terminate quickly + enough after a test run, causing the start of the next + run to fail. A monitor is now used to ensure termination + of the utility process after each test run.</p> + <p> + Own Id: OTP-11244 Aux Id: seq12396 </p> + </item> + <item> + <p> + Test Server installed an error handler (test_server_h) + only to be able to write the name of the current test + case to stdout whenever it received an error- or progress + report. This functionality was not useful and has been + removed. The built-in Common Test hook, cth_log_redirect, + has instead been improved to now also tag all error- and + progress reports in the log with suite-, group-, and/or + test case name.</p> + <p> + Own Id: OTP-11263 Aux Id: seq12251 </p> + </item> + </list> + </section> + + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + A new log, the "Pre- and Post Test I/O Log", has been + introduced, which makes it possible to capture error- and + progress reports, as well as printouts made with ct:log/2 + and ct:pal/2, before and after a test run. (Some minor + improvements of the logging system have been made at the + same time). Links to the new log are found on the Common + Test Framework Log page. The Common Test User's Guide has + been updated with information about the new log and also + with a new section on how to synchronize external + applications with Common Test by means of the CT Hook + init and terminate functions.</p> + <p> + Own Id: OTP-11272</p> + </item> + </list> + </section> + +</section> + <section><title>Common_Test 1.7.2</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/common_test/doc/src/run_test_chapter.xml b/lib/common_test/doc/src/run_test_chapter.xml index 4f826d4e31..03d98eb371 100644 --- a/lib/common_test/doc/src/run_test_chapter.xml +++ b/lib/common_test/doc/src/run_test_chapter.xml @@ -21,7 +21,7 @@ </legalnotice> - <title>Running Tests</title> + <title>Running Tests and Analyzing Results</title> <prepared>Peter Andersson, Kenneth Lundin</prepared> <docno></docno> <date></date> @@ -105,8 +105,8 @@ RPC from a remote node.</p> </section> - <marker id="ct_run"></marker> <section> + <marker id="ct_run"></marker> <title>Running tests from the OS command line</title> <p>The <c>ct_run</c> program can be used for running tests from @@ -225,15 +225,15 @@ <p>Common Test provides an Erlang API for running tests. The main (and most flexible) function for specifying and executing tests is called - <c><seealso marker="ct#run_test-1">ct:run_test/1</seealso></c>. + <seealso marker="ct#run_test-1"><c>ct:run_test/1</c></seealso>. This function takes the same start parameters as - the <c><seealso marker="run_test_chapter#ct_run">ct_run</seealso></c> + the <seealso marker="run_test_chapter#ct_run"><c>ct_run</c></seealso> program described above, only the flags are instead given as options in a list of key-value tuples. E.g. a test specified with <c>ct_run</c> like:</p> <p><c>$ ct_run -suite ./my_SUITE -logdir ./results</c></p> - <p>is with <c><seealso marker="ct#run_test-1">ct:run_test/1</seealso></c> specified as:</p> + <p>is with <seealso marker="ct#run_test-1"><c>ct:run_test/1</c></seealso> specified as:</p> <p><c>1> ct:run_test([{suite,"./my_SUITE"},{logdir,"./results"}]).</c></p> <p>The function returns the test result, represented by the tuple: @@ -245,7 +245,7 @@ <section> <title>Releasing the Erlang shell</title> <p>During execution of tests, started with - <c><seealso marker="ct#run_test-1">ct:run_test/1</seealso></c>, + <seealso marker="ct#run_test-1"><c>ct:run_test/1</c></seealso>, the Erlang shell process, controlling stdin, will remain the top level process of the Common Test system of processes. The result is that the Erlang shell is not available for interaction during @@ -260,19 +260,19 @@ <c>ct:run_test/1</c> returns the pid of this process rather than the test result - which instead is printed to tty at the end of the test run.</p> <note><p>Note that in order to use the - <c><seealso marker="ct#break-1">ct:break/1/2</seealso></c> and - <c><seealso marker="ct#continue-0">ct:continue/0/1</seealso></c> functions, + <seealso marker="ct#break-1"><c>ct:break/1/2</c></seealso> and + <seealso marker="ct#continue-0"><c>ct:continue/0/1</c></seealso> functions, <c>release_shell</c> <em>must</em> be set to <c>true</c>.</p></note> </section> <p>For detailed documentation about - <c><seealso marker="ct#run_test-1">ct:run_test/1</seealso></c>, + <seealso marker="ct#run_test-1"><c>ct:run_test/1</c></seealso>, please see the - <c><seealso marker="ct#run_test-1">ct</seealso></c> manual page.</p> + <seealso marker="ct#run_test-1"><c>ct</c></seealso> manual page.</p> </section> - <marker id="group_execution"></marker> <section> + <marker id="group_execution"></marker> <title>Test case group execution</title> <p>With the <c>ct_run</c> flag, or <c>ct:run_test/1</c> option <c>group</c>, @@ -442,9 +442,9 @@ for trying out various operations during test suite development.</p> <p>To invoke the interactive shell mode, you can start an Erlang shell - manually and call <c><seealso marker="ct#install-1">ct:install/1</seealso></c> to install any configuration + manually and call <seealso marker="ct#install-1"><c>ct:install/1</c></seealso> to install any configuration data you might need (use <c>[]</c> as argument otherwise), then - call <c><seealso marker="ct#start_interactive-0">ct:start_interactive/0</seealso></c> to start Common Test. If you use + call <seealso marker="ct#start_interactive-0"><c>ct:start_interactive/0</c></seealso> to start Common Test. If you use the <c>ct_run</c> program, you may start the Erlang shell and Common Test in the same go by using the <c>-shell</c> and, optionally, the <c>-config</c> and/or <c>-userconfig</c> flag. Examples: @@ -463,8 +463,8 @@ <p>If any functions using "required config data" (e.g. ct_telnet or ct_ftp functions) are to be called from the erlang shell, config - data must first be required with <c><seealso marker="ct#require-1"> - ct:require/1/2</seealso></c>. This is + data must first be required with <seealso marker="ct#require-1"><c> + ct:require/1/2</c></seealso>. This is equivalent to a <c>require</c> statement in the <seealso marker="write_test_chapter#suite">Test Suite Info Function</seealso> or in the <seealso @@ -491,11 +491,11 @@ is not supported.</p> <p>If you wish to exit the interactive mode (e.g. to start an - automated test run with <c><seealso marker="ct#run_test-1">ct:run_test/1</seealso></c>), call the function - <c><seealso marker="ct#stop_interactive-0">ct:stop_interactive/0</seealso></c>. This shuts down the + automated test run with <seealso marker="ct#run_test-1"><c>ct:run_test/1</c></seealso>), call the function + <seealso marker="ct#stop_interactive-0"><c>ct:stop_interactive/0</c></seealso>. This shuts down the running <c>ct</c> application. Associations between configuration names and data created with <c>require</c> are - consequently deleted. <c><seealso marker="ct#start_interactive-0">ct:start_interactive/0</seealso></c> will get you + consequently deleted. <seealso marker="ct#start_interactive-0"><c>ct:start_interactive/0</c></seealso> will get you back into interactive mode, but the previous state is not restored.</p> </section> @@ -503,7 +503,7 @@ <title>Step by step execution of test cases with the Erlang Debugger</title> <p>By means of <c>ct_run -step [opts]</c>, or by passing the - <c>{step,Opts}</c> option to <c><seealso marker="ct#run_test-1">ct:run_test/1</seealso></c>, it is possible + <c>{step,Opts}</c> option to <seealso marker="ct#run_test-1"><c>ct:run_test/1</c></seealso>, it is possible to get the Erlang Debugger started automatically and use its graphical interface to investigate the state of the current test case and to execute it step by step and/or set execution breakpoints.</p> @@ -527,17 +527,17 @@ with <c>dir</c>.</p> </section> - <marker id="test_specifications"></marker> <section> + <marker id="test_specifications"></marker> <title>Test Specifications</title> <section> <title>General description</title> <p>The most flexible way to specify what to test, is to use a so called test specification. A test specification is a sequence of Erlang terms. The terms are normally declared in one or more text files - (see <c><seealso marker="ct#run_test-1">ct:run_test/1</seealso></c>), but + (see <seealso marker="ct#run_test-1"><c>ct:run_test/1</c></seealso>), but may also be passed to Common Test on the form of a list (see - <c><seealso marker="ct#run_testspec-1">ct:run_testspec/1</seealso></c>). + <seealso marker="ct#run_testspec-1"><c>ct:run_testspec/1</c></seealso>). There are two general types of terms: configuration terms and test specification terms.</p> <p>With configuration terms it is possible to e.g. label the test @@ -989,7 +989,7 @@ <c>ct_run</c>. This forces Common Test to ignore unrecognizable terms. Note that in this mode, Common Test is not able to check the specification for errors as efficiently as if the scanner runs in default mode. - If <c><seealso marker="ct#run_test-1">ct:run_test/1</seealso></c> is used + If <seealso marker="ct#run_test-1"><c>ct:run_test/1</c></seealso> is used for starting the tests, the relaxed scanner mode is enabled by means of the tuple: <c>{allow_user_terms,true}</c></p> </section> @@ -999,7 +999,7 @@ <title>Running tests from the Web based GUI</title> <p>The web based GUI, VTS, is started with the - <c><seealso marker="run_test_chapter#ct_run">ct_run</seealso></c> + <seealso marker="run_test_chapter#ct_run"><c>ct_run</c></seealso> program. From the GUI you can load config files, and select directories, suites and cases to run. You can also state the config files, directories, suites and cases on the command line @@ -1087,18 +1087,18 @@ </list> <p>On the test run index page there is a link to the Common Test - Framework log file in which information about imported - configuration data and general test progress is written. This - log file is useful to get snapshot information about the test - run during execution. It can also be very helpful when - analyzing test results or debugging test suites.</p> + Framework Log file in which information about imported + configuration data and general test progress is written. This + log file is useful to get snapshot information about the test + run during execution. It can also be very helpful when + analyzing test results or debugging test suites.</p> <p>On the test run index page it is noted if a test has missing suites (i.e. suites that Common Test has failed to compile). Names of the missing suites can be found in the - Common Test Framework log file.</p> + Common Test Framework Log file.</p> - <p>The major logfile shows a detailed report of the test run. It + <p>The major log file shows a detailed report of the test run. It includes test suite and test case names, execution time, the exact reason for failures etc. The information is available in both a file with textual and with HTML representation. The HTML file shows a @@ -1172,6 +1172,40 @@ <url href="http://tablesorter.com">tablesorter</url> plugin, with customized sorting functions, for this implementation.</p> </section> + + <section> + <title>The Unexpected I/O Log</title> + <p>On the test suites overview page you find a link to the Unexpected I/O Log. + In this log, Common Test saves printouts made with + <c>ct:log/2</c> and <c>ct:pal/2</c>, as well as captured system error- and + progress reports, that cannot be associated with particular test cases and + therefore cannot be written to individual test case log files. This happens e.g. + if a log printout is made from an external process (not a test case process), + or if an error- or progress report comes in, during a short interval while Common + Test is not executing a test case or configuration function, <em>or</em> while + Common Test is currently executing a parallell test case group.</p> + </section> + + <section> + <marker id="pre_post_test_io_log"></marker> + <title>The Pre- and Post Test I/O Log</title> + <p>On the Common Test Framework Log page you find links to the so called + Pre- and Post Test I/O Log. In this log, Common Test saves printouts made with + <c>ct:log/2</c> and <c>ct:pal/2</c>, as well as captured system error- + and progress reports, that take place before - and after - the actual test run. + Examples of this are printouts from a CT hook init- or terminate function, or + progress reports generated when an OTP application is started from a CT hook + init function. Another example is an error report generated due to + a failure when an external application is stopped from a CT hook terminate function. + All information in these examples ends up in the Pre- and Post Test I/O Log. + For more information on how to synchronize test runs with external user + applications, please see the + <seealso marker="ct_hooks_chapter#synchronizing">Synchronizing</seealso> + section in the Common Test Hooks chapter.</p> + <p>Note that logging to file with <c>ct:log/2</c> or <c>ct:pal/2</c> + only works when Common Test is running. Printouts with <c>ct:pal/2</c> + are however always displayed on screen.</p> + </section> </section> <section> diff --git a/lib/common_test/doc/src/write_test_chapter.xml b/lib/common_test/doc/src/write_test_chapter.xml index 69b17f3c4b..055fb90641 100644 --- a/lib/common_test/doc/src/write_test_chapter.xml +++ b/lib/common_test/doc/src/write_test_chapter.xml @@ -129,8 +129,8 @@ </p> </section> - <marker id="per_testcase"/> <section> + <marker id="per_testcase"/> <title>Init and end per test case</title> <p>Each test suite module can contain the optional configuration functions @@ -173,7 +173,7 @@ </p> <p>The <c>end_per_testcase/2</c> function is called even after a - test case terminates due to a call to <c><seealso marker="ct#abort_current_testcase-1">ct:abort_current_testcase/1</seealso></c>, + test case terminates due to a call to <seealso marker="ct#abort_current_testcase-1"><c>ct:abort_current_testcase/1</c></seealso>, or after a timetrap timeout. However, <c>end_per_testcase</c> will then execute on a different process than the test case function, and in this situation, <c>end_per_testcase</c> will @@ -243,8 +243,8 @@ <note><p>The test case function argument <c>Config</c> should not be confused with the information that can be retrieved from - configuration files (using <c><seealso marker="ct#get_config-1"> - ct:get_config/1/2</seealso></c>). The Config argument + configuration files (using <seealso marker="ct#get_config-1"><c> + ct:get_config/1/2</c></seealso>). The Config argument should be used for runtime configuration of the test suite and the test cases, while configuration files should typically contain data related to the SUT. These two types of configuration data are handled @@ -303,7 +303,7 @@ <item> <p> Use this to specify arbitrary data related to the testcase. This - data can be retrieved at any time using the <c><seealso marker="ct#userdata-3">ct:userdata/3</seealso></c> + data can be retrieved at any time using the <seealso marker="ct#userdata-3"><c>ct:userdata/3</c></seealso> utility function. </p> </item> @@ -348,8 +348,8 @@ </taglist> <p>See the <seealso marker="config_file_chapter#require_config_data">Config files</seealso> - chapter and the <c><seealso marker="ct#require-1"> - ct:require/1/2</seealso></c> function in the + chapter and the <seealso marker="ct#require-1"><c> + ct:require/1/2</c></seealso> function in the <seealso marker="ct">ct</seealso> reference manual for more information about <c>require</c>.</p> @@ -826,14 +826,16 @@ Common Test to create one dedicated private directory per test case and execution instead. This is accomplished by means of the flag/option: <c>create_priv_dir</c> (to be used with the - <c>ct_run</c> program, the <c><seealso marker="ct#run_test-1">ct:run_test/1</seealso></c> function, or + <c>ct_run</c> program, the <seealso marker="ct#run_test-1"><c>ct:run_test/1</c></seealso> function, or as test specification term). There are three possible values for this option: + </p> <list> <item><c>auto_per_run</c></item> <item><c>auto_per_tc</c></item> <item><c>manual_per_tc</c></item> </list> + <p> The first value indicates the default priv_dir behaviour, i.e. one private directory created per test run. The two latter values tell Common Test to generate a unique test directory name @@ -842,7 +844,7 @@ become very inefficient for test runs with many test cases and/or repetitions. Therefore, in case the manual version is instead used, the test case must tell Common Test to create priv_dir when it needs it. - It does this by calling the function <c><seealso marker="ct#make_priv_dir-0">ct:make_priv_dir/0</seealso></c>. + It does this by calling the function <seealso marker="ct#make_priv_dir-0"><c>ct:make_priv_dir/0</c></seealso>. </p> <note><p>You should not depend on current working directory for @@ -890,7 +892,7 @@ <p>It is also possible to dynamically set/reset a timetrap during the excution of a test case, or configuration function. This is done by calling - <c><seealso marker="ct#timetrap-1">ct:timetrap/1</seealso></c>. This function cancels the current timetrap + <seealso marker="ct#timetrap-1"><c>ct:timetrap/1</c></seealso>. This function cancels the current timetrap and starts a new one (that stays active until timeout, or end of the current function).</p> @@ -903,12 +905,12 @@ <p>If a test case needs to suspend itself for a time that also gets multipled by <c>multiply_timetraps</c> (and possibly also scaled up if - <c>scale_timetraps</c> is enabled), the function <c><seealso marker="ct#sleep-1">ct:sleep/1</seealso></c> + <c>scale_timetraps</c> is enabled), the function <seealso marker="ct#sleep-1"><c>ct:sleep/1</c></seealso> may be used (instead of e.g. <c>timer:sleep/1</c>).</p> <p>A function (<c>fun/0</c> or <c>MFA</c>) may be specified as timetrap value in the suite-, group- and test case info function, as - well as argument to the <c><seealso marker="ct#timetrap-1">ct:timetrap/1</seealso></c> function. Examples:</p> + well as argument to the <seealso marker="ct#timetrap-1"><c>ct:timetrap/1</c></seealso> function. Examples:</p> <p><c>{timetrap,{my_test_utils,timetrap,[?MODULE,system_start]}}</c></p> <p><c>ct:timetrap(fun() -> my_timetrap(TestCaseName, Config) end)</c></p> diff --git a/lib/common_test/include/ct.hrl b/lib/common_test/include/ct.hrl index bde2709ad1..44cc33f01e 100644 --- a/lib/common_test/include/ct.hrl +++ b/lib/common_test/include/ct.hrl @@ -32,3 +32,7 @@ -define(STD_VERBOSITY, 50 ). -define(HI_VERBOSITY, 75 ). -define(MAX_VERBOSITY, 100). + +%% name of process executing the CT Hook init and terminate function +-define(CT_HOOK_INIT_PROCESS, ct_util_server). +-define(CT_HOOK_TERMINATE_PROCESS, ct_util_server). diff --git a/lib/common_test/src/ct_hooks.erl b/lib/common_test/src/ct_hooks.erl index 3d87a82e24..e845e9e908 100644 --- a/lib/common_test/src/ct_hooks.erl +++ b/lib/common_test/src/ct_hooks.erl @@ -50,9 +50,8 @@ -spec init(State :: term()) -> ok | {fail, Reason :: term()}. init(Opts) -> - call(get_new_hooks(Opts, undefined) ++ get_builtin_hooks(Opts), + call(get_builtin_hooks(Opts) ++ get_new_hooks(Opts, undefined), ok, init, []). - %% @doc Called after all suites are done. -spec terminate(Hooks :: term()) -> @@ -276,8 +275,10 @@ get_new_hooks(Config, Fun) -> end, get_new_hooks(Config)). get_new_hooks(Config) when is_list(Config) -> - lists:flatmap(fun({?config_name, HookConfigs}) -> + lists:flatmap(fun({?config_name, HookConfigs}) when is_list(HookConfigs) -> HookConfigs; + ({?config_name, HookConfig}) when is_atom(HookConfig) -> + [HookConfig]; (_) -> [] end, Config); diff --git a/lib/common_test/src/ct_logs.erl b/lib/common_test/src/ct_logs.erl index bd37b690b6..1a6e4d31a8 100644 --- a/lib/common_test/src/ct_logs.erl +++ b/lib/common_test/src/ct_logs.erl @@ -61,6 +61,7 @@ -define(index_name, "index.html"). -define(totals_name, "totals.info"). -define(log_cache_name, "ct_log_cache"). +-define(misc_io_log, "misc_io.log.html"). -define(table_color1,"#ADD8E6"). -define(table_color2,"#E4F0FE"). @@ -523,7 +524,7 @@ int_footer() -> div_header(Class) -> div_header(Class,"User"). div_header(Class,Printer) -> - "<div class=\"" ++ atom_to_list(Class) ++ "\"><b>*** " ++ Printer ++ + "\n<div class=\"" ++ atom_to_list(Class) ++ "\"><b>*** " ++ Printer ++ " " ++ log_timestamp(now()) ++ " ***</b>". div_footer() -> "</div>". @@ -617,6 +618,34 @@ logger(Parent, Mode, Verbosity) -> end end end, + + test_server_io:start_link(), + MiscIoName = filename:join(Dir, ?misc_io_log), + {ok,MiscIoFd} = file:open(MiscIoName, + [write,{encoding,utf8}]), + test_server_io:set_fd(unexpected_io, MiscIoFd), + + {MiscIoHeader,MiscIoFooter} = + case get_ts_html_wrapper("Pre/post-test I/O log", Dir, false, + Dir, undefined, utf8) of + {basic_html,UH,UF} -> + {UH,UF}; + {xhtml,UH,UF} -> + {UH,UF} + end, + io:put_chars(MiscIoFd, + [MiscIoHeader, + "<a name=\"pretest\"></a>\n", + xhtml("<br>\n<h2>Pre-test Log</h2>", + "<br />\n<h3>PRE-TEST LOG</h3>"), + "\n<pre>\n"]), + MiscIoDivider = + "\n<a name=\"posttest\"></a>\n"++ + xhtml("</pre>\n<br><h2>Post-test Log</h2>\n<pre>\n", + "</pre>\n<br />\n<h3>POST-TEST LOG</h3>\n<pre>\n"), + ct_util:set_testdata_async({misc_io_log,{filename:absname(MiscIoName), + MiscIoDivider,MiscIoFooter}}), + ct_event:notify(#event{name=start_logging,node=node(), data=AbsDir}), make_all_runs_index(start), @@ -627,7 +656,7 @@ logger(Parent, Mode, Verbosity) -> end, file:set_cwd(Dir), make_last_run_index(Time), - CtLogFd = open_ctlog(), + CtLogFd = open_ctlog(?misc_io_log), io:format(CtLogFd,int_header()++int_footer(), [log_timestamp(now()),"Common Test Logger started"]), Parent ! {started,self(),{Time,filename:absname("")}}, @@ -922,7 +951,7 @@ set_evmgr_gl(GL) -> EvMgrPid -> group_leader(GL,EvMgrPid) end. -open_ctlog() -> +open_ctlog(MiscIoName) -> {ok,Fd} = file:open(?ct_log_name,[write,{encoding,utf8}]), io:format(Fd, header("Common Test Framework Log", {[],[1,2],[]}), []), case file:consult(ct_run:variables_file_name("../")) of @@ -937,10 +966,21 @@ open_ctlog() -> "No configuration found for test!!\n", [Variables,Reason]) end, + io:format(Fd, + xhtml("<br><br><h2>Pre/post-test I/O Log</h2>\n", + "<br /><br />\n<h4>PRE/POST TEST I/O LOG</h4>\n"), []), + io:format(Fd, + "\n<ul>\n" + "<li><a href=\"~ts#pretest\">" + "View I/O logged before the test run</a></li>\n" + "<li><a href=\"~ts#posttest\">" + "View I/O logged after the test run</a></li>\n</ul>\n", + [MiscIoName,MiscIoName]), + print_style(Fd,undefined), io:format(Fd, - xhtml("<br><br><h2>Progress Log</h2>\n<pre>\n", - "<br /><br /><h4>PROGRESS LOG</h4>\n<pre>\n"), []), + xhtml("<br><h2>Progress Log</h2>\n<pre>\n", + "<br />\n<h4>PROGRESS LOG</h4>\n<pre>\n"), []), Fd. print_style(Fd,undefined) -> @@ -2856,6 +2896,9 @@ make_relative1(DirTs, CwdTs) -> %%% @doc %%% get_ts_html_wrapper(TestName, PrintLabel, Cwd, TableCols, Encoding) -> + get_ts_html_wrapper(TestName, undefined, PrintLabel, Cwd, TableCols, Encoding). + +get_ts_html_wrapper(TestName, Logdir, PrintLabel, Cwd, TableCols, Encoding) -> TestName1 = if is_list(TestName) -> lists:flatten(TestName); true -> @@ -2876,7 +2919,12 @@ get_ts_html_wrapper(TestName, PrintLabel, Cwd, TableCols, Encoding) -> end end, CTPath = code:lib_dir(common_test), - {ok,CtLogdir} = get_log_dir(true), + + {ok,CtLogdir} = + if Logdir == undefined -> get_log_dir(true); + true -> {ok,Logdir} + end, + AllRuns = make_relative(filename:join(filename:dirname(CtLogdir), ?all_runs_name), Cwd), TestIndex = make_relative(filename:join(filename:dirname(CtLogdir), @@ -3074,16 +3122,8 @@ unexpected_io(Pid,ct_internal,_Importance,List,State) -> IoFun = create_io_fun(Pid,State), io:format(State#logger_state.ct_log_fd, "~ts", [lists:foldl(IoFun, [], List)]); -unexpected_io(Pid,Category,Importance,List,State) -> +unexpected_io(Pid,_Category,_Importance,List,State) -> IoFun = create_io_fun(Pid,State), Data = io_lib:format("~ts", [lists:foldl(IoFun, [], List)]), - %% if unexpected io comes in during startup or shutdown, test_server - %% might not be running - if so (noproc exit), simply print to - %% stdout instead (will result in double printouts when pal is used) - try test_server_io:print_unexpected(Data) of - _ -> - ok - catch - _:{noproc,_} -> tc_print(Category,Importance,Data,[]); - _:Reason -> exit(Reason) - end. + test_server_io:print_unexpected(Data), + ok. diff --git a/lib/common_test/src/ct_run.erl b/lib/common_test/src/ct_run.erl index 266ca73417..7c797be03e 100644 --- a/lib/common_test/src/ct_run.erl +++ b/lib/common_test/src/ct_run.erl @@ -1883,7 +1883,7 @@ verify_suites(TestSuites) -> atom_to_list( Suite)), io:format(user, - "Suite ~w not found" + "Suite ~w not found " "in directory ~ts~n", [Suite,TestDir]), {Found,[{DS,[Name]}|NotFound]} diff --git a/lib/common_test/src/ct_util.erl b/lib/common_test/src/ct_util.erl index abda87c2cd..bcc4caa62e 100644 --- a/lib/common_test/src/ct_util.erl +++ b/lib/common_test/src/ct_util.erl @@ -187,6 +187,7 @@ do_start(Parent, Mode, LogDir, Verbosity) -> false -> ok end, + {StartTime,TestLogDir} = ct_logs:init(Mode, Verbosity), ct_event:notify(#event{name=test_start, @@ -198,12 +199,26 @@ do_start(Parent, Mode, LogDir, Verbosity) -> ok -> Parent ! {self(),started}; {fail,CTHReason} -> - ct_logs:tc_print('Suite Callback',CTHReason,[]), + ErrorInfo = if is_atom(CTHReason) -> + io_lib:format("{~p,~p}", + [CTHReason, + erlang:get_stacktrace()]); + true -> + CTHReason + end, + ct_logs:tc_print('Suite Callback',ErrorInfo,[]), self() ! {{stop,{self(),{user_error,CTHReason}}}, {Parent,make_ref()}} catch _:CTHReason -> - ct_logs:tc_print('Suite Callback',CTHReason,[]), + ErrorInfo = if is_atom(CTHReason) -> + io_lib:format("{~p,~p}", + [CTHReason, + erlang:get_stacktrace()]); + true -> + CTHReason + end, + ct_logs:tc_print('Suite Callback',ErrorInfo,[]), self() ! {{stop,{self(),{user_error,CTHReason}}}, {Parent,make_ref()}} end, @@ -392,19 +407,38 @@ loop(Mode,TestData,StartDir) -> return(From,StartDir), loop(From,TestData,StartDir); {{stop,Info},From} -> + test_server_io:reset_state(), + {MiscIoName,MiscIoDivider,MiscIoFooter} = + proplists:get_value(misc_io_log,TestData), + {ok,MiscIoFd} = file:open(MiscIoName, + [append,{encoding,utf8}]), + io:put_chars(MiscIoFd, MiscIoDivider), + test_server_io:set_fd(unexpected_io, MiscIoFd), + Time = calendar:local_time(), ct_event:sync_notify(#event{name=test_done, node=node(), data=Time}), - Callbacks = ets:lookup_element(?suite_table, - ct_hooks, - #suite_data.value), + Callbacks = + try ets:lookup_element(?suite_table, + ct_hooks, + #suite_data.value) of + CTHMods -> CTHMods + catch + %% this is because ct_util failed in init + error:badarg -> [] + end, ct_hooks:terminate(Callbacks), close_connections(ets:tab2list(?conn_table)), ets:delete(?conn_table), ets:delete(?board_table), ets:delete(?suite_table), ets:delete(?verbosity_table), + + io:put_chars(MiscIoFd, "\n</pre>\n"++MiscIoFooter), + test_server_io:stop([unexpected_io]), + test_server_io:finish(), + ct_logs:close(Info, StartDir), ct_event:stop(), ct_config:stop(), @@ -679,8 +713,14 @@ reset_silent_connections() -> %%% @see ct stop(Info) -> case whereis(ct_util_server) of - undefined -> ok; - _ -> call({stop,Info}) + undefined -> + ok; + CtUtilPid -> + Ref = monitor(process, CtUtilPid), + call({stop,Info}), + receive + {'DOWN',Ref,_,_,_} -> ok + end end. %%%----------------------------------------------------------------- diff --git a/lib/common_test/src/cth_log_redirect.erl b/lib/common_test/src/cth_log_redirect.erl index 958b7a94c7..f5e769e1ba 100644 --- a/lib/common_test/src/cth_log_redirect.erl +++ b/lib/common_test/src/cth_log_redirect.erl @@ -25,16 +25,31 @@ %% CTH Callbacks --export([id/1, init/2, post_init_per_group/4, pre_end_per_group/3, - post_end_per_testcase/4]). +-export([id/1, init/2, + pre_init_per_suite/3, pre_end_per_suite/3, post_end_per_suite/4, + pre_init_per_group/3, post_init_per_group/4, + pre_end_per_group/3, post_end_per_group/4, + pre_init_per_testcase/3, post_end_per_testcase/4]). %% Event handler Callbacks -export([init/1, handle_event/2, handle_call/2, handle_info/2, - terminate/1]). + terminate/2, code_change/3]). + +%% Other +-export([handle_remote_events/1]). -include("ct.hrl"). +-behaviour(gen_event). + +-record(eh_state, {log_func, + curr_suite, + curr_group, + curr_func, + parallel_tcs = false, + handle_remote_events = false}). + id(_Opts) -> ?MODULE. @@ -42,36 +57,62 @@ init(?MODULE, _Opts) -> error_logger:add_report_handler(?MODULE), tc_log_async. +pre_init_per_suite(Suite, Config, State) -> + set_curr_func({Suite,init_per_suite}, Config), + {Config, State}. + +pre_end_per_suite(Suite, Config, State) -> + set_curr_func({Suite,end_per_suite}, Config), + {Config, State}. + +post_end_per_suite(_Suite, Config, Return, State) -> + set_curr_func(undefined, Config), + {Return, State}. + +pre_init_per_group(Group, Config, State) -> + set_curr_func({group,Group,init_per_group}, Config), + {Config, State}. + post_init_per_group(Group, Config, Result, tc_log_async) -> case lists:member(parallel,proplists:get_value( tc_group_properties,Config,[])) of true -> - {Result, {set_log_func(ct_log),Group}}; + {Result, {set_log_func(tc_log),Group}}; false -> {Result, tc_log_async} end; post_init_per_group(_Group, _Config, Result, State) -> {Result, State}. +pre_init_per_testcase(TC, Config, State) -> + set_curr_func(TC, Config), + {Config, State}. + post_end_per_testcase(_TC, _Config, Result, State) -> %% Make sure that the event queue is flushed %% before ending this test case. gen_event:call(error_logger, ?MODULE, flush, 300000), {Result, State}. -pre_end_per_group(Group, Config, {ct_log, Group}) -> +pre_end_per_group(Group, Config, {tc_log, Group}) -> + set_curr_func({group,Group,end_per_group}, Config), {Config, set_log_func(tc_log_async)}; -pre_end_per_group(_Group, Config, State) -> +pre_end_per_group(Group, Config, State) -> + set_curr_func({group,Group,end_per_group}, Config), {Config, State}. +post_end_per_group(_Group, Config, Return, State) -> + set_curr_func({group,undefined}, Config), + {Return, State}. %% Copied and modified from sasl_report_tty_h.erl init(_Type) -> - {ok, tc_log_async}. + {ok, #eh_state{log_func = tc_log_async}}. -handle_event({_Type, GL, _Msg}, State) when node(GL) /= node() -> +handle_event({_Type,GL,_Msg}, #eh_state{handle_remote_events = false} = State) + when node(GL) /= node() -> {ok, State}; -handle_event(Event, LogFunc) -> +handle_event(Event, #eh_state{log_func = LogFunc} = State) -> case lists:keyfind(sasl, 1, application:which_applications()) of false -> sasl_not_started; @@ -80,7 +121,8 @@ handle_event(Event, LogFunc) -> SReport = sasl_report:format_report(group_leader(), ErrLogType, tag_event(Event)), if is_list(SReport) -> - ct_logs:LogFunc(sasl, ?STD_IMPORTANCE, "System", SReport, []); + SaslHeader = format_header(State), + ct_logs:LogFunc(sasl, ?STD_IMPORTANCE, SaslHeader, SReport, []); true -> %% Report is an atom if no logging is to be done ignore end @@ -88,27 +130,114 @@ handle_event(Event, LogFunc) -> EReport = error_logger_tty_h:write_event( tag_event(Event),io_lib), if is_list(EReport) -> - ct_logs:LogFunc(error_logger, ?STD_IMPORTANCE, "System", EReport, []); + ErrHeader = format_header(State), + ct_logs:LogFunc(error_logger, ?STD_IMPORTANCE, ErrHeader, EReport, []); true -> %% Report is an atom if no logging is to be done ignore end, - {ok, LogFunc}. - + {ok, State}. + +handle_info({'EXIT',User,killed}, State) -> + case whereis(user) of + %% init:stop/1/2 has been called, let's finish! + undefined -> + remove_handler; + User -> + remove_handler; + _ -> + {ok,State} + end; -handle_info(_,State) -> {ok, State}. +handle_info(_, State) -> + {ok,State}. handle_call(flush,State) -> {ok, ok, State}; -handle_call({set_logfunc,NewLogFunc},_) -> - {ok, NewLogFunc, NewLogFunc}; -handle_call(_Query, _State) -> {error, bad_query}. -terminate(_State) -> +handle_call({set_curr_func,{group,Group,Conf},Config}, State) -> + Parallel = case proplists:get_value(tc_group_properties, Config) of + undefined -> false; + Props -> lists:member(parallel, Props) + end, + {ok, ok, State#eh_state{curr_group = Group, + curr_func = Conf, + parallel_tcs = Parallel}}; +handle_call({set_curr_func,{group,undefined},_Config}, State) -> + {ok, ok, State#eh_state{curr_group = undefined, + curr_func = undefined, + parallel_tcs = false}}; +handle_call({set_curr_func,{Suite,Conf},_Config}, State) -> + {ok, ok, State#eh_state{curr_suite = Suite, + curr_func = Conf, + parallel_tcs = false}}; +handle_call({set_curr_func,undefined,_Config}, State) -> + {ok, ok, State#eh_state{curr_suite = undefined, + curr_func = undefined, + parallel_tcs = false}}; +handle_call({set_curr_func,TC,_Config}, State) -> + {ok, ok, State#eh_state{curr_func = TC}}; + +handle_call({set_logfunc,NewLogFunc}, State) -> + {ok, NewLogFunc, State#eh_state{log_func = NewLogFunc}}; + +handle_call({handle_remote_events,Bool}, State) -> + {ok, ok, State#eh_state{handle_remote_events = Bool}}; + +handle_call(_Query, _State) -> + {error, bad_query}. + +terminate(_Arg, _State) -> error_logger:delete_report_handler(?MODULE), []. tag_event(Event) -> {calendar:local_time(), Event}. +set_curr_func(CurrFunc, Config) -> + gen_event:call(error_logger, ?MODULE, {set_curr_func, CurrFunc, Config}). + set_log_func(Func) -> gen_event:call(error_logger, ?MODULE, {set_logfunc, Func}). + +handle_remote_events(Bool) -> + gen_event:call(error_logger, ?MODULE, {handle_remote_events, Bool}). + +%%%----------------------------------------------------------------- + +format_header(#eh_state{curr_suite = undefined, + curr_group = undefined, + curr_func = undefined}) -> + io_lib:format("System report", []); + +format_header(#eh_state{curr_suite = Suite, + curr_group = undefined, + curr_func = undefined}) -> + io_lib:format("System report during ~w", [Suite]); + +format_header(#eh_state{curr_suite = Suite, + curr_group = undefined, + curr_func = TcOrConf}) -> + io_lib:format("System report during ~w:~w/1", + [Suite,TcOrConf]); + +format_header(#eh_state{curr_suite = Suite, + curr_group = Group, + curr_func = Conf}) when Conf == init_per_group; + Conf == end_per_group -> + io_lib:format("System report during ~w:~w/2 for ~w", + [Suite,Conf,Group]); + +format_header(#eh_state{curr_suite = Suite, + curr_group = Group, + parallel_tcs = true}) -> + io_lib:format("System report during ~w in ~w", + [Group,Suite]); + +format_header(#eh_state{curr_suite = Suite, + curr_group = Group, + curr_func = TC}) -> + io_lib:format("System report during ~w:~w/1 in ~w", + [Suite,TC,Group]). + +code_change(_OldVsn, State, _Extra) -> + {ok, State}. diff --git a/lib/common_test/test/Makefile b/lib/common_test/test/Makefile index 9d2edcd653..085f19d023 100644 --- a/lib/common_test/test/Makefile +++ b/lib/common_test/test/Makefile @@ -51,6 +51,7 @@ MODULES= \ ct_master_SUITE \ ct_misc_1_SUITE \ ct_hooks_SUITE \ + ct_pre_post_test_io_SUITE \ ct_netconfc_SUITE \ ct_basic_html_SUITE \ ct_auto_compile_SUITE \ diff --git a/lib/common_test/test/ct_gen_conn_SUITE_data/proto.erl b/lib/common_test/test/ct_gen_conn_SUITE_data/proto.erl index 8fcd35e0a4..1d08ce167b 100644 --- a/lib/common_test/test/ct_gen_conn_SUITE_data/proto.erl +++ b/lib/common_test/test/ct_gen_conn_SUITE_data/proto.erl @@ -1,10 +1,21 @@ -%%% @author Peter Andersson <[email protected]> -%%% @copyright (C) 2013, Peter Andersson -%%% @doc -%%% -%%% @end -%%% Created : 24 May 2013 by Peter Andersson <[email protected]> - +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2012. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% -module(proto). -compile(export_all). diff --git a/lib/common_test/test/ct_hooks_SUITE.erl b/lib/common_test/test/ct_hooks_SUITE.erl index 796a0832d7..596bfe3ff0 100644 --- a/lib/common_test/test/ct_hooks_SUITE.erl +++ b/lib/common_test/test/ct_hooks_SUITE.erl @@ -84,7 +84,7 @@ all(suite) -> skip_post_suite_cth, recover_post_suite_cth, update_config_cth, state_update_cth, options_cth, same_id_cth, fail_n_skip_with_minimal_cth, prio_cth, no_config, - data_dir + data_dir, cth_log ] ). @@ -222,7 +222,32 @@ data_dir(Config) when is_list(Config) -> do_test(data_dir, "ct_data_dir_SUITE.erl", [verify_data_dir_cth],Config). - +cth_log(Config) when is_list(Config) -> + %% test that cth_log_redirect writes properly to + %% unexpected I/O log + StartOpts = do_test(cth_log, "cth_log_SUITE.erl", [], Config), + Logdir = proplists:get_value(logdir, StartOpts), + UnexpIoLogs = + filelib:wildcard( + filename:join(Logdir, + "ct_run*/cth.tests*/run*/unexpected_io.log.html")), + lists:foreach( + fun(UnexpIoLog) -> + {ok,Bin} = file:read_file(UnexpIoLog), + Ts = string:tokens(binary_to_list(Bin),[$\n]), + Matches = lists:foldl(fun([$=,$E,$R,$R,$O,$R|_], N) -> + N+1; + ([$L,$o,$g,$g,$e,$r|_], N) -> + N+1; + (_, N) -> N + end, 0, Ts), + ct:pal("~p matches in ~tp", [Matches,UnexpIoLog]), + if Matches > 10 -> ok; + true -> exit({no_unexpected_io_found,UnexpIoLog}) + end + end, UnexpIoLogs), + ok. + %%%----------------------------------------------------------------- %%% HELP FUNCTIONS @@ -251,7 +276,8 @@ do_test(Tag, SuiteWildCard, CTHs, Config, Res, EC) -> Opts), TestEvents = events_to_check(Tag, EC), - ok = ct_test_support:verify_events(TestEvents, Events, Config). + ok = ct_test_support:verify_events(TestEvents, Events, Config), + Opts. setup(Test, Config) -> Opts0 = ct_test_support:get_opts(Config), @@ -1187,6 +1213,23 @@ test_events(data_dir) -> {?eh,stop_logging,[]} ]; +test_events(cth_log) -> + [{?eh,start_logging,{'DEF','RUNDIR'}}, + {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}}, + {?eh,tc_start,{cth_log_SUITE,init_per_suite}}, + + {parallel, + [{?eh,tc_start,{ct_framework,{init_per_group,g1,[parallel]}}}, + {?eh,tc_done,{ct_framework,{init_per_group,g1,[parallel]},ok}}, + {?eh,test_stats,{30,0,{0,0}}}, + {?eh,tc_start,{ct_framework,{end_per_group,g1,[parallel]}}}, + {?eh,tc_done,{ct_framework,{end_per_group,g1,[parallel]},ok}}]}, + + {?eh,tc_done,{cth_log_SUITE,end_per_suite,ok}}, + {?eh,test_done,{'DEF','STOP_TIME'}}, + {?eh,stop_logging,[]} + ]; + test_events(ok) -> ok. diff --git a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/cth_log_SUITE.erl b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/cth_log_SUITE.erl new file mode 100644 index 0000000000..18dd07e87e --- /dev/null +++ b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/cth_log_SUITE.erl @@ -0,0 +1,124 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2010-2011. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% + +-module(cth_log_SUITE). + +-compile(export_all). + +-include_lib("common_test/include/ct.hrl"). + +%%-------------------------------------------------------------------- +%% @spec suite() -> Info +%% Info = [tuple()] +%% @end +%%-------------------------------------------------------------------- +suite() -> + [{timetrap,{seconds,30}}]. + +%%-------------------------------------------------------------------- +%% @spec init_per_suite(Config0) -> +%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1} +%% Config0 = Config1 = [tuple()] +%% Reason = term() +%% @end +%%-------------------------------------------------------------------- +init_per_suite(Config) -> + Gen = spawn(fun() -> gen() end), + [{gen,Gen}|Config]. + +%%-------------------------------------------------------------------- +%% @spec end_per_suite(Config0) -> void() | {save_config,Config1} +%% Config0 = Config1 = [tuple()] +%% @end +%%-------------------------------------------------------------------- +end_per_suite(Config) -> + Gen = proplists:get_value(gen, Config), + exit(Gen, kill), + timer:sleep(100), + ok. + +%%-------------------------------------------------------------------- +%% @spec init_per_testcase(TestCase, Config0) -> +%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1} +%% TestCase = atom() +%% Config0 = Config1 = [tuple()] +%% Reason = term() +%% @end +%%-------------------------------------------------------------------- +init_per_testcase(_TestCase, Config) -> + Config. + +%%-------------------------------------------------------------------- +%% @spec end_per_testcase(TestCase, Config0) -> +%% void() | {save_config,Config1} | {fail,Reason} +%% TestCase = atom() +%% Config0 = Config1 = [tuple()] +%% Reason = term() +%% @end +%%-------------------------------------------------------------------- +end_per_testcase(_TestCase, _Config) -> + ok. + +%%-------------------------------------------------------------------- +%% @spec groups() -> [Group] +%% Group = {GroupName,Properties,GroupsAndTestCases} +%% GroupName = atom() +%% Properties = [parallel | sequence | Shuffle | {RepeatType,N}] +%% GroupsAndTestCases = [Group | {group,GroupName} | TestCase] +%% TestCase = atom() +%% Shuffle = shuffle | {shuffle,{integer(),integer(),integer()}} +%% RepeatType = repeat | repeat_until_all_ok | repeat_until_all_fail | +%% repeat_until_any_ok | repeat_until_any_fail +%% N = integer() | forever +%% @end +%%-------------------------------------------------------------------- +groups() -> + [{g1,[parallel,{repeat,10}],[tc1,tc2,tc3]}]. + +%%-------------------------------------------------------------------- +%% @spec all() -> GroupsAndTestCases | {skip,Reason} +%% GroupsAndTestCases = [{group,GroupName} | TestCase] +%% GroupName = atom() +%% TestCase = atom() +%% Reason = term() +%% @end +%%-------------------------------------------------------------------- +all() -> + [{group,g1}]. + +tc1(_) -> + ct:sleep(100), + ok. +tc2(_) -> + ct:sleep(100), + ok. +tc3(_) -> + ct:sleep(100), + ok. + +%%%----------------------------------------------------------------- + +gen() -> + gen_loop(1). + +gen_loop(N) -> + ct:log("Logger iteration: ~p", [N]), + error_logger:error_report(N), + ct:sleep(200), + gen_loop(N+1). diff --git a/lib/common_test/test/ct_pre_post_test_io_SUITE.erl b/lib/common_test/test/ct_pre_post_test_io_SUITE.erl new file mode 100644 index 0000000000..5de1ecc2bd --- /dev/null +++ b/lib/common_test/test/ct_pre_post_test_io_SUITE.erl @@ -0,0 +1,255 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2012. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% + +%%%------------------------------------------------------------------- +%%% File: ct_pre_post_test_io_SUITE +%%% +%%% Description: +%%% +%%% Test that ct:log/2 printouts and error/progress reports that happen +%%% before or after the test run are saved in the pre/post test IO log. +%%%------------------------------------------------------------------- +-module(ct_pre_post_test_io_SUITE). + +-compile(export_all). + +-include_lib("common_test/include/ct.hrl"). +-include_lib("common_test/include/ct_event.hrl"). + +-define(eh, ct_test_support_eh). + +%%-------------------------------------------------------------------- +%% TEST SERVER CALLBACK FUNCTIONS +%%-------------------------------------------------------------------- + +%%-------------------------------------------------------------------- +%% Description: Since Common Test starts another Test Server +%% instance, the tests need to be performed on a separate node (or +%% there will be clashes with logging processes etc). +%%-------------------------------------------------------------------- +init_per_suite(Config) -> + DataDir = ?config(data_dir, Config), + CTH = filename:join(DataDir, "cth_ctrl.erl"), + ct:pal("Compiling ~p: ~p", + [CTH,compile:file(CTH,[{outdir,DataDir},debug_info])]), + ct_test_support:init_per_suite([{path_dirs,[DataDir]}, + {start_sasl,true} | Config]). + +end_per_suite(Config) -> + ct_test_support:end_per_suite(Config). + +init_per_testcase(TestCase, Config) -> + ct_test_support:init_per_testcase(TestCase, Config). + +end_per_testcase(TestCase, Config) -> + ct_test_support:end_per_testcase(TestCase, Config). + +suite() -> [{ct_hooks,[ts_install_cth]}]. + +all() -> + [ + pre_post_io + ]. + +%%-------------------------------------------------------------------- +%% TEST CASES +%%-------------------------------------------------------------------- + +%%%----------------------------------------------------------------- +%%% +pre_post_io(Config) -> + TC = pre_post_io, + DataDir = ?config(data_dir, Config), + Suite = filename:join(DataDir, "dummy_SUITE"), + {Opts,ERPid} = setup([{suite,Suite},{label,TC},{ct_hooks,[cth_ctrl]}], + Config), + + %%!-------------------------------------------------------------------- + %%! Note that error reports will not start showing up in the pre-test + %%! io log until handle_remote_events has been set to true (see below). + %%! The reason is that the error logger has its group leader on the + %%! test_server node (not the ct node) and cth_log_redirect ignores + %%! events with remote destination until told otherwise. + %%!-------------------------------------------------------------------- + + spawn(fun() -> + ct:pal("CONTROLLER: Started!", []), + %% --- test run 1 --- + timer:sleep(3000), + ct:pal("CONTROLLER: Handle remote events = true", []), + ok = ct_test_support:ct_rpc({cth_log_redirect, + handle_remote_events, + [true]}, Config), + timer:sleep(2000), + ct:pal("CONTROLLER: Proceeding with test run #1!", []), + ok = ct_test_support:ct_rpc({cth_ctrl,proceed,[]}, Config), + timer:sleep(6000), + ct:pal("CONTROLLER: Proceeding with shutdown #1!", []), + ok = ct_test_support:ct_rpc({cth_ctrl,proceed,[]}, Config), + %% --- test run 2 --- + timer:sleep(3000), + ct:pal("CONTROLLER: Handle remote events = true", []), + ok = ct_test_support:ct_rpc({cth_log_redirect, + handle_remote_events, + [true]}, Config), + timer:sleep(2000), + ct:pal("CONTROLLER: Proceeding with test run #2!", []), + ok = ct_test_support:ct_rpc({cth_ctrl,proceed,[]}, Config), + timer:sleep(6000), + ct:pal("CONTROLLER: Proceeding with shutdown #2!", []), + ok = ct_test_support:ct_rpc({cth_ctrl,proceed,[]}, Config) + end), + ct_test_support:run(Opts, Config), + Events = ct_test_support:get_events(ERPid, Config), + ct_test_support:log_events(TC, + reformat(Events, ?eh), + ?config(priv_dir, Config), + Opts), + TestEvents = events_to_check(TC), + ok = ct_test_support:verify_events(TestEvents, Events, Config), + + LogDirs = lists:flatmap(fun({_EH,#event{name=start_logging,data=Dir}}) -> + [Dir]; + (_) -> + [] + end, Events), + PrePostIoFiles = + [filename:join(LogDir, "misc_io.log.html") || LogDir <- LogDirs], + lists:foreach( + fun(PrePostIoFile) -> + ct:log("Reading Pre/Post Test IO Log file: ~ts", [PrePostIoFile]), + {ok,Bin} = file:read_file(PrePostIoFile), + Ts = string:tokens(binary_to_list(Bin),[$\n]), + PrePostIOEntries = + lists:foldl(fun([$L,$o,$g,$g,$e,$r|_], + {pre,PreLogN,PreErrN,0,0}) -> + {pre,PreLogN+1,PreErrN,0,0}; + ([$=,$E,$R,$R,$O,$R|_], + {pre,PreLogN,PreErrN,0,0}) -> + {pre,PreLogN,PreErrN+1,0,0}; + ([_,_,_,_,$P,$O,$S,$T,$-,$T,$E,$S,$T|_], + {pre,PreLogN,PreErrN,0,0}) -> + {post,PreLogN,PreErrN,0,0}; + ([$L,$o,$g,$g,$e,$r|_], + {post,PreLogN,PreErrN,PostLogN,PostErrN}) -> + {post,PreLogN,PreErrN,PostLogN+1,PostErrN}; + ([$=,$E,$R,$R,$O,$R|_], + {post,PreLogN,PreErrN,PostLogN,PostErrN}) -> + {post,PreLogN,PreErrN,PostLogN,PostErrN+1}; + (_, Counters) -> + Counters + end, {pre,0,0,0,0}, Ts), + [_|Counters] = tuple_to_list(PrePostIOEntries), + ct:log("Entries in the Pre/Post Test IO Log: ~p", [Counters]), + case [C || C <- Counters, C < 2] of + [] -> + ok; + _ -> + exit("Not enough entries in the Pre/Post Test IO Log!") + end + end, PrePostIoFiles), + + UnexpIoFiles = + [filelib:wildcard( + filename:join(LogDir, + "*dummy_SUITE.logs/run.*/" + "unexpected_io.log.html")) || LogDir <- LogDirs], + lists:foreach( + fun(UnexpIoFile) -> + ct:log("Reading Unexpected IO Log file: ~ts", [UnexpIoFile]), + {ok,Bin} = file:read_file(UnexpIoFile), + Ts = string:tokens(binary_to_list(Bin),[$\n]), + UnexpIOEntries = + lists:foldl(fun([$L,$o,$g,$g,$e,$r|_], [LogN,ErrN]) -> + [LogN+1,ErrN]; + ([$=,$E,$R,$R,$O,$R|_], [LogN,ErrN]) -> + [LogN,ErrN+1]; + (_, Counters) -> Counters + end, [0,0], Ts), + ct:log("Entries in the Unexpected IO Log: ~p", [UnexpIOEntries]), + case [N || N <- UnexpIOEntries, N < 2] of + [] -> + ok; + _ -> + exit("Not enough entries in the Unexpected IO Log!") + end + end, UnexpIoFiles), + ok. + +%%%----------------------------------------------------------------- +%%% HELP FUNCTIONS +%%%----------------------------------------------------------------- + +setup(Test, Config) -> + Opts0 = ct_test_support:get_opts(Config), + Level = ?config(trace_level, Config), + EvHArgs = [{cbm,ct_test_support},{trace_level,Level}], + Opts = Opts0 ++ [{event_handler,{?eh,EvHArgs}}|Test], + ERPid = ct_test_support:start_event_receiver(Config), + {Opts,ERPid}. + +reformat(Events, EH) -> + ct_test_support:reformat(Events, EH). + +%%%----------------------------------------------------------------- +%%% TEST EVENTS +%%%----------------------------------------------------------------- + +events_to_check(pre_post_io) -> + [ + {?eh,start_logging,{'DEF','RUNDIR'}}, + {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}}, + {?eh,start_info,{1,1,7}}, + {?eh,tc_start,{dummy_SUITE,init_per_suite}}, + {?eh,tc_done,{dummy_SUITE,init_per_suite,ok}}, + {parallel, + [{?eh,tc_start,{dummy_SUITE,{init_per_group,g1,[parallel]}}}, + {?eh,tc_done, + {dummy_SUITE,{init_per_group,g1,[parallel]},ok}}, + {?eh,tc_start,{dummy_SUITE,tc1}}, + {?eh,tc_start,{dummy_SUITE,tc2}}, + {?eh,tc_start,{dummy_SUITE,tc3}}, + {?eh,tc_done,{dummy_SUITE,tc2,ok}}, + {?eh,tc_done,{dummy_SUITE,tc1,ok}}, + {?eh,tc_done,{dummy_SUITE,tc3,ok}}, + {?eh,test_stats,{1,0,{0,0}}}, + {?eh,test_stats,{2,0,{0,0}}}, + {?eh,test_stats,{3,0,{0,0}}}, + {?eh,tc_start,{dummy_SUITE,{end_per_group,g1,[parallel]}}}, + {?eh,tc_done,{dummy_SUITE,{end_per_group,g1,[parallel]},ok}}]}, + {?eh,tc_start,{dummy_SUITE,tc1}}, + {?eh,tc_done,{dummy_SUITE,tc1,ok}}, + {?eh,test_stats,{4,0,{0,0}}}, + {?eh,tc_start,{dummy_SUITE,tc2}}, + {?eh,tc_done,{dummy_SUITE,tc2,ok}}, + {?eh,test_stats,{5,0,{0,0}}}, + [{?eh,tc_start,{dummy_SUITE,{init_per_group,g2,[]}}}, + {?eh,tc_done,{dummy_SUITE,{init_per_group,g2,[]},ok}}, + {?eh,tc_start,{dummy_SUITE,tc4}}, + {?eh,tc_done,{dummy_SUITE,tc4,ok}}, + {?eh,test_stats,{6,0,{0,0}}}, + {?eh,tc_start,{dummy_SUITE,tc5}}, + {?eh,tc_done,{dummy_SUITE,tc5,ok}}, + {?eh,test_stats,{7,0,{0,0}}}, + {?eh,tc_start,{dummy_SUITE,{end_per_group,g2,[]}}}, + {?eh,tc_done,{dummy_SUITE,{end_per_group,g2,[]},ok}}], + {?eh,tc_start,{dummy_SUITE,end_per_suite}}, + {?eh,tc_done,{dummy_SUITE,end_per_suite,ok}}, + {?eh,test_done,{'DEF','STOP_TIME'}}, + {?eh,stop_logging,[]}]. diff --git a/lib/common_test/test/ct_pre_post_test_io_SUITE_data/cth_ctrl.erl b/lib/common_test/test/ct_pre_post_test_io_SUITE_data/cth_ctrl.erl new file mode 100644 index 0000000000..2ba991fc61 --- /dev/null +++ b/lib/common_test/test/ct_pre_post_test_io_SUITE_data/cth_ctrl.erl @@ -0,0 +1,108 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2012. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +-module(cth_ctrl). + +-export([proceed/0, + init/2, terminate/1]). + +-include_lib("common_test/include/ct.hrl"). + +%%%=================================================================== +%%% API +%%%=================================================================== + +proceed() -> + ?MODULE ! proceed, + ok. + +%%-------------------------------------------------------------------- +%% Hook functions +%%-------------------------------------------------------------------- +init(_Id, _Opts) -> + case lists:keyfind(sasl, 1, application:which_applications()) of + false -> + exit(sasl_not_started); + _Else -> + ok + end, + WhoAmI = self(), + WhoAmI = whereis(?CT_HOOK_INIT_PROCESS), + DispPid = spawn_link(fun() -> dispatcher(WhoAmI) end), + register(?MODULE, DispPid), + ct:pal("~n~n+++ Startup of ~w on ~p finished, " + "call ~w:proceed() to run tests...~n", + [?MODULE,node(),?MODULE]), + start_external_logger(cth_logger), + receive + {?MODULE,proceed} -> ok + after + 10000 -> + ok + end, + {ok,[],ct_last}. + +terminate(_State) -> + WhoAmI = whereis(?CT_HOOK_TERMINATE_PROCESS), + WhoAmI = self(), + ct:pal("~n~n+++ Tests finished, call ~w:proceed() to shut down...~n", + [?MODULE]), + receive + {?MODULE,proceed} -> ok + after + 10000 -> + ok + end, + stop_external_logger(cth_logger), + stop_dispatcher(), + ok. + +%%%=================================================================== +%%% Internal functions +%%%=================================================================== + +start_external_logger(Name) -> + case whereis(Name) of + undefined -> ok; + Pid -> exit(Pid, kill) + end, + spawn(fun() -> init_logger(Name) end). + +stop_external_logger(Name) -> + catch exit(whereis(Name), kill). + +init_logger(Name) -> + register(Name, self()), + logger_loop(1). + +logger_loop(N) -> + ct:log("Logger iteration: ~p", [N]), + error_logger:error_report(N), + timer:sleep(250), + logger_loop(N+1). + +%%%----------------------------------------------------------------- + +dispatcher(SendTo) -> + receive Msg -> SendTo ! {?MODULE,Msg} end, + dispatcher(SendTo). + +stop_dispatcher() -> + catch exit(whereis(?MODULE), kill). + + diff --git a/lib/common_test/test/ct_pre_post_test_io_SUITE_data/dummy_SUITE.erl b/lib/common_test/test/ct_pre_post_test_io_SUITE_data/dummy_SUITE.erl new file mode 100644 index 0000000000..ac9c4efd31 --- /dev/null +++ b/lib/common_test/test/ct_pre_post_test_io_SUITE_data/dummy_SUITE.erl @@ -0,0 +1,132 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2012. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +-module(dummy_SUITE). + +-compile(export_all). + +-include_lib("common_test/include/ct.hrl"). + +%%-------------------------------------------------------------------- +%% @spec suite() -> Info +%% Info = [tuple()] +%% @end +%%-------------------------------------------------------------------- +suite() -> + [{timetrap,{seconds,30}}]. + +%%-------------------------------------------------------------------- +%% @spec init_per_suite(Config0) -> +%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1} +%% Config0 = Config1 = [tuple()] +%% Reason = term() +%% @end +%%-------------------------------------------------------------------- +init_per_suite(Config) -> + Config. + +%%-------------------------------------------------------------------- +%% @spec end_per_suite(Config0) -> void() | {save_config,Config1} +%% Config0 = Config1 = [tuple()] +%% @end +%%-------------------------------------------------------------------- +end_per_suite(_Config) -> + ok. + +%%-------------------------------------------------------------------- +%% @spec init_per_group(GroupName, Config0) -> +%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1} +%% GroupName = atom() +%% Config0 = Config1 = [tuple()] +%% Reason = term() +%% @end +%%-------------------------------------------------------------------- +init_per_group(_GroupName, Config) -> + Config. + +%%-------------------------------------------------------------------- +%% @spec end_per_group(GroupName, Config0) -> +%% void() | {save_config,Config1} +%% GroupName = atom() +%% Config0 = Config1 = [tuple()] +%% @end +%%-------------------------------------------------------------------- +end_per_group(_GroupName, _Config) -> + ok. + +%%-------------------------------------------------------------------- +%% @spec init_per_testcase(TestCase, Config0) -> +%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1} +%% TestCase = atom() +%% Config0 = Config1 = [tuple()] +%% Reason = term() +%% @end +%%-------------------------------------------------------------------- +init_per_testcase(_TestCase, Config) -> + ct:sleep(500), + Config. + +%%-------------------------------------------------------------------- +%% @spec end_per_testcase(TestCase, Config0) -> +%% void() | {save_config,Config1} | {fail,Reason} +%% TestCase = atom() +%% Config0 = Config1 = [tuple()] +%% Reason = term() +%% @end +%%-------------------------------------------------------------------- +end_per_testcase(_TestCase, _Config) -> + ok. + +%%-------------------------------------------------------------------- +%% @spec groups() -> [Group] +%% Group = {GroupName,Properties,GroupsAndTestCases} +%% GroupName = atom() +%% Properties = [parallel | sequence | Shuffle | {RepeatType,N}] +%% GroupsAndTestCases = [Group | {group,GroupName} | TestCase] +%% TestCase = atom() +%% Shuffle = shuffle | {shuffle,{integer(),integer(),integer()}} +%% RepeatType = repeat | repeat_until_all_ok | repeat_until_all_fail | +%% repeat_until_any_ok | repeat_until_any_fail +%% N = integer() | forever +%% @end +%%-------------------------------------------------------------------- +groups() -> + [{g1,[parallel],[tc1,tc2,tc3]}, + {g2,[],[tc4,tc5]}]. + +%%-------------------------------------------------------------------- +%% @spec all() -> GroupsAndTestCases | {skip,Reason} +%% GroupsAndTestCases = [{group,GroupName} | TestCase] +%% GroupName = atom() +%% TestCase = atom() +%% Reason = term() +%% @end +%%-------------------------------------------------------------------- +all() -> + [{group,g1},tc1,tc2,{group,g2}]. + +tc1(_C) -> + ok. +tc2(_C) -> + ok. +tc3(_C) -> + ok. +tc4(_C) -> + ok. +tc5(_C) -> + ok. diff --git a/lib/common_test/test/ct_test_support.erl b/lib/common_test/test/ct_test_support.erl index 4132995bf6..67e430f821 100644 --- a/lib/common_test/test/ct_test_support.erl +++ b/lib/common_test/test/ct_test_support.erl @@ -38,7 +38,7 @@ -export([start_slave/3, slave_stop/1]). --export([ct_test_halt/1]). +-export([ct_test_halt/1, ct_rpc/2]). -include_lib("kernel/include/file.hrl"). @@ -65,7 +65,6 @@ init_per_suite(Config, Level) -> _ -> ok end, - start_slave(Config, Level). start_slave(Config, Level) -> @@ -103,6 +102,14 @@ start_slave(NodeName, Config, Level) -> test_server:format(Level, "Dirs added to code path (on ~w):~n", [CTNode]), [io:format("~s~n", [D]) || D <- PathDirs], + + case proplists:get_value(start_sasl, Config) of + true -> + rpc:call(CTNode, application, start, [sasl]), + test_server:format(Level, "SASL started on ~w~n", [CTNode]); + _ -> + ok + end, TraceFile = filename:join(DataDir, "ct.trace"), case file:read_file_info(TraceFile) of @@ -378,6 +385,16 @@ wait_for_ct_stop(Retries, CTNode) -> end. %%%----------------------------------------------------------------- +%%% ct_rpc/1 +ct_rpc({M,F,A}, Config) -> + CTNode = proplists:get_value(ct_node, Config), + Level = proplists:get_value(trace_level, Config), + test_server:format(Level, "~nCalling ~w:~w(~p) on ~p...", + [M,F,A, CTNode]), + rpc:call(CTNode, M, F, A). + + +%%%----------------------------------------------------------------- %%% EVENT HANDLING handle_event(EH, Event) -> diff --git a/lib/common_test/vsn.mk b/lib/common_test/vsn.mk index d60b4ba675..c810a0d98d 100644 --- a/lib/common_test/vsn.mk +++ b/lib/common_test/vsn.mk @@ -1 +1 @@ -COMMON_TEST_VSN = 1.7.2 +COMMON_TEST_VSN = 1.7.3 diff --git a/lib/compiler/doc/src/compile.xml b/lib/compiler/doc/src/compile.xml index 96907f6b10..73d75851cf 100644 --- a/lib/compiler/doc/src/compile.xml +++ b/lib/compiler/doc/src/compile.xml @@ -859,6 +859,10 @@ pi() -> 3.1416. {ErrorLine, Module, ErrorDescriptor} </code> + <p><c>ErrorLine</c> will be the atom <c>none</c> if the error does + not correspond to a specific line (e.g. if the source file does + not exist).</p> + <p>A string describing the error is obtained with the following call:</p> <code> diff --git a/lib/compiler/doc/src/notes.xml b/lib/compiler/doc/src/notes.xml index 837fcf4368..eb5fa8b398 100644 --- a/lib/compiler/doc/src/notes.xml +++ b/lib/compiler/doc/src/notes.xml @@ -31,6 +31,67 @@ <p>This document describes the changes made to the Compiler application.</p> +<section><title>Compiler 4.9.3</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Expressions such as <c>'B = is_integer(V), if B and B + -> ok end'</c> would crash the compiler.</p> + <p> + Own Id: OTP-11240</p> + </item> + <item> + <p> + <c>compile:file2/2</c> with the option + <c>report_errors</c> could return ErrorInfo tuples with + only two elements, while the documentation says that the + ErrorInfo tuple always has three elements. Also updated + the documentation to add that the first element may be + '<c>none</c>' if no line number is applicable.</p> + <p> + Own Id: OTP-11304 Aux Id: seq12412 </p> + </item> + </list> + </section> + + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Fix matching of floating point middle-endian machines. + Thanks to Johannes Weissl.</p> + <p> + Own Id: OTP-11201</p> + </item> + <item> + <p> + Restrict inlining of local fun references. Thanks to + Anthony Ramine.</p> + <p> + Own Id: OTP-11211</p> + </item> + <item> + <p> + Silence a misleading warning with some comprehensions. + Thanks to Anthony Ramine.</p> + <p> + Own Id: OTP-11212</p> + </item> + <item> + <p> + Forbid returning a match context in beam_validator. + Thanks to Anthony Ramine.</p> + <p> + Own Id: OTP-11247</p> + </item> + </list> + </section> + +</section> + <section><title>Compiler 4.9.2</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/compiler/src/beam_clean.erl b/lib/compiler/src/beam_clean.erl index e208ffec1f..9d89e21a4e 100644 --- a/lib/compiler/src/beam_clean.erl +++ b/lib/compiler/src/beam_clean.erl @@ -86,7 +86,7 @@ add_to_work_list(F, {Fs,Used}=Sets) -> false -> {[F|Fs],sets:add_element(F, Used)} end. - + %%% %%% Coalesce adjacent labels. Renumber all labels to eliminate gaps. %%% This cleanup will slightly reduce file size and slightly speed up loading. diff --git a/lib/compiler/src/beam_type.erl b/lib/compiler/src/beam_type.erl index 3b51216a6c..3ec57a67da 100644 --- a/lib/compiler/src/beam_type.erl +++ b/lib/compiler/src/beam_type.erl @@ -600,7 +600,7 @@ checkerror_1([], OrigIs) -> OrigIs. checkerror_2(OrigIs) -> [{set,[],[],fcheckerror}|OrigIs]. - + %%% Routines for maintaining a type database. The type database %%% associates type information with registers. %%% diff --git a/lib/compiler/src/compile.erl b/lib/compiler/src/compile.erl index 2ca403de54..47d446273b 100644 --- a/lib/compiler/src/compile.erl +++ b/lib/compiler/src/compile.erl @@ -41,7 +41,8 @@ -type option() :: atom() | {atom(), term()} | {'d', atom(), term()}. --type err_info() :: {erl_scan:line(), module(), term()}. %% ErrorDescriptor +-type err_info() :: {erl_scan:line() | 'none', + module(), term()}. %% ErrorDescriptor -type errors() :: [{file:filename(), [err_info()]}]. -type warnings() :: [{file:filename(), [err_info()]}]. -type mod_ret() :: {'ok', module()} @@ -1290,10 +1291,10 @@ native_compile_1(St) -> {error,R} -> case IgnoreErrors of true -> - Ws = [{St#compile.ifile,[{?MODULE,{native,R}}]}], + Ws = [{St#compile.ifile,[{none,?MODULE,{native,R}}]}], {ok,St#compile{warnings=St#compile.warnings ++ Ws}}; false -> - Es = [{St#compile.ifile,[{?MODULE,{native,R}}]}], + Es = [{St#compile.ifile,[{none,?MODULE,{native,R}}]}], {error,St#compile{errors=St#compile.errors ++ Es}} end catch @@ -1302,7 +1303,7 @@ native_compile_1(St) -> case IgnoreErrors of true -> Ws = [{St#compile.ifile, - [{?MODULE,{native_crash,R,Stk}}]}], + [{none,?MODULE,{native_crash,R,Stk}}]}], {ok,St#compile{warnings=St#compile.warnings ++ Ws}}; false -> erlang:raise(Class, R, Stk) @@ -1349,7 +1350,7 @@ save_binary(#compile{module=Mod,ofile=Outfile, save_binary_1(St); _ -> Es = [{St#compile.ofile, - [{?MODULE,{module_name,Mod,Base}}]}], + [{none,?MODULE,{module_name,Mod,Base}}]}], {error,St#compile{errors=St#compile.errors ++ Es}} end end. @@ -1363,20 +1364,20 @@ save_binary_1(St) -> ok -> {ok,St}; {error,RenameError} -> - Es0 = [{Ofile,[{?MODULE,{rename,Tfile,Ofile, - RenameError}}]}], + Es0 = [{Ofile,[{none,?MODULE,{rename,Tfile,Ofile, + RenameError}}]}], Es = case file:delete(Tfile) of ok -> Es0; {error,DeleteError} -> Es0 ++ [{Ofile, - [{?MODULE,{delete_temp,Tfile, - DeleteError}}]}] + [{none,?MODULE,{delete_temp,Tfile, + DeleteError}}]}] end, {error,St#compile{errors=St#compile.errors ++ Es}} end; {error,_Error} -> - Es = [{Tfile,[{compile,write_error}]}], + Es = [{Tfile,[{none,compile,write_error}]}], {error,St#compile{errors=St#compile.errors ++ Es}} end. @@ -1419,6 +1420,9 @@ report_warnings(#compile{options=Opts,warnings=Ws0}) -> false -> ok end. +format_message(F, P, [{none,Mod,E}|Es]) -> + M = {none,io_lib:format("~ts: ~s~ts\n", [F,P,Mod:format_error(E)])}, + [M|format_message(F, P, Es)]; format_message(F, P, [{{Line,Column}=Loc,Mod,E}|Es]) -> M = {{F,Loc},io_lib:format("~ts:~w:~w ~s~ts\n", [F,Line,Column,P,Mod:format_error(E)])}, @@ -1428,12 +1432,17 @@ format_message(F, P, [{Line,Mod,E}|Es]) -> [F,Line,P,Mod:format_error(E)])}, [M|format_message(F, P, Es)]; format_message(F, P, [{Mod,E}|Es]) -> + %% Not documented and not expected to be used any more, but + %% keep a while just in case. M = {none,io_lib:format("~ts: ~s~ts\n", [F,P,Mod:format_error(E)])}, [M|format_message(F, P, Es)]; format_message(_, _, []) -> []. %% list_errors(File, ErrorDescriptors) -> ok +list_errors(F, [{none,Mod,E}|Es]) -> + io:fwrite("~ts: ~ts\n", [F,Mod:format_error(E)]), + list_errors(F, Es); list_errors(F, [{{Line,Column},Mod,E}|Es]) -> io:fwrite("~ts:~w:~w: ~ts\n", [F,Line,Column,Mod:format_error(E)]), list_errors(F, Es); @@ -1441,6 +1450,8 @@ list_errors(F, [{Line,Mod,E}|Es]) -> io:fwrite("~ts:~w: ~ts\n", [F,Line,Mod:format_error(E)]), list_errors(F, Es); list_errors(F, [{Mod,E}|Es]) -> + %% Not documented and not expected to be used any more, but + %% keep a while just in case. io:fwrite("~ts: ~ts\n", [F,Mod:format_error(E)]), list_errors(F, Es); list_errors(_F, []) -> ok. @@ -1545,7 +1556,7 @@ restore_expand_module([F|Fs]) -> [F|restore_expand_module(Fs)]; restore_expand_module([]) -> []. - + -spec options() -> 'ok'. options() -> @@ -1582,7 +1593,7 @@ help([_|T]) -> help(_) -> ok. - + %% compile(AbsFileName, Outfilename, Options) %% Compile entry point for erl_compile. diff --git a/lib/compiler/src/core_lint.erl b/lib/compiler/src/core_lint.erl index 1e8983f594..67d37ff1fc 100644 --- a/lib/compiler/src/core_lint.erl +++ b/lib/compiler/src/core_lint.erl @@ -68,7 +68,7 @@ | {'undefined_function', fa(), fa()} | {'tail_segment_not_at_end', fa()}. --type error() :: {module(), err_desc()}. +-type error() :: {'none', module(), err_desc()}. -type warning() :: {module(), term()}. %%----------------------------------------------------------------------- @@ -162,7 +162,7 @@ return_status(St) -> %% add_warning(ErrorDescriptor, State) -> State' %% Note that we don't use line numbers here. -add_error(E, St) -> St#lint{errors=[{?MODULE,E}|St#lint.errors]}. +add_error(E, St) -> St#lint{errors=[{none,?MODULE,E}|St#lint.errors]}. %%add_warning(W, St) -> St#lint{warnings=[{none,core_lint,W}|St#lint.warnings]}. diff --git a/lib/compiler/src/core_scan.erl b/lib/compiler/src/core_scan.erl index 0d90739bfc..a4fe920258 100644 --- a/lib/compiler/src/core_scan.erl +++ b/lib/compiler/src/core_scan.erl @@ -95,7 +95,7 @@ format_error(Other) -> io_lib:write(Other). string_thing($') -> "atom"; %' stupid emacs string_thing($") -> "string". %" stupid emacs - + %% Re-entrant pre-scanner. %% %% If the input list of characters is insufficient to build a term the @@ -213,7 +213,7 @@ pre_comment(eof, Sofar, Pos) -> pre_error(E, Epos, Pos) -> {error,{Epos,core_scan,E}, Pos}. - + %% scan(CharList, StartPos) %% This takes a list of characters and tries to tokenise them. %% diff --git a/lib/compiler/src/genop.tab b/lib/compiler/src/genop.tab index 75ac91907a..ebc9b1c85b 100644..100755 --- a/lib/compiler/src/genop.tab +++ b/lib/compiler/src/genop.tab @@ -23,45 +23,148 @@ BEAM_FORMAT_NUMBER=0 # arity or semantics, the format number above must be bumped. # +## @spec label Lbl +## @doc Specify a module local label. +## Label gives this code address a name (Lbl) and marks the start of +## a basic block. 1: label/1 + +## @spec func_info M F A +## @doc Define a function M:F/A 2: func_info/3 + 3: int_code_end/0 # # Function and BIF calls. # + +## @spec call Arity Label +## @doc Call the function at Label. +## Save the next instruction as the return address in the CP register. 4: call/2 + +## @spec call_last Arity Label Dellocate +## @doc Deallocate and do a tail recursive call to the function at Label. +## Do not update the CP register. +## Before the call deallocate Deallocate words of stack. 5: call_last/3 + +## @spec call_only Arity Label +## @doc Do a tail recursive call to the function at Label. +## Do not update the CP register. 6: call_only/2 +## @spec call_ext Arity Destination +## @doc Call the function of arity Arity pointed to by Destination. +## Save the next instruction as the return address in the CP register. 7: call_ext/2 + +## @spec call_ext_last Arity Destination Deallocate +## @doc Deallocate and do a tail call to function of arity Arity +## pointed to by Destination. +## Do not update the CP register. +## Deallocate Deallocate words from the stack before the call. 8: call_ext_last/3 +## @spec bif0 Bif Reg +## @doc Call the bif Bif and store the result in Reg. 9: bif0/2 + +## @spec bif1 Lbl Bif Arg Reg +## @doc Call the bif Bif with the argument Arg, and store the result in Reg. +## On failure jump to Lbl. 10: bif1/4 + +## @spec bif2 Lbl Bif Arg1 Arg2 Reg +## @doc Call the bif Bif with the arguments Arg1 and Arg2, +## and store the result in Reg. +## On failure jump to Lbl. 11: bif2/5 # # Allocating, deallocating and returning. # + +## @spec allocate StackNeed Live +## @doc Allocate space for StackNeed words on the stack. If a GC is needed +## during allocation there are Live number of live X registers. +## Also save the continuation pointer (CP) on the stack. 12: allocate/2 + +## @spec allocate_heap StackNeed HeapNeed Live +## @doc Allocate space for StackNeed words on the stack and ensure there is +## space for HeapNeed words on the heap. If a GC is needed +## save Live number of X registers. +## Also save the continuation pointer (CP) on the stack. 13: allocate_heap/3 + +## @spec allocate_zero StackNeed Live +## @doc Allocate space for StackNeed words on the stack. If a GC is needed +## during allocation there are Live number of live X registers. +## Clear the new stack words. (By writing NIL.) +## Also save the continuation pointer (CP) on the stack. 14: allocate_zero/2 + +## @spec allocate_heap_zero StackNeed HeapNeed Live +## @doc Allocate space for StackNeed words on the stack and HeapNeed words +## on the heap. If a GC is needed +## during allocation there are Live number of live X registers. +## Clear the new stack words. (By writing NIL.) +## Also save the continuation pointer (CP) on the stack. 15: allocate_heap_zero/3 + +## @spec test_heap HeapNeed Live +## @doc Ensure there is space for HeapNeed words on the heap. If a GC is needed +## save Live number of X registers. 16: test_heap/2 + +## @spec init N +## @doc Clear the Nth stack word. (By writing NIL.) 17: init/1 + +## @spec deallocate N +## @doc Restore the continuation pointer (CP) from the stack and deallocate +## N+1 words from the stack (the + 1 is for the CP). 18: deallocate/1 + +## @spec return +## @doc Return to the address in the continuation pointer (CP). 19: return/0 # # Sending & receiving. # +## @spec send +## @doc Send argument in x(0) as a message to the destination process in x(0). +## The message in x(1) ends up as the result of the send in x(0). 20: send/0 + +## @spec remove_message +## @doc Unlink the current message from the message queue and store a +## pointer to the message in x(0). Remove any timeout. 21: remove_message/0 + +## @spec timeout +## @doc Reset the save point of the mailbox and clear the timeout flag. 22: timeout/0 + +## @spec loop_rec Label Source +## @doc Loop over the message queue, if it is empty jump to Label. 23: loop_rec/2 + +## @spec loop_rec_end Label +## @doc Advance the save pointer to the next message and jump back to Label. 24: loop_rec_end/1 + +## @spec wait Label +## @doc Suspend the processes and set the entry point to the beginning of the +## receive loop at Label. 25: wait/1 + +## @spec wait_timeout Lable Time +## @doc Sets up a timeout of Time milllisecons and saves the address of the +## following instruction as the entry point if the timeout triggers. 26: wait_timeout/2 # @@ -83,36 +186,106 @@ BEAM_FORMAT_NUMBER=0 # # Comparision operators. # + +## @spec is_lt Lbl Arg1 Arg2 +## @doc Compare two terms and jump to Lbl if Arg1 is not less than Arg2. 39: is_lt/3 + +## @spec is_ge Lbl Arg1 Arg2 +## @doc Compare two terms and jump to Lbl if Arg1 is less than Arg2. 40: is_ge/3 + +## @spec is_eq Lbl Arg1 Arg2 +## @doc Compare two terms and jump to Lbl if Arg1 is not (numerically) equal to Arg2. 41: is_eq/3 + +## @spec is_ne Lbl Arg1 Arg2 +## @doc Compare two terms and jump to Lbl if Arg1 is (numerically) equal to Arg2. 42: is_ne/3 + +## @spec is_eq_exact Lbl Arg1 Arg2 +## @doc Compare two terms and jump to Lbl if Arg1 is not exactly equal to Arg2. 43: is_eq_exact/3 + +## @spec is_ne_exact Lbl Arg1 Arg2 +## @doc Compare two terms and jump to Lbl if Arg1 is exactly equal to Arg2. 44: is_ne_exact/3 # # Type tests. # + +## @spec is_integer Lbl Arg1 +## @doc Test the type of Arg1 and jump to Lbl if it is not an integer. 45: is_integer/2 + +## @spec is_float Lbl Arg1 +## @doc Test the type of Arg1 and jump to Lbl if it is not a float. 46: is_float/2 + +## @spec is_number Lbl Arg1 +## @doc Test the type of Arg1 and jump to Lbl if it is not a number. 47: is_number/2 + +## @spec is_atom Lbl Arg1 +## @doc Test the type of Arg1 and jump to Lbl if it is not an atom. 48: is_atom/2 + +## @spec is_pid Lbl Arg1 +## @doc Test the type of Arg1 and jump to Lbl if it is not a pid. 49: is_pid/2 + +## @spec is_reference Lbl Arg1 +## @doc Test the type of Arg1 and jump to Lbl if it is not a reference. 50: is_reference/2 + +## @spec is_port Lbl Arg1 +## @doc Test the type of Arg1 and jump to Lbl if it is not a port. 51: is_port/2 + +## @spec is_nil Lbl Arg1 +## @doc Test the type of Arg1 and jump to Lbl if it is not nil. 52: is_nil/2 + +## @spec is_binary Lbl Arg1 +## @doc Test the type of Arg1 and jump to Lbl if it is not a binary. 53: is_binary/2 + 54: -is_constant/2 + +## @spec is_list Lbl Arg1 +## @doc Test the type of Arg1 and jump to Lbl if it is not a cons or nil. 55: is_list/2 + +## @spec is_nonempty_list Lbl Arg1 +## @doc Test the type of Arg1 and jump to Lbl if it is not a cons. 56: is_nonempty_list/2 + +## @spec is_tuple Lbl Arg1 +## @doc Test the type of Arg1 and jump to Lbl if it is not a tuple. 57: is_tuple/2 + +## @spec test_arity Lbl Arg1 Arity +## @doc Test the arity of (the tuple in) Arg1 and jump +## to Lbl if it is not equal to Arity. 58: test_arity/3 # # Indexing & jumping. # + +## @spec select_val Arg FailLabel Destinations +## @doc Jump to the destination label corresponding to Arg +## in the Destinations list, if no arity matches, jump to FailLabel. 59: select_val/3 + +## @spec select_tuple_arity Tuple FailLabel Destinations +## @doc Check the arity of the tuple Tuple and jump to the corresponding +## destination label, if no arity matches, jump to FailLabel. 60: select_tuple_arity/3 + +## @spec jump Label +## @doc Jump to Label. 61: jump/1 # @@ -124,9 +297,26 @@ BEAM_FORMAT_NUMBER=0 # # Moving, extracting, modifying. # + +## @spec move Source Destination +## @doc Move the source Source (a literal or a register) to +## the destination register Destination. 64: move/2 + +## @spec get_list Source Head Tail +## @doc Get the head and tail (or car and cdr) parts of a list +## (a cons cell) from Source and put them into the registers +## Head and Tail. 65: get_list/3 + +## @spec get_tuple_element Source Element Destination +## @doc Get element number Element from the tuple in Source and put +## it in the destination register Destination. 66: get_tuple_element/3 + +## @spec set_tuple_element NewElement Tuple Position +## @doc Update the element at postition Position of the tuple Tuple +## with the new element NewElement. 67: set_tuple_element/3 # @@ -147,13 +337,26 @@ BEAM_FORMAT_NUMBER=0 # # 'fun' support. # +## @spec call_fun Arity +## @doc Call a fun of arity Arity. Assume arguments in +## registers x(0) to x(Arity-1) and that the fun is in x(Arity). +## Save the next instruction as the return address in the CP register. 75: call_fun/1 + 76: -make_fun/3 + +## @spec is_function Lbl Arg1 +## @doc Test the type of Arg1 and jump to Lbl if it is not a +## function (i.e. fun or closure). 77: is_function/2 # # Late additions to R5. # + +## @spec call_ext_only Arity Label +## Do a tail recursive call to the function at Label. +## Do not update the CP register. 78: call_ext_only/2 # @@ -212,9 +415,14 @@ BEAM_FORMAT_NUMBER=0 111: bs_add/5 112: apply/1 113: apply_last/2 +## @spec is_boolean Lbl Arg1 +## @doc Test the type of Arg1 and jump to Lbl if it is not a Boolean. 114: is_boolean/2 # New instructions in R10B-6. +## @spec is_function2 Lbl Arg1 Arity +## @doc Test the type of Arg1 and jump to Lbl if it is not a +## function of arity Arity. 115: is_function2/3 # New bit syntax matching in R11B. @@ -229,7 +437,20 @@ BEAM_FORMAT_NUMBER=0 123: bs_restore2/2 # New GC bifs introduced in R11B. + +## @spec gc_bif1 Lbl Live Bif Arg Reg +## @doc Call the bif Bif with the argument Arg, and store the result in Reg. +## On failure jump to Lbl. +## Do a garbage collection if necessary to allocate space on the heap +## for the result (saving Live number of X registers). 124: gc_bif1/5 + +## @spec gc_bif2 Lbl Live Bif Arg1 Arg2 Reg +## @doc Call the bif Bif with the arguments Arg1 and Arg2, +## and store the result in Reg. +## On failure jump to Lbl. +## Do a garbage collection if necessary to allocate space on the heap +## for the result (saving Live number of X registers). 125: gc_bif2/6 # Experimental new bit_level bifs introduced in R11B. @@ -241,6 +462,8 @@ BEAM_FORMAT_NUMBER=0 128: -put_literal/2 # R11B-5 +## @spec is_bitstr Lbl Arg1 +## @doc Test the type of Arg1 and jump to Lbl if it is not a bit string. 129: is_bitstr/2 # R12B @@ -250,7 +473,12 @@ BEAM_FORMAT_NUMBER=0 133: bs_init_writable/0 134: bs_append/8 135: bs_private_append/6 + +## @spec trim N Remaining +## @doc Reduce the stack usage by N words, +## keeping the CP on the top of the stack. 136: trim/2 + 137: bs_init_bits/6 # R12B-5 @@ -277,8 +505,24 @@ BEAM_FORMAT_NUMBER=0 # R14A +## @spec recv_mark Label +## @doc Save the end of the message queue and the address of +## the label Label so that a recv_set instruction can start +## scanning the inbox from this position. 150: recv_mark/1 + +## @spec recv_set Label +## @doc Check that the saved mark points to Label and set the +## save pointer in the message queue to the last position +## of the message queue saved by the recv_mark instruction. 151: recv_set/1 + +## @spec gc_bif3 Lbl Live Bif Arg1 Arg2 Arg3 Reg +## @doc Call the bif Bif with the arguments Arg1, Arg2 and Arg3, +## and store the result in Reg. +## On failure jump to Lbl. +## Do a garbage collection if necessary to allocate space on the heap +## for the result (saving Live number of X registers). 152: gc_bif3/7 # R15A diff --git a/lib/compiler/src/v3_core.erl b/lib/compiler/src/v3_core.erl index 6dc4f3f300..33f5015e0b 100644 --- a/lib/compiler/src/v3_core.erl +++ b/lib/compiler/src/v3_core.erl @@ -553,16 +553,22 @@ expr({'try',L,Es0,[],[],As0}, St0) -> %% 'try ... after ... end' {Es1,St1} = exprs(Es0, St0), {As1,St2} = exprs(As0, St1), - {Evs,Hs0,St3} = try_after(As1, St2), - %% We must kill the id for any funs in the duplicated after body, - %% to avoid getting two local functions having the same name. - Hs = kill_id_anns(Hs0), + {Name,St3} = new_fun_name("after", St2), {V,St4} = new_var(St3), % (must not exist in As1) - %% TODO: this duplicates the 'after'-code; should lift to function. - Lanno = lineno_anno(L, St4), - {#itry{anno=#a{anno=Lanno},args=Es1,vars=[V],body=As1++[V], - evars=Evs,handler=Hs}, - [],St4}; + LA = lineno_anno(L, St4), + Lanno = #a{anno=LA}, + Fc = function_clause([], LA, {Name,0}), + Fun = #ifun{anno=Lanno,id=[],vars=[], + clauses=[#iclause{anno=Lanno,pats=[], + guard=[#c_literal{val=true}], + body=As1}], + fc=Fc}, + App = #iapply{anno=Lanno,op=#c_var{anno=LA,name={Name,0}},args=[]}, + {Evs,Hs,St5} = try_after([App], St4), + Try = #itry{anno=Lanno,args=Es1,vars=[V],body=[App,V],evars=Evs,handler=Hs}, + Letrec = #iletrec{anno=Lanno,defs=[{{Name,0},Fun}], + body=[Try]}, + {Letrec,[],St5}; expr({'try',L,Es,Cs,Ecs,As}, St0) -> %% 'try ... [of ...] [catch ...] after ... end' expr({'try',L,[{'try',L,Es,Cs,Ecs,[]}],[],[],As}, St0); @@ -1897,7 +1903,7 @@ new_in_all([Le|Les]) -> foldl(fun (L, Ns) -> intersection((get_anno(L))#a.ns, Ns) end, (get_anno(Le))#a.ns, Les); new_in_all([]) -> []. - + %% The AfterVars are the variables which are used afterwards. We need %% this to work out which variables are actually exported and used %% from case/receive. In subblocks/clauses the AfterVars of the block @@ -2041,24 +2047,6 @@ cexpr(Lit, _As, St) -> %%Vs = lit_vars(Lit), {set_anno(Lit, Anno#a.anno),[],Vs,St}. -%% Kill the id annotations for any fun inside the expression. -%% Necessary when duplicating code in try ... after. - -kill_id_anns(#ifun{clauses=Cs0}=Fun) -> - Cs = kill_id_anns(Cs0), - Fun#ifun{clauses=Cs,id=[]}; -kill_id_anns(#a{}=A) -> - %% Optimization: Don't waste time searching for funs inside annotations. - A; -kill_id_anns([H|T]) -> - [kill_id_anns(H)|kill_id_anns(T)]; -kill_id_anns([]) -> []; -kill_id_anns(Tuple) when is_tuple(Tuple) -> - L0 = tuple_to_list(Tuple), - L = kill_id_anns(L0), - list_to_tuple(L); -kill_id_anns(Other) -> Other. - %% lit_vars(Literal) -> [Var]. lit_vars(Lit) -> lit_vars(Lit, []). diff --git a/lib/compiler/src/v3_kernel.erl b/lib/compiler/src/v3_kernel.erl index 5f1c108f7c..65f1251099 100644 --- a/lib/compiler/src/v3_kernel.erl +++ b/lib/compiler/src/v3_kernel.erl @@ -160,8 +160,8 @@ function({#c_var{name={F,Arity}=FA},Body}, St0) -> io:fwrite("Function: ~w/~w\n", [F,Arity]), erlang:raise(Class, Error, Stack) end. - - + + %% body(Cexpr, Sub, State) -> {Kexpr,[PreKepxr],State}. %% Do the main sequence of a body. A body ends in an atomic value or %% values. Must check if vector first so do expr. @@ -834,7 +834,7 @@ last([_|T]) -> last(T). first([_]) -> []; first([H|T]) -> [H|first(T)]. - + %% This code implements the algorithm for an optimizing compiler for %% pattern matching given "The Implementation of Functional %% Programming Languages" by Simon Peyton Jones. The code is much @@ -1428,7 +1428,7 @@ arg_val(Arg, C) -> {set_kanno(S, []),U,T,Fs} end end. - + %% ubody_used_vars(Expr, State) -> [UsedVar] %% Return all used variables for the body sequence. Much more %% efficient than using ubody/3 if the body contains nested letrecs. @@ -1875,7 +1875,7 @@ format_error(bad_segment_size) -> add_warning(none, Term, Anno, #kern{ws=Ws}=St) -> File = get_file(Anno), - St#kern{ws=[{File,[{?MODULE,Term}]}|Ws]}; + St#kern{ws=[{File,[{none,?MODULE,Term}]}|Ws]}; add_warning(Line, Term, Anno, #kern{ws=Ws}=St) -> File = get_file(Anno), St#kern{ws=[{File,[{Line,?MODULE,Term}]}|Ws]}. diff --git a/lib/compiler/test/compile_SUITE.erl b/lib/compiler/test/compile_SUITE.erl index da8aecdc8b..66ce6c00ab 100644 --- a/lib/compiler/test/compile_SUITE.erl +++ b/lib/compiler/test/compile_SUITE.erl @@ -139,8 +139,8 @@ forms_2(Config) when is_list(Config) -> module_mismatch(Config) when is_list(Config) -> ?line DataDir = ?config(data_dir, Config), ?line File = filename:join(DataDir, "wrong_module_name.erl"), - ?line {error,[{"wrong_module_name.beam", - [{compile,{module_name,arne,"wrong_module_name"}}]}], + {error,[{"wrong_module_name.beam", + [{none,compile,{module_name,arne,"wrong_module_name"}}]}], []} = compile:file(File, [return]), ?line error = compile:file(File, [report]), diff --git a/lib/compiler/test/core_fold_SUITE.erl b/lib/compiler/test/core_fold_SUITE.erl index abc9ab6a72..a5a4e62a42 100644 --- a/lib/compiler/test/core_fold_SUITE.erl +++ b/lib/compiler/test/core_fold_SUITE.erl @@ -299,7 +299,7 @@ unused_multiple_values_error(Config) when is_list(Config) -> Opts = [no_copt,clint,return,from_core,{outdir,PrivDir} |test_lib:opt_opts(?MODULE)], {error,[{unused_multiple_values_error, - [{core_lint,{return_mismatch,{hello,1}}}]}], + [{none,core_lint,{return_mismatch,{hello,1}}}]}], []} = c:c(Core, Opts), ok. diff --git a/lib/compiler/vsn.mk b/lib/compiler/vsn.mk index 1c6f49d89b..8cfd8d294e 100644 --- a/lib/compiler/vsn.mk +++ b/lib/compiler/vsn.mk @@ -1 +1 @@ -COMPILER_VSN = 4.9.2 +COMPILER_VSN = 4.9.3 diff --git a/lib/crypto/doc/src/notes.xml b/lib/crypto/doc/src/notes.xml index 6abe19eac5..0ff0c8aa96 100644 --- a/lib/crypto/doc/src/notes.xml +++ b/lib/crypto/doc/src/notes.xml @@ -30,6 +30,22 @@ </header> <p>This document describes the changes made to the Crypto application.</p> +<section><title>Crypto 3.1</title> + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Refactor ecdsa cipher to simplify code and improve + performance.</p> + <p> + Own Id: OTP-11320</p> + </item> + </list> + </section> + +</section> + <section><title>Crypto 3.0</title> <section><title>Improvements and New Features</title> diff --git a/lib/crypto/vsn.mk b/lib/crypto/vsn.mk index d5d7c8a128..3bd2f9b4bf 100644 --- a/lib/crypto/vsn.mk +++ b/lib/crypto/vsn.mk @@ -1 +1 @@ -CRYPTO_VSN = 3.0 +CRYPTO_VSN = 3.1 diff --git a/lib/debugger/doc/src/notes.xml b/lib/debugger/doc/src/notes.xml index 5f1d411db2..a3543a1e11 100644 --- a/lib/debugger/doc/src/notes.xml +++ b/lib/debugger/doc/src/notes.xml @@ -32,6 +32,22 @@ <p>This document describes the changes made to the Debugger application.</p> +<section><title>Debugger 3.2.12</title> + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Fix matching of floating point middle-endian machines. + Thanks to Johannes Weissl.</p> + <p> + Own Id: OTP-11201</p> + </item> + </list> + </section> + +</section> + <section><title>Debugger 3.2.11</title> <section><title>Improvements and New Features</title> diff --git a/lib/debugger/test/dbg_ui_SUITE_data/manual_data/src/lists1.erl b/lib/debugger/test/dbg_ui_SUITE_data/manual_data/src/lists1.erl index 0214983c11..db84ee5fc8 100644 --- a/lib/debugger/test/dbg_ui_SUITE_data/manual_data/src/lists1.erl +++ b/lib/debugger/test/dbg_ui_SUITE_data/manual_data/src/lists1.erl @@ -236,7 +236,7 @@ flatlength([H|T], L) when list(H) -> flatlength([H|T], L) -> flatlength(T, L + 1); flatlength([], L) -> L. - + %% keymember(Key, Index, [Tuple]) %% keysearch(Key, Index, [Tuple]) %% keydelete(Key, Index, [Tuple]) @@ -298,7 +298,7 @@ keymap(Fun, ExtraArgs, Index, [Tup|Tail]) -> [setelement(Index, Tup, apply(Fun, [element(Index, Tup)|ExtraArgs]))| keymap(Fun, ExtraArgs, Index, Tail)]; keymap( _, _ , _, []) -> []. - + %% all(Predicate, List) %% any(Predicate, List) %% map(Function, List) diff --git a/lib/debugger/test/int_SUITE_data/lists1.erl b/lib/debugger/test/int_SUITE_data/lists1.erl index 0214983c11..db84ee5fc8 100644 --- a/lib/debugger/test/int_SUITE_data/lists1.erl +++ b/lib/debugger/test/int_SUITE_data/lists1.erl @@ -236,7 +236,7 @@ flatlength([H|T], L) when list(H) -> flatlength([H|T], L) -> flatlength(T, L + 1); flatlength([], L) -> L. - + %% keymember(Key, Index, [Tuple]) %% keysearch(Key, Index, [Tuple]) %% keydelete(Key, Index, [Tuple]) @@ -298,7 +298,7 @@ keymap(Fun, ExtraArgs, Index, [Tup|Tail]) -> [setelement(Index, Tup, apply(Fun, [element(Index, Tup)|ExtraArgs]))| keymap(Fun, ExtraArgs, Index, Tail)]; keymap( _, _ , _, []) -> []. - + %% all(Predicate, List) %% any(Predicate, List) %% map(Function, List) diff --git a/lib/debugger/test/int_SUITE_data/my_lists.erl b/lib/debugger/test/int_SUITE_data/my_lists.erl index 98eb4396e3..f9399b1085 100644 --- a/lib/debugger/test/int_SUITE_data/my_lists.erl +++ b/lib/debugger/test/int_SUITE_data/my_lists.erl @@ -237,7 +237,7 @@ flatlength([H|T], L) when list(H) -> flatlength([H|T], L) -> flatlength(T, L + 1); flatlength([], L) -> L. - + %% keymember(Key, Index, [Tuple]) %% keysearch(Key, Index, [Tuple]) %% keydelete(Key, Index, [Tuple]) @@ -299,7 +299,7 @@ keymap(Fun, ExtraArgs, Index, [Tup|Tail]) -> [setelement(Index, Tup, apply(Fun, [element(Index, Tup)|ExtraArgs]))| keymap(Fun, ExtraArgs, Index, Tail)]; keymap( _, _ , _, []) -> []. - + %% all(Predicate, List) %% any(Predicate, List) %% map(Function, List) @@ -698,7 +698,7 @@ flatlength_1([H|T], L) when list(H) -> flatlength_1([H|T], L) -> flatlength_1(T, L + 1); flatlength_1([], L) -> L. - + %% keymember(Key, Index, [Tuple]) %% keysearch(Key, Index, [Tuple]) %% keydelete(Key, Index, [Tuple]) @@ -760,7 +760,7 @@ keymap_1(Fun, ExtraArgs, Index, [Tup|Tail]) -> [setelement(Index, Tup, apply(Fun, [element(Index, Tup)|ExtraArgs]))| keymap_1(Fun, ExtraArgs, Index, Tail)]; keymap_1( _, _ , _, []) -> []. - + %% all(Predicate, List) %% any(Predicate, List) %% map(Function, List) @@ -1162,7 +1162,7 @@ flatlength_2([H|T], L) when list(H) -> flatlength_2([H|T], L) -> flatlength_2(T, L + 1); flatlength_2([], L) -> L. - + %% keymember_2(Key, Index, [Tuple]) %% keysearch_2(Key, Index, [Tuple]) %% keydelete_2(Key, Index, [Tuple]) @@ -1224,7 +1224,7 @@ keymap_2(Fun, ExtraArgs, Index, [Tup|Tail]) -> [setelement(Index, Tup, apply(Fun, [element(Index, Tup)|ExtraArgs]))| keymap_2(Fun, ExtraArgs, Index, Tail)]; keymap_2( _, _ , _, []) -> []. - + %% all_2(Predicate, List) %% any_2(Predicate, List) %% map_2(Function, List) @@ -1624,7 +1624,7 @@ flatlength_3([H|T], L) when list(H) -> flatlength_3([H|T], L) -> flatlength_3(T, L + 1); flatlength_3([], L) -> L. - + %% keymember_3(Key, Index, [Tuple]) %% keysearch_3(Key, Index, [Tuple]) %% keydelete_3(Key, Index, [Tuple]) @@ -1686,7 +1686,7 @@ keymap_3(Fun, ExtraArgs, Index, [Tup|Tail]) -> [setelement(Index, Tup, apply(Fun, [element(Index, Tup)|ExtraArgs]))| keymap_3(Fun, ExtraArgs, Index, Tail)]; keymap_3( _, _ , _, []) -> []. - + %% all_3(Predicate, List) %% any_3(Predicate, List) %% map_3(Function, List) diff --git a/lib/debugger/vsn.mk b/lib/debugger/vsn.mk index c3e3579e2c..a245e26a55 100644 --- a/lib/debugger/vsn.mk +++ b/lib/debugger/vsn.mk @@ -1 +1 @@ -DEBUGGER_VSN = 3.2.11 +DEBUGGER_VSN = 3.2.12 diff --git a/lib/dialyzer/test/options1_SUITE_data/src/compiler/beam_clean.erl b/lib/dialyzer/test/options1_SUITE_data/src/compiler/beam_clean.erl index 04225e9bd0..4fc4e89ce9 100644 --- a/lib/dialyzer/test/options1_SUITE_data/src/compiler/beam_clean.erl +++ b/lib/dialyzer/test/options1_SUITE_data/src/compiler/beam_clean.erl @@ -80,7 +80,7 @@ add_to_work_list(F, {Fs,Used}=Sets) -> false -> {[F|Fs],sets:add_element(F, Used)} end. - + %%% %%% Coalesce adjacent labels. Renumber all labels to eliminate gaps. %%% This cleanup will slightly reduce file size and slightly speed up loading. diff --git a/lib/dialyzer/test/options1_SUITE_data/src/compiler/beam_type.erl b/lib/dialyzer/test/options1_SUITE_data/src/compiler/beam_type.erl index d2ac3fcd99..f59cc897d6 100644 --- a/lib/dialyzer/test/options1_SUITE_data/src/compiler/beam_type.erl +++ b/lib/dialyzer/test/options1_SUITE_data/src/compiler/beam_type.erl @@ -456,7 +456,7 @@ are_live_regs_determinable([{'%live',_}|_]) -> true; are_live_regs_determinable([_|Is]) -> are_live_regs_determinable(Is); are_live_regs_determinable([]) -> false. - + %%% Routines for maintaining a type database. The type database %%% associates type information with registers. %%% diff --git a/lib/dialyzer/test/options1_SUITE_data/src/compiler/compile.erl b/lib/dialyzer/test/options1_SUITE_data/src/compiler/compile.erl index 2b6d14e300..9b56d384ab 100644 --- a/lib/dialyzer/test/options1_SUITE_data/src/compiler/compile.erl +++ b/lib/dialyzer/test/options1_SUITE_data/src/compiler/compile.erl @@ -990,7 +990,7 @@ listing(LFun, Ext, St) -> Es = [{Lfile,[{none,compile,write_error}]}], {error,St#compile{errors=St#compile.errors ++ Es}} end. - + options() -> help(standard_passes()). @@ -1022,7 +1022,7 @@ help([_|T]) -> help(_) -> ok. - + %% compile(AbsFileName, Outfilename, Options) %% Compile entry point for erl_compile. diff --git a/lib/dialyzer/test/options1_SUITE_data/src/compiler/core_scan.erl b/lib/dialyzer/test/options1_SUITE_data/src/compiler/core_scan.erl index 5ca3d6becd..2f9f6a2bcc 100644 --- a/lib/dialyzer/test/options1_SUITE_data/src/compiler/core_scan.erl +++ b/lib/dialyzer/test/options1_SUITE_data/src/compiler/core_scan.erl @@ -122,7 +122,7 @@ format_error(Other) -> io_lib:write(Other). string_thing($') -> "atom"; string_thing($") -> "string". - + %% Re-entrant pre-scanner. %% %% If the input list of characters is insufficient to build a term the @@ -240,7 +240,7 @@ pre_comment(eof, Sofar, Pos) -> pre_error(E, Epos, Pos) -> {error,{Epos,core_scan,E}, Pos}. - + %% scan(CharList, StartPos) %% This takes a list of characters and tries to tokenise them. %% diff --git a/lib/dialyzer/test/options1_SUITE_data/src/compiler/sys_pre_expand.erl b/lib/dialyzer/test/options1_SUITE_data/src/compiler/sys_pre_expand.erl index 41b7cb248d..590cc682c9 100644 --- a/lib/dialyzer/test/options1_SUITE_data/src/compiler/sys_pre_expand.erl +++ b/lib/dialyzer/test/options1_SUITE_data/src/compiler/sys_pre_expand.erl @@ -647,7 +647,7 @@ new_fun_name(#expand{func=F,arity=A,fcount=I}=St) -> ++ "-fun-" ++ integer_to_list(I) ++ "-", {list_to_atom(Name),St#expand{fcount=I+1}}. - + %% normalise_fields([RecDef]) -> [Field]. %% Normalise the field definitions to always have a default value. If %% none has been given then use 'undefined'. @@ -881,7 +881,7 @@ bin_expand_strings(Es) -> end, Es1, S); (E, Es1) -> [E|Es1] end, [], Es). - + %% new_var_name(State) -> {VarName,State}. new_var_name(St) -> diff --git a/lib/dialyzer/test/options1_SUITE_data/src/compiler/v3_core.erl b/lib/dialyzer/test/options1_SUITE_data/src/compiler/v3_core.erl index c96837ab5e..45a8bc4ad9 100644 --- a/lib/dialyzer/test/options1_SUITE_data/src/compiler/v3_core.erl +++ b/lib/dialyzer/test/options1_SUITE_data/src/compiler/v3_core.erl @@ -1127,7 +1127,7 @@ new_in_all([Le|Les]) -> foldl(fun (L, Ns) -> intersection((core_lib:get_anno(L))#a.ns, Ns) end, (core_lib:get_anno(Le))#a.ns, Les); new_in_all([]) -> []. - + %% The AfterVars are the variables which are used afterwards. We need %% this to work out which variables are actually exported and used %% from case/receive. In subblocks/clauses the AfterVars of the block diff --git a/lib/dialyzer/test/options1_SUITE_data/src/compiler/v3_kernel.erl b/lib/dialyzer/test/options1_SUITE_data/src/compiler/v3_kernel.erl index d7c3e1add9..ecba19b1d1 100644 --- a/lib/dialyzer/test/options1_SUITE_data/src/compiler/v3_kernel.erl +++ b/lib/dialyzer/test/options1_SUITE_data/src/compiler/v3_kernel.erl @@ -129,7 +129,7 @@ function(#c_def{anno=Af,name=#c_fname{id=F,arity=Arity},val=Body}, St0) -> %%B1 = B0, St3 = St2, %Null second pass {#k_fdef{anno=#k{us=[],ns=[],a=Af ++ Ab}, func=F,arity=Arity,vars=Kvs,body=B1},St3}. - + %% body(Cexpr, Sub, State) -> {Kexpr,[PreKepxr],State}. %% Do the main sequence of a body. A body ends in an atomic value or %% values. Must check if vector first so do expr. @@ -719,7 +719,7 @@ last([_|T]) -> last(T). first([_]) -> []; first([H|T]) -> [H|first(T)]. - + %% This code implements the algorithm for an optimizing compiler for %% pattern matching given "The Implementation of Functional %% Programming Languages" by Simon Peyton Jones. The code is much @@ -1143,7 +1143,7 @@ arg_val(Arg) -> #k_bin_end{} -> 0; #k_binary{} -> 0 end. - + %% ubody(Expr, Break, State) -> {Expr,[UsedVar],State}. %% Tag the body sequence with its used variables. These bodies %% either end with a #k_break{}, or with #k_return{} or an expression diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_cgi.erl b/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_cgi.erl index d3f67eb77a..8c91b6f430 100644 --- a/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_cgi.erl +++ b/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_cgi.erl @@ -338,7 +338,7 @@ exec_script(false,Info,Script,_AfterScript,_RequestURI) -> %% proxy(#mod{config_db = ConfigDb} = Info, Port) -> - Timeout = httpd_util:lookup(ConfigDb, cgi_timeout, ?DEFAULT_CGI_TIMEOUT), + Timeout = httpd_util:lookup(ConfigDb, script_timeout, ?DEFAULT_CGI_TIMEOUT), proxy(Info, Port, 0, undefined,[], Timeout). proxy(Info, Port, Size, StatusCode, AccResponse, Timeout) -> diff --git a/lib/dialyzer/test/small_SUITE_data/results/trec b/lib/dialyzer/test/small_SUITE_data/results/trec index 01ccc63761..b95df1e6ef 100644 --- a/lib/dialyzer/test/small_SUITE_data/results/trec +++ b/lib/dialyzer/test/small_SUITE_data/results/trec @@ -1,7 +1,7 @@ -trec.erl:26: Function test/0 has no local return -trec.erl:27: The call trec:mk_foo_loc(42,any()) will never return since it differs in the 1st argument from the success typing arguments: ('undefined',atom()) -trec.erl:29: Function mk_foo_loc/2 has no local return -trec.erl:30: Record construction violates the declared type for #foo{} since variable A cannot be of type atom() -trec.erl:36: Function mk_foo_exp/2 has no local return -trec.erl:37: Record construction violates the declared type for #foo{} since variable A cannot be of type atom() +trec.erl:28: Function test/0 has no local return +trec.erl:29: The call trec:mk_foo_loc(42,any()) will never return since it differs in the 1st argument from the success typing arguments: ('undefined',atom()) +trec.erl:31: Function mk_foo_loc/2 has no local return +trec.erl:32: Record construction violates the declared type for #foo{} since variable A cannot be of type atom() +trec.erl:38: Function mk_foo_exp/2 has no local return +trec.erl:39: Record construction violates the declared type for #foo{} since variable A cannot be of type atom() diff --git a/lib/dialyzer/test/small_SUITE_data/src/appmon_place.erl b/lib/dialyzer/test/small_SUITE_data/src/appmon_place.erl index 60ffbe818f..ddb97796fb 100644 --- a/lib/dialyzer/test/small_SUITE_data/src/appmon_place.erl +++ b/lib/dialyzer/test/small_SUITE_data/src/appmon_place.erl @@ -1,6 +1,6 @@ %%--------------------------------------------------------------------- %% This is added as a test because it was giving a false positive -%% (function move/4 will nevr be called) due to the strange use of +%% (function move/4 will never be called) due to the strange use of %% self-recursive fun construction in placex/3. %% %% The analysis was getting confused that the foldl call will never diff --git a/lib/dialyzer/test/small_SUITE_data/src/contract3.erl b/lib/dialyzer/test/small_SUITE_data/src/contract3.erl index 5b0bee9694..a6ce91882e 100644 --- a/lib/dialyzer/test/small_SUITE_data/src/contract3.erl +++ b/lib/dialyzer/test/small_SUITE_data/src/contract3.erl @@ -18,16 +18,23 @@ t(X, Y, Z) -> (atom()|list()) -> atom(). t1(X) -> - foo:bar(X). + f(X). -spec t2(atom(), integer()) -> integer(); (atom(), list()) -> atom(). t2(X, Y) -> - foo:bar(X, Y). + g(X, Y). -spec t3(atom(), integer(), list()) -> integer(); (X, integer(), list()) -> X. t3(X, Y, Z) -> X. + +%% dummy functions below + +f(X) -> X. + +g(X, Y) when is_atom(X), is_integer(Y) -> Y; +g(X, Y) when is_atom(X), is_list(Y) -> X. diff --git a/lib/dialyzer/test/small_SUITE_data/src/empty_list_infimum.erl b/lib/dialyzer/test/small_SUITE_data/src/empty_list_infimum.erl index b58fa732cb..3acc5ca065 100644 --- a/lib/dialyzer/test/small_SUITE_data/src/empty_list_infimum.erl +++ b/lib/dialyzer/test/small_SUITE_data/src/empty_list_infimum.erl @@ -1,6 +1,6 @@ %% -%% The Original Code is RabbitMQ. -%% +%% This is stripped down code from RabbitMQ. It is used to report an +%% invalid type specification for function list_vhost_permissions/1. %% The Initial Developer of the Original Code is VMware, Inc. %% @@ -38,7 +38,7 @@ vhost_perms_info_keys() -> -spec list_vhost_permissions(vhost()) -> infos(). list_vhost_permissions(VHostPath) -> - list_permissions(vhost_perms_info_keys(), rabbit_foo:some_list()). + list_permissions(vhost_perms_info_keys(), some_mod:some_function()). filter_props(Keys, Props) -> [T || T = {K, _} <- Props, lists:member(K, Keys)]. diff --git a/lib/dialyzer/test/small_SUITE_data/src/gencall.erl b/lib/dialyzer/test/small_SUITE_data/src/gencall.erl index d2875c9df1..762be55007 100644 --- a/lib/dialyzer/test/small_SUITE_data/src/gencall.erl +++ b/lib/dialyzer/test/small_SUITE_data/src/gencall.erl @@ -7,6 +7,6 @@ f() -> gen_server:call(1,2,3), ets:lookup(1,2,3), - gencall2:foo(), + some_mod:some_function(), gencall:foo(), gen_server:handle_cast(1,2). diff --git a/lib/dialyzer/test/small_SUITE_data/src/maybe_improper.erl b/lib/dialyzer/test/small_SUITE_data/src/maybe_improper.erl index 1743d81493..6d2a35b7c8 100644 --- a/lib/dialyzer/test/small_SUITE_data/src/maybe_improper.erl +++ b/lib/dialyzer/test/small_SUITE_data/src/maybe_improper.erl @@ -1,7 +1,18 @@ +%%%======================================================================== +%%% Tests handling of maybe improper lists +%%%======================================================================== -module(maybe_improper). --export([s/1]). +-export([s/1, t/0]). -spec s(maybe_improper_list(X,Y)) -> {[X], maybe_improper_list(X,Y)}. -s(A) -> - lists:split(2,A). +s(L) -> + lists:split(2, L). + +%% Having a remote type in the 'tail' of the list crashed dialyzer. +%% The problem was fixed for R16B03. +-type t_mil() :: maybe_improper_list(integer(), orddict:orddict()). + +-spec t() -> t_mil(). +t() -> + [42 | []]. diff --git a/lib/dialyzer/test/small_SUITE_data/src/overloaded1.erl b/lib/dialyzer/test/small_SUITE_data/src/overloaded1.erl index 0af4f7446f..074a93e2fe 100644 --- a/lib/dialyzer/test/small_SUITE_data/src/overloaded1.erl +++ b/lib/dialyzer/test/small_SUITE_data/src/overloaded1.erl @@ -1,5 +1,5 @@ %%----------------------------------------------------------------------------- -%% Test that tests overloaded contratcs. +%% Test that tests overloaded contracts. %% In December 2008 it works as far as intersection types are concerned (test1) %% However, it does NOT work as far as type variables are concerned (test2) %%----------------------------------------------------------------------------- @@ -16,13 +16,13 @@ test2() -> -type mod() :: atom(). --spec foo(ATM, list()) -> {'ok', ATM} | {'error', _} when is_subtype(ATM, mod()) - ; (MFA, list()) -> {'ok', MFA} | {'error', _} when is_subtype(MFA, mfa()). +-spec foo(ATM, list()) -> {'ok', ATM} | {'error', _} when ATM :: mod() + ; (MFA, list()) -> {'ok', MFA} | {'error', _} when MFA :: mfa(). foo(F, _) when is_atom(F) -> case atom_to_list(F) of - [42|_] -> {ok, F}; - _Other -> {error, mod:bar(F)} + [42|_] -> {ok, F}; + _Other -> {error, some_mod:some_function()} end; foo({M,F,A}, _) -> case A =:= 0 of diff --git a/lib/dialyzer/test/small_SUITE_data/src/trec.erl b/lib/dialyzer/test/small_SUITE_data/src/trec.erl index ba50c3b401..06706162c1 100644 --- a/lib/dialyzer/test/small_SUITE_data/src/trec.erl +++ b/lib/dialyzer/test/small_SUITE_data/src/trec.erl @@ -18,20 +18,22 @@ %% ('undefined',atom()) %% 3. Function mk_foo_loc/2 has no local return %% -%% Arguably, the second warning is not what most users have in mind -%% when they wrote the type declarations in the 'foo' record, so no -%% doubt they'll find it confusing. But note that it is also inconsistent! -%% How come there is a success typing for a function that has no local return? +%% Arguably, the second warning is not what most users have in mind when +%% they wrote the type declarations in the 'foo' record, so no doubt +%% they'll find it confusing. But note that it is also quite confusing! +%% Many users may be wondering: How come there is a success typing for a +%% function that has no local return? Running typer on this module +%% reveals a success typing for this function that is interesting indeed. %% test() -> - mk_foo_loc(42, bar:f()). + mk_foo_loc(42, some_mod:some_function()). mk_foo_loc(A, B) -> #foo{a = A, b = [A,B]}. %% -%% For this function we currently get "has no local return" but we get -%% no reason; I want us to get a reason. +%% For this function we used to get a "has no local return" warning +%% but we got no reason. This has now been fixed. %% mk_foo_exp(A, B) when is_integer(A) -> #foo{a = A, b = [A,B]}. diff --git a/lib/diameter/doc/src/notes.xml b/lib/diameter/doc/src/notes.xml index 6e79a9589a..274a3f594c 100644 --- a/lib/diameter/doc/src/notes.xml +++ b/lib/diameter/doc/src/notes.xml @@ -42,6 +42,52 @@ first.</p> <!-- ===================================================================== --> +<section><title>diameter 1.4.3</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Fix UTF8String encode.</p> + <p> + Encode now accepts any nested list of codepoints and + binaries. A list containing a binary was previously + misinterpreted and the documentation was incomplete.</p> + <p> + Own Id: OTP-11172</p> + </item> + <item> + <p> + Ensure DWR isn't sent immediately after DWA.</p> + <p> + This was possible if the timing was unfortunate. An + incoming DWR now properly resets the watchdog timer.</p> + <p> + Own Id: OTP-11184</p> + </item> + <item> + <p> + Fix faulty encode of Failed-AVP</p> + <p> + Reception of a CER, DWR or DPR that has decode failures + caused encode of the corresponding answer message to + fail.</p> + <p> + Own Id: OTP-11293</p> + </item> + <item> + <p> + Fix broken service_opt() spawn_opt.</p> + <p> + The option was ignored.</p> + <p> + Own Id: OTP-11299</p> + </item> + </list> + </section> + +</section> + <section><title>diameter 1.4.2</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/diameter/src/base/diameter_config.erl b/lib/diameter/src/base/diameter_config.erl index fc5c284bf2..34b40c3a29 100644 --- a/lib/diameter/src/base/diameter_config.erl +++ b/lib/diameter/src/base/diameter_config.erl @@ -651,8 +651,9 @@ make_opts(Opts, Defs) -> [{K, opt(K,V)} || {K,V} <- Known]. -opt(spawn_opt, L) -> - is_list(L); +opt(spawn_opt, L) + when is_list(L) -> + L; opt(K, false = B) when K /= sequence -> diff --git a/lib/diameter/src/base/diameter_peer_fsm.erl b/lib/diameter/src/base/diameter_peer_fsm.erl index 2b99ecc59c..282276827f 100644 --- a/lib/diameter/src/base/diameter_peer_fsm.erl +++ b/lib/diameter/src/base/diameter_peer_fsm.erl @@ -741,7 +741,7 @@ rejected(N, T, S) -> rejected({N, []}, T, S). failed_avp(RC, [{RC, Avp} | _]) -> - [{'Failed-AVP', [{'AVP', [Avp]}]}]; + [{'Failed-AVP', [[{'AVP', [Avp]}]]}]; failed_avp(RC, [_ | Es]) -> failed_avp(RC, Es); failed_avp(_, [] = No) -> diff --git a/lib/diameter/src/base/diameter_service.erl b/lib/diameter/src/base/diameter_service.erl index 9dd8aafc61..47e03cd0a0 100644 --- a/lib/diameter/src/base/diameter_service.erl +++ b/lib/diameter/src/base/diameter_service.erl @@ -673,7 +673,8 @@ service_options(Opts) -> {use_shared_peers, get_value(use_shared_peers, Opts)}, {restrict_connections, proplists:get_value(restrict_connections, Opts, - ?RESTRICT)}]. + ?RESTRICT)}, + {spawn_opt, proplists:get_value(spawn_opt, Opts, [])}]. %% The order of options is significant since we match against the list. mref(false = No) -> diff --git a/lib/diameter/src/diameter.appup.src b/lib/diameter/src/diameter.appup.src index 62ace16faa..c6828e6705 100644 --- a/lib/diameter/src/diameter.appup.src +++ b/lib/diameter/src/diameter.appup.src @@ -29,38 +29,13 @@ {"1.3", [{restart_application, diameter}]}, %% R15B03 {"1.3.1", [{restart_application, diameter}]}, {"1.4", [{restart_application, diameter}]}, %% R16A - {"1.4.1", [{load_module, diameter_reg}, %% R16B - {load_module, diameter_stats}, - {load_module, diameter_traffic}, - {load_module, diameter_service}, + {"1.4.1", [{restart_application, diameter}]}, %% R16B + {"1.4.1.1", [{restart_application, diameter}]}, + {"1.4.2", [{load_module, diameter_types}, %% R16B01 {load_module, diameter_config}, - {load_module, diameter_peer}, + {load_module, diameter_service}, {load_module, diameter_peer_fsm}, - {load_module, diameter_watchdog}, - {load_module, diameter_capx}, - {load_module, diameter_codec}, - {load_module, diameter_gen_base_rfc3588}, - {load_module, diameter_gen_base_accounting}, - {load_module, diameter_gen_base_rfc6733}, - {load_module, diameter_gen_base_acct6733}, - {load_module, diameter_tcp}, - {load_module, diameter_lib}, - {load_module, diameter}]}, - {"1.4.1.1", [{load_module, diameter_traffic}, - {load_module, diameter_service}, - {load_module, diameter_config}, - {load_module, diameter_peer}, - {load_module, diameter_peer_fsm}, - {load_module, diameter_watchdog}, - {load_module, diameter_capx}, - {load_module, diameter_codec}, - {load_module, diameter_gen_base_rfc3588}, - {load_module, diameter_gen_base_accounting}, - {load_module, diameter_gen_base_rfc6733}, - {load_module, diameter_gen_base_acct6733}, - {load_module, diameter_tcp}, - {load_module, diameter_lib}, - {load_module, diameter}]} + {load_module, diameter_watchdog}]} ], [ {"0.9", [{restart_application, diameter}]}, @@ -73,6 +48,7 @@ {"1.3.1", [{restart_application, diameter}]}, {"1.4", [{restart_application, diameter}]}, {"1.4.1", [{restart_application, diameter}]}, - {"1.4.1.1", [{restart_application, diameter}]} + {"1.4.1.1", [{restart_application, diameter}]}, + {"1.4.2", [{restart_application, diameter}]} ] }. diff --git a/lib/diameter/vsn.mk b/lib/diameter/vsn.mk index f7462c3916..e003fe76b9 100644 --- a/lib/diameter/vsn.mk +++ b/lib/diameter/vsn.mk @@ -18,5 +18,5 @@ # %CopyrightEnd% APPLICATION = diameter -DIAMETER_VSN = 1.4.2 +DIAMETER_VSN = 1.4.3 APP_VSN = $(APPLICATION)-$(DIAMETER_VSN)$(PRE_VSN) diff --git a/lib/edoc/doc/src/notes.xml b/lib/edoc/doc/src/notes.xml index d2ec82efc8..394e7af09c 100644 --- a/lib/edoc/doc/src/notes.xml +++ b/lib/edoc/doc/src/notes.xml @@ -31,6 +31,23 @@ <p>This document describes the changes made to the EDoc application.</p> +<section><title>Edoc 0.7.12.1</title> + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + The encoding of the <c>notes.xml</c> file has been + changed from latin1 to utf-8 to avoid future merge + problems.</p> + <p> + Own Id: OTP-11310</p> + </item> + </list> + </section> + +</section> + <section><title>Edoc 0.7.12</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/edoc/vsn.mk b/lib/edoc/vsn.mk index af2aa2203f..2fcc97e406 100644 --- a/lib/edoc/vsn.mk +++ b/lib/edoc/vsn.mk @@ -1 +1 @@ -EDOC_VSN = 0.7.12 +EDOC_VSN = 0.7.12.1 diff --git a/lib/eldap/src/eldap.erl b/lib/eldap/src/eldap.erl index d11f904996..8ebb88e35b 100644 --- a/lib/eldap/src/eldap.erl +++ b/lib/eldap/src/eldap.erl @@ -42,8 +42,8 @@ log, % User provided log function timeout = infinity, % Request timeout anon_auth = false, % Allow anonymous authentication - use_tls = false, % LDAP/LDAPS - tls_opts = [] % ssl:ssloptsion() + use_tls = false, % LDAP/LDAPS + tls_opts = [] % ssl:ssloption() }). %%% For debug purposes @@ -389,8 +389,7 @@ try_connect([],_) -> do_connect(Host, Data, Opts) when Data#eldap.use_tls == false -> gen_tcp:connect(Host, Data#eldap.port, Opts, Data#eldap.timeout); do_connect(Host, Data, Opts) when Data#eldap.use_tls == true -> - SslOpts = [{verify,0} | Opts ++ Data#eldap.tls_opts], - ssl:connect(Host, Data#eldap.port, SslOpts). + ssl:connect(Host, Data#eldap.port, Opts ++ Data#eldap.tls_opts). loop(Cpid, Data) -> receive diff --git a/lib/erl_docgen/doc/src/notes.xml b/lib/erl_docgen/doc/src/notes.xml index 2ae5f93165..24d12b2bb7 100644 --- a/lib/erl_docgen/doc/src/notes.xml +++ b/lib/erl_docgen/doc/src/notes.xml @@ -30,7 +30,24 @@ </header> <p>This document describes the changes made to the <em>erl_docgen</em> application.</p> - <section><title>Erl_Docgen 0.3.4</title> + <section><title>Erl_Docgen 0.3.4.1</title> + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + The encoding of the <c>notes.xml</c> file has been + changed from latin1 to utf-8 to avoid future merge + problems.</p> + <p> + Own Id: OTP-11310</p> + </item> + </list> + </section> + +</section> + +<section><title>Erl_Docgen 0.3.4</title> <section><title>Fixed Bugs and Malfunctions</title> <list> diff --git a/lib/erl_docgen/priv/dtd/common.dtd b/lib/erl_docgen/priv/dtd/common.dtd index fdc02c55a1..f999ef8ea4 100644 --- a/lib/erl_docgen/priv/dtd/common.dtd +++ b/lib/erl_docgen/priv/dtd/common.dtd @@ -67,7 +67,7 @@ <!-- References --> -<!ELEMENT seealso (#PCDATA) > +<!ELEMENT seealso (#PCDATA|c|em)* > <!ATTLIST seealso marker CDATA #REQUIRED > <!ELEMENT url (#PCDATA) > <!ATTLIST url href CDATA #REQUIRED > diff --git a/lib/erl_docgen/vsn.mk b/lib/erl_docgen/vsn.mk index a2262198dc..cda8671cfd 100644 --- a/lib/erl_docgen/vsn.mk +++ b/lib/erl_docgen/vsn.mk @@ -1 +1 @@ -ERL_DOCGEN_VSN = 0.3.4 +ERL_DOCGEN_VSN = 0.3.4.1 diff --git a/lib/erl_interface/doc/src/notes.xml b/lib/erl_interface/doc/src/notes.xml index 930b24c26a..f05456bbbd 100644 --- a/lib/erl_interface/doc/src/notes.xml +++ b/lib/erl_interface/doc/src/notes.xml @@ -30,6 +30,38 @@ </header> <p>This document describes the changes made to the Erl_interface application.</p> +<section><title>Erl_Interface 3.7.14</title> + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Introduced functionality for inspection of system and + build configuration.</p> + <p> + Own Id: OTP-11196</p> + </item> + <item> + <p> + Header and library files from ic and erl_interface are + now installed into usr/{include,lib}. Note that these + directories are unversioned, so the latest installed + version will be the one in the directory.</p> + <p> + Own Id: OTP-11284</p> + </item> + <item> + <p> + Fix location of true binary under Mac OSX. Thanks to + Simon Cornish.</p> + <p> + Own Id: OTP-11289</p> + </item> + </list> + </section> + +</section> + <section><title>Erl_Interface 3.7.13</title> <section><title>Improvements and New Features</title> diff --git a/lib/erl_interface/src/Makefile.in b/lib/erl_interface/src/Makefile.in index ebacc1cee0..e36b39c1fb 100644 --- a/lib/erl_interface/src/Makefile.in +++ b/lib/erl_interface/src/Makefile.in @@ -866,8 +866,12 @@ release: opt $(INSTALL_DIR) "$(RELSYSDIR)/src/misc" $(INSTALL_DIR) "$(RELSYSDIR)/src/prog" $(INSTALL_DIR) "$(RELSYSDIR)/src/registry" + $(INSTALL_DIR) "$(RELEASE_PATH)/usr/include" + $(INSTALL_DIR) "$(RELEASE_PATH)/usr/lib" $(INSTALL_DATA) $(HEADERS) "$(RELSYSDIR)/include" + $(INSTALL_DATA) $(HEADERS) "$(RELEASE_PATH)/usr/include" $(INSTALL_DATA) $(OBJ_TARGETS) "$(RELSYSDIR)/lib" + $(INSTALL_DATA) $(OBJ_TARGETS) "$(RELEASE_PATH)/usr/lib" ifneq ($(EXE_TARGETS),) $(INSTALL_PROGRAM) $(EXE_TARGETS) "$(RELSYSDIR)/bin" endif diff --git a/lib/erl_interface/src/legacy/erl_eterm.c b/lib/erl_interface/src/legacy/erl_eterm.c index 7ca4f430de..636d26b24b 100644 --- a/lib/erl_interface/src/legacy/erl_eterm.c +++ b/lib/erl_interface/src/legacy/erl_eterm.c @@ -686,7 +686,7 @@ int erl_length(const ETERM *ep) return n; } - + /*********************************************************************** * I o l i s t f u n c t i o n s * diff --git a/lib/erl_interface/test/all_SUITE_data/ei_runner.c b/lib/erl_interface/test/all_SUITE_data/ei_runner.c index 205f911e38..cdf32b48c4 100644 --- a/lib/erl_interface/test/all_SUITE_data/ei_runner.c +++ b/lib/erl_interface/test/all_SUITE_data/ei_runner.c @@ -77,7 +77,7 @@ run_tests(char* argv0, TestCase test_cases[], unsigned number) } } - + /*********************************************************************** * * R e a d i n g p a c k e t s @@ -182,7 +182,7 @@ char *read_packet(int *len) return io_buf; } - + /*********************************************************************** * S e n d i n g r e p l i e s * diff --git a/lib/erl_interface/test/all_SUITE_data/runner.c b/lib/erl_interface/test/all_SUITE_data/runner.c index a474c17722..038d651275 100644 --- a/lib/erl_interface/test/all_SUITE_data/runner.c +++ b/lib/erl_interface/test/all_SUITE_data/runner.c @@ -78,7 +78,7 @@ run_tests(char* argv0, TestCase test_cases[], unsigned number) } } - + /*********************************************************************** * * R e a d i n g p a c k e t s @@ -188,7 +188,7 @@ char *read_packet(int *len) return io_buf; } - + /*********************************************************************** * S e n d i n g r e p l i e s * diff --git a/lib/erl_interface/test/ei_accept_SUITE.erl b/lib/erl_interface/test/ei_accept_SUITE.erl index 48469e68dc..642809ea7a 100644 --- a/lib/erl_interface/test/ei_accept_SUITE.erl +++ b/lib/erl_interface/test/ei_accept_SUITE.erl @@ -155,7 +155,7 @@ start_einode(Einode, N, Host, Port) -> ok. - + %%% Interface functions for ei (erl_interface) functions. ei_connect_init(P, Num, Cookie, Creation) -> diff --git a/lib/erl_interface/test/ei_decode_encode_SUITE.erl b/lib/erl_interface/test/ei_decode_encode_SUITE.erl index 2271278291..c7830f58f2 100644 --- a/lib/erl_interface/test/ei_decode_encode_SUITE.erl +++ b/lib/erl_interface/test/ei_decode_encode_SUITE.erl @@ -68,6 +68,8 @@ test_ei_decode_encode(Config) when is_list(Config) -> Port = case os:type() of {win32,_} -> open_port({spawn,"sort"},[]); + {unix, darwin} -> + open_port({spawn,"/usr/bin/true"},[]); _ -> open_port({spawn,"/bin/true"},[]) end, diff --git a/lib/erl_interface/test/erl_connect_SUITE.erl b/lib/erl_interface/test/erl_connect_SUITE.erl index bd54013402..c8becc760c 100644 --- a/lib/erl_interface/test/erl_connect_SUITE.erl +++ b/lib/erl_interface/test/erl_connect_SUITE.erl @@ -106,7 +106,7 @@ erl_reg_send(Config) when is_list(Config) -> ?line runner:recv_eot(P), ok. - + %%% Interface functions for erl_interface functions. erl_connect_init(P, Num, Cookie, Creation) -> diff --git a/lib/erl_interface/test/erl_eterm_SUITE.erl b/lib/erl_interface/test/erl_eterm_SUITE.erl index 10a27e48e3..100e9b6f68 100644 --- a/lib/erl_interface/test/erl_eterm_SUITE.erl +++ b/lib/erl_interface/test/erl_eterm_SUITE.erl @@ -108,7 +108,7 @@ end_per_group(_GroupName, Config) -> Config. - + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% %%% 1. B a s i c t e s t s @@ -196,7 +196,7 @@ t_erl_free_compound(Config) when is_list(Config) -> ?line runner:test(?t_erl_free_compound), ok. - + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% %%% 2. C o n s t r u c t i n g t e r m s @@ -521,7 +521,7 @@ t_erl_cons(Config) when is_list(Config) -> - + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% %%% 3. E x t r a c t i n g & i n f o f u n c t i o n s @@ -669,7 +669,7 @@ t_erl_element(Config) when is_list(Config) -> ok. - + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% %%% 4. I / O l i s t f u n c t i o n s @@ -894,7 +894,7 @@ iolist_to_string(Port, Term) -> 'NULL' -> 'NULL' end. - + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% %%% 5. M i s c e l l a n o u s T e s t s diff --git a/lib/erl_interface/test/erl_eterm_SUITE_data/eterm_test.c b/lib/erl_interface/test/erl_eterm_SUITE_data/eterm_test.c index 80d7f69520..94959187b9 100644 --- a/lib/erl_interface/test/erl_eterm_SUITE_data/eterm_test.c +++ b/lib/erl_interface/test/erl_eterm_SUITE_data/eterm_test.c @@ -269,7 +269,7 @@ TESTCASE(t_erl_free_compound) report(1); } - + /*********************************************************************** * * 2. C o n s t r u c t i n g t e r m s @@ -1047,7 +1047,7 @@ TESTCASE(t_erl_cons) - + /*********************************************************************** * * 3. E x t r a c t i n g & i n f o f u n c t i o n s @@ -1296,7 +1296,7 @@ TESTCASE(extractor_macros) } - + /*********************************************************************** * * 4. I / O l i s t f u n c t i o n s @@ -1393,7 +1393,7 @@ TESTCASE(t_erl_iolist_to_string) } } - + /*********************************************************************** * * 5. M i s c e l l a n o u s T e s t s diff --git a/lib/erl_interface/vsn.mk b/lib/erl_interface/vsn.mk index 6f08d380ca..5cde054a49 100644 --- a/lib/erl_interface/vsn.mk +++ b/lib/erl_interface/vsn.mk @@ -1 +1 @@ -EI_VSN = 3.7.13 +EI_VSN = 3.7.14 diff --git a/lib/et/doc/src/notes.xml b/lib/et/doc/src/notes.xml index 7b9d3fcf81..815dfada5e 100644 --- a/lib/et/doc/src/notes.xml +++ b/lib/et/doc/src/notes.xml @@ -36,6 +36,23 @@ one section in this document. The title of each section is the version number of <c>Event Tracer (ET)</c>.</p> +<section><title>ET 1.4.4.5</title> + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + The encoding of the <c>notes.xml</c> file has been + changed from latin1 to utf-8 to avoid future merge + problems.</p> + <p> + Own Id: OTP-11310</p> + </item> + </list> + </section> + +</section> + <section><title>ET 1.4.4.4</title> <section><title>Improvements and New Features</title> @@ -43,7 +60,7 @@ <item> <p> Use erlang:demonitor(Ref, [flush]) where applicable. - Thanks to Lo�c Hoguin.</p> + Thanks to Loïc Hoguin.</p> <p> Own Id: OTP-11039</p> </item> diff --git a/lib/et/vsn.mk b/lib/et/vsn.mk index 40cdc2b298..282991aa49 100644 --- a/lib/et/vsn.mk +++ b/lib/et/vsn.mk @@ -1 +1 @@ -ET_VSN = 1.4.4.4 +ET_VSN = 1.4.4.5 diff --git a/lib/eunit/doc/src/notes.xml b/lib/eunit/doc/src/notes.xml index d5675574fc..21f759c4b1 100644 --- a/lib/eunit/doc/src/notes.xml +++ b/lib/eunit/doc/src/notes.xml @@ -32,6 +32,22 @@ </header> <p>This document describes the changes made to the EUnit application.</p> +<section><title>Eunit 2.2.5</title> + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Wrap eunit macros into begin ... end blocks. Thanks to + Anthony Ramine.</p> + <p> + Own Id: OTP-11217</p> + </item> + </list> + </section> + +</section> + <section><title>Eunit 2.2.4</title> <section><title>Improvements and New Features</title> diff --git a/lib/eunit/src/eunit_proc.erl b/lib/eunit/src/eunit_proc.erl index ec7d93fd48..03d1a18321 100644 --- a/lib/eunit/src/eunit_proc.erl +++ b/lib/eunit/src/eunit_proc.erl @@ -643,11 +643,11 @@ io_request({get_until, _Prompt, _M, _F, _As}, Buf) -> io_request({setopts, _Opts}, Buf) -> {ok, Buf}; io_request(getopts, Buf) -> - {error, {error, enotsup}, Buf}; + {{error, enotsup}, Buf}; io_request({get_geometry,columns}, Buf) -> - {error, {error, enotsup}, Buf}; + {{error, enotsup}, Buf}; io_request({get_geometry,rows}, Buf) -> - {error, {error, enotsup}, Buf}; + {{error, enotsup}, Buf}; io_request({requests, Reqs}, Buf) -> io_requests(Reqs, {ok, Buf}); io_request(_, Buf) -> @@ -657,3 +657,10 @@ io_requests([R | Rs], {ok, Buf}) -> io_requests(Rs, io_request(R, Buf)); io_requests(_, Result) -> Result. + +-ifdef(TEST). +io_error_test_() -> + [?_assertMatch({error, enotsup}, io:getopts()), + ?_assertMatch({error, enotsup}, io:columns()), + ?_assertMatch({error, enotsup}, io:rows())]. +-endif. diff --git a/lib/eunit/vsn.mk b/lib/eunit/vsn.mk index 798196f8cf..be06c81559 100644 --- a/lib/eunit/vsn.mk +++ b/lib/eunit/vsn.mk @@ -1 +1 @@ -EUNIT_VSN = 2.2.4 +EUNIT_VSN = 2.2.5 diff --git a/lib/hipe/cerl/erl_types.erl b/lib/hipe/cerl/erl_types.erl index d1243b2325..d7d8a878c5 100644 --- a/lib/hipe/cerl/erl_types.erl +++ b/lib/hipe/cerl/erl_types.erl @@ -671,8 +671,9 @@ t_solve_remote(?function(Domain, Range), ET, R, C) -> {RT2, RR2} = t_solve_remote(Range, ET, R, C), {?function(RT1, RT2), RR1 ++ RR2}; t_solve_remote(?list(Types, Term, Size), ET, R, C) -> - {RT, RR} = t_solve_remote(Types, ET, R, C), - {?list(RT, Term, Size), RR}; + {RT1, RR1} = t_solve_remote(Types, ET, R, C), + {RT2, RR2} = t_solve_remote(Term, ET, R, C), + {?list(RT1, RT2, Size), RR1 ++ RR2}; t_solve_remote(?product(Types), ET, R, C) -> {RL, RR} = list_solve_remote(Types, ET, R, C), {?product(RL), RR}; @@ -1349,8 +1350,8 @@ t_maybe_improper_list() -> t_maybe_improper_list(_Content, ?unit) -> ?none; t_maybe_improper_list(?unit, _Termination) -> ?none; t_maybe_improper_list(Content, Termination) -> - %% Safety check - true = t_is_subtype(t_nil(), Termination), + %% Safety check: would be nice to have but does not work with remote types + %% true = t_is_subtype(t_nil(), Termination), ?list(Content, Termination, ?unknown_qual). -spec t_is_maybe_improper_list(erl_type()) -> boolean(). @@ -1365,8 +1366,8 @@ t_is_maybe_improper_list(_) -> false. %% t_improper_list(?unit, _Termination) -> ?none; %% t_improper_list(_Content, ?unit) -> ?none; %% t_improper_list(Content, Termination) -> -%% %% Safety check -%% false = t_is_subtype(t_nil(), Termination), +%% %% Safety check: would be nice to have but does not work with remote types +%% %% false = t_is_subtype(t_nil(), Termination), %% ?list(Content, Termination, ?any). -spec lift_list_to_pos_empty(erl_type()) -> erl_type(). diff --git a/lib/hipe/doc/src/notes.xml b/lib/hipe/doc/src/notes.xml index 52c5e068e1..2f8f1782cc 100644 --- a/lib/hipe/doc/src/notes.xml +++ b/lib/hipe/doc/src/notes.xml @@ -30,6 +30,23 @@ </header> <p>This document describes the changes made to HiPE.</p> +<section><title>Hipe 3.10.2.1</title> + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + The encoding of the <c>notes.xml</c> file has been + changed from latin1 to utf-8 to avoid future merge + problems.</p> + <p> + Own Id: OTP-11310</p> + </item> + </list> + </section> + +</section> + <section><title>Hipe 3.10.2</title> <section><title>Improvements and New Features</title> @@ -37,7 +54,7 @@ <item> <p> Fix the title of hipe_app documentation page. Thanks to - Lo�c Hoguin.</p> + Loïc Hoguin.</p> <p> Own Id: OTP-10904</p> </item> diff --git a/lib/hipe/vsn.mk b/lib/hipe/vsn.mk index deb16b02fd..d9ed0b299f 100644 --- a/lib/hipe/vsn.mk +++ b/lib/hipe/vsn.mk @@ -1 +1 @@ -HIPE_VSN = 3.10.2 +HIPE_VSN = 3.10.2.1 diff --git a/lib/ic/c_src/Makefile.in b/lib/ic/c_src/Makefile.in index 856823b1b3..ed860ab73b 100644 --- a/lib/ic/c_src/Makefile.in +++ b/lib/ic/c_src/Makefile.in @@ -132,10 +132,8 @@ docs: _create_dirs := $(shell mkdir -p $(OBJDIR) $(LIBDIR)) $(LIBRARY): $(OBJ_FILES) - $(ar_verbose) - -$(AR) $(AR_OUT) $@ $(OBJ_FILES) - $(ranlib_verbose) - -$(RANLIB) $@ + -$(V_AR) $(AR_OUT) $@ $(OBJ_FILES) + -$(V_RANLIB) $@ $(OBJDIR)/%.o: %.c $(V_CC) $(CC_FLAGS) -c -o $@ $(ALL_CFLAGS) $< @@ -149,9 +147,13 @@ release_spec: opt $(INSTALL_DIR) "$(RELSYSDIR)/c_src" $(INSTALL_DIR) "$(RELSYSDIR)/include" $(INSTALL_DIR) "$(RELSYSDIR)/priv/lib" + $(INSTALL_DIR) "$(RELEASE_PATH)/usr/include" + $(INSTALL_DIR) "$(RELEASE_PATH)/usr/lib" $(INSTALL_DATA) ic.c ic_tmo.c "$(RELSYSDIR)/c_src" $(INSTALL_DATA) $(IDL_FILES) $(H_FILES) "$(RELSYSDIR)/include" $(INSTALL_DATA) $(LIBRARY) "$(RELSYSDIR)/priv/lib" + $(INSTALL_DATA) $(IDL_FILES) $(H_FILES) "$(RELEASE_PATH)/usr/include" + $(INSTALL_DATA) $(LIBRARY) "$(RELEASE_PATH)/usr/lib" release_docs_spec: diff --git a/lib/ic/doc/src/notes.xml b/lib/ic/doc/src/notes.xml index 7169a58543..112c0aff09 100644 --- a/lib/ic/doc/src/notes.xml +++ b/lib/ic/doc/src/notes.xml @@ -30,7 +30,25 @@ <file>notes.xml</file> </header> - <section><title>IC 4.3.2</title> + <section><title>IC 4.3.3</title> + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Header and library files from ic and erl_interface are + now installed into usr/{include,lib}. Note that these + directories are unversioned, so the latest installed + version will be the one in the directory.</p> + <p> + Own Id: OTP-11284</p> + </item> + </list> + </section> + +</section> + +<section><title>IC 4.3.2</title> <section><title>Fixed Bugs and Malfunctions</title> <list> diff --git a/lib/ic/vsn.mk b/lib/ic/vsn.mk index 53b81ad731..d1969ef3d8 100644 --- a/lib/ic/vsn.mk +++ b/lib/ic/vsn.mk @@ -1 +1 @@ -IC_VSN = 4.3.2 +IC_VSN = 4.3.3 diff --git a/lib/inets/doc/src/httpc.xml b/lib/inets/doc/src/httpc.xml index 39860a4cc2..357a62381d 100644 --- a/lib/inets/doc/src/httpc.xml +++ b/lib/inets/doc/src/httpc.xml @@ -440,7 +440,10 @@ apply(Module, Function, [ReplyInfo | Args]) <v>Profile = profile() | pid() (when started <c>stand_alone</c>)</v> </type> <desc> - <p>Cancels an asynchronous HTTP-request. </p> + <p>Cancels an asynchronous HTTP-request. Note this does not guarantee + that the request response will not be delivered, as it is asynchronous the + the request may already have been completed when the cancellation arrives. + </p> <marker id="set_options"></marker> </desc> diff --git a/lib/inets/doc/src/notes.xml b/lib/inets/doc/src/notes.xml index 42183b8cc5..4e0dc8bd37 100644 --- a/lib/inets/doc/src/notes.xml +++ b/lib/inets/doc/src/notes.xml @@ -32,7 +32,51 @@ <file>notes.xml</file> </header> - <section><title>Inets 5.9.5</title> + <section><title>Inets 5.9.6</title> + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + httpc: Allow content body in DELETE requests. Thanks to + James Wheare.</p> + <p> + Own Id: OTP-11190</p> + </item> + <item> + <p> + Add missing brackets to report formatting on ftp_progress + process exit. Thanks to Artur Wilniewczyc.</p> + <p> + Own Id: OTP-11202</p> + </item> + <item> + <p> + Fix some errors in the inets documentation. Thanks to + Johannes Weissl.</p> + <p> + Own Id: OTP-11210</p> + </item> + <item> + <p> + Fix various typos in httpd, inets. Thanks to Tomohiko + Aono.</p> + <p> + Own Id: OTP-11226</p> + </item> + <item> + <p> + Fix httpd config option 'erl_script_nocache'. Thanks to + Johannes Weissl.</p> + <p> + Own Id: OTP-11260</p> + </item> + </list> + </section> + +</section> + +<section><title>Inets 5.9.5</title> <section><title>Fixed Bugs and Malfunctions</title> <list> diff --git a/lib/inets/src/http_client/httpc.erl b/lib/inets/src/http_client/httpc.erl index 4d7023a8e9..da9bbdd1ec 100644 --- a/lib/inets/src/http_client/httpc.erl +++ b/lib/inets/src/http_client/httpc.erl @@ -208,16 +208,8 @@ cancel_request(RequestId) -> cancel_request(RequestId, Profile) when is_atom(Profile) orelse is_pid(Profile) -> ?hcrt("cancel request", [{request_id, RequestId}, {profile, Profile}]), - ok = httpc_manager:cancel_request(RequestId, profile_name(Profile)), - receive - %% If the request was already fulfilled throw away the - %% answer as the request has been canceled. - {http, {RequestId, _}} -> - ok - after 0 -> - ok - end. - + httpc_manager:cancel_request(RequestId, profile_name(Profile)). + %%-------------------------------------------------------------------------- %% set_options(Options) -> ok | {error, Reason} @@ -241,14 +233,7 @@ set_options(Options, Profile) when is_atom(Profile) orelse is_pid(Profile) -> ?hcrt("set options", [{options, Options}, {profile, Profile}]), case validate_options(Options) of {ok, Opts} -> - try - begin - httpc_manager:set_options(Opts, profile_name(Profile)) - end - catch - exit:{noproc, _} -> - {error, inets_not_started} - end; + httpc_manager:set_options(Opts, profile_name(Profile)); {error, Reason} -> {error, Reason} end. @@ -343,8 +328,6 @@ store_cookies(SetCookieHeaders, Url, Profile) ok end catch - exit:{noproc, _} -> - {error, {not_started, Profile}}; error:{badmatch, Bad} -> {error, {parse_failed, Bad}} end. diff --git a/lib/inets/src/http_client/httpc_handler.erl b/lib/inets/src/http_client/httpc_handler.erl index 55794f57dc..80c8b2439e 100644 --- a/lib/inets/src/http_client/httpc_handler.erl +++ b/lib/inets/src/http_client/httpc_handler.erl @@ -32,7 +32,7 @@ start_link/4, %% connect_and_send/2, send/2, - cancel/3, + cancel/2, stream_next/1, info/1 ]). @@ -117,8 +117,8 @@ send(Request, Pid) -> %% Description: Cancels a request. Intended to be called by the httpc %% manager process. %%-------------------------------------------------------------------- -cancel(RequestId, Pid, From) -> - cast({cancel, RequestId, From}, Pid). +cancel(RequestId, Pid) -> + cast({cancel, RequestId}, Pid). %%-------------------------------------------------------------------- @@ -400,19 +400,17 @@ handle_call(info, _, State) -> %% handle_keep_alive_queue/2 on the other hand will just skip the %% request as if it was never issued as in this case the request will %% not have been sent. -handle_cast({cancel, RequestId, From}, +handle_cast({cancel, RequestId}, #state{request = #request{id = RequestId} = Request, profile_name = ProfileName, canceled = Canceled} = State) -> ?hcrv("cancel current request", [{request_id, RequestId}, {profile, ProfileName}, {canceled, Canceled}]), - httpc_manager:request_canceled(RequestId, ProfileName, From), - ?hcrv("canceled", []), {stop, normal, State#state{canceled = [RequestId | Canceled], request = Request#request{from = answer_sent}}}; -handle_cast({cancel, RequestId, From}, +handle_cast({cancel, RequestId}, #state{profile_name = ProfileName, request = #request{id = CurrId}, canceled = Canceled} = State) -> @@ -420,8 +418,6 @@ handle_cast({cancel, RequestId, From}, {curr_req_id, CurrId}, {profile, ProfileName}, {canceled, Canceled}]), - httpc_manager:request_canceled(RequestId, ProfileName, From), - ?hcrv("canceled", []), {noreply, State#state{canceled = [RequestId | Canceled]}}; handle_cast(stream_next, #state{session = Session} = State) -> @@ -521,19 +517,12 @@ handle_info({Proto, _Socket, Data}, activate_once(Session), {noreply, State#state{mfa = NewMFA}} catch - exit:_Exit -> - ?hcrd("data processing exit", [{exit, _Exit}]), + _:_Reason -> + ?hcrd("data processing exit", [{exit, _Reason}]), ClientReason = {could_not_parse_as_http, Data}, ClientErrMsg = httpc_response:error(Request, ClientReason), NewState = answer_request(Request, ClientErrMsg, State), - {stop, normal, NewState}; - error:_Error -> - ?hcrd("data processing error", [{error, _Error}]), - ClientReason = {could_not_parse_as_http, Data}, - ClientErrMsg = httpc_response:error(Request, ClientReason), - NewState = answer_request(Request, ClientErrMsg, State), {stop, normal, NewState} - end, ?hcri("data processed", [{final_result, FinalResult}]), FinalResult; @@ -1165,7 +1154,7 @@ handle_http_body(Body, #state{headers = Headers, handle_response(#state{status = new} = State) -> ?hcrd("handle response - status = new", []), - handle_response(try_to_enable_pipeline_or_keep_alive(State)); + handle_response(check_persistent(State)); handle_response(#state{request = Request, status = Status, @@ -1440,39 +1429,22 @@ is_keep_alive_enabled_server(_,_) -> is_keep_alive_connection(Headers, #session{client_close = ClientClose}) -> (not ((ClientClose) orelse httpc_response:is_server_closing(Headers))). -try_to_enable_pipeline_or_keep_alive( - #state{session = Session, - request = #request{method = Method}, +check_persistent( + #state{session = #session{type = Type} = Session, status_line = {Version, _, _}, headers = Headers, - profile_name = ProfileName} = State) -> - ?hcrd("try to enable pipeline or keep-alive", - [{version, Version}, - {headers, Headers}, - {session, Session}]), + profile_name = ProfileName} = State) -> case is_keep_alive_enabled_server(Version, Headers) andalso - is_keep_alive_connection(Headers, Session) of + is_keep_alive_connection(Headers, Session) of true -> - case (is_pipeline_enabled_client(Session) andalso - httpc_request:is_idempotent(Method)) of - true -> - insert_session(Session, ProfileName), - State#state{status = pipeline}; - false -> - insert_session(Session, ProfileName), - %% Make sure type is keep_alive in session - %% as it in this case might be pipeline - NewSession = Session#session{type = keep_alive}, - State#state{status = keep_alive, - session = NewSession} - end; + mark_persistent(ProfileName, Session), + State#state{status = Type}; false -> State#state{status = close} end. answer_request(#request{id = RequestId, from = From} = Request, Msg, - #state{session = Session, - timers = Timers, + #state{timers = Timers, profile_name = ProfileName} = State) -> ?hcrt("answer request", [{request, Request}, {msg, Msg}]), httpc_response:send(From, Msg), @@ -1482,19 +1454,14 @@ answer_request(#request{id = RequestId, from = From} = Request, Msg, Timer = {RequestId, TimerRef}, cancel_timer(TimerRef, {timeout, Request#request.id}), httpc_manager:request_done(RequestId, ProfileName), - NewSession = maybe_make_session_available(ProfileName, Session), Timers2 = Timers#timers{request_timers = lists:delete(Timer, RequestTimers)}, State#state{request = Request#request{from = answer_sent}, - session = NewSession, timers = Timers2}. -maybe_make_session_available(ProfileName, - #session{available = false} = Session) -> - update_session(ProfileName, Session, #session.available, true), - Session#session{available = true}; -maybe_make_session_available(_ProfileName, Session) -> - Session. +mark_persistent(ProfileName, Session) -> + update_session(ProfileName, Session, #session.persistent, true), + Session#session{persistent = true}. cancel_timers(#timers{request_timers = ReqTmrs, queue_timer = QTmr}) -> cancel_timer(QTmr, timeout_queue), diff --git a/lib/inets/src/http_client/httpc_internal.hrl b/lib/inets/src/http_client/httpc_internal.hrl index 30e2742e9d..d5b3dd2a2a 100644 --- a/lib/inets/src/http_client/httpc_internal.hrl +++ b/lib/inets/src/http_client/httpc_internal.hrl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2005-2012. All Rights Reserved. +%% Copyright Ericsson AB 2005-2013. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -143,8 +143,8 @@ %% true | false %% This will be true, when a response has been received for - %% the first request. See type above. - available = false + %% the first request and the server has not closed the connection + persistent = false }). diff --git a/lib/inets/src/http_client/httpc_manager.erl b/lib/inets/src/http_client/httpc_manager.erl index c45dcab802..a3ed371e61 100644 --- a/lib/inets/src/http_client/httpc_manager.erl +++ b/lib/inets/src/http_client/httpc_manager.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2002-2012. All Rights Reserved. +%% Copyright Ericsson AB 2002-2013. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -29,7 +29,6 @@ start_link/3, request/2, cancel_request/2, - request_canceled/3, request_done/2, retry_request/2, redirect_request/2, @@ -144,22 +143,7 @@ redirect_request(Request, ProfileName) -> %%-------------------------------------------------------------------- cancel_request(RequestId, ProfileName) -> - call(ProfileName, {cancel_request, RequestId}). - - -%%-------------------------------------------------------------------- -%% Function: request_canceled(RequestId, ProfileName) -> ok -%% RequestId - ref() -%% ProfileName = atom() -%% -%% Description: Confirms that a request has been canceld. Intended to -%% be called by the httpc handler process. -%%-------------------------------------------------------------------- - -request_canceled(RequestId, ProfileName, From) -> - gen_server:reply(From, ok), - cast(ProfileName, {request_canceled, RequestId}). - + cast(ProfileName, {cancel_request, RequestId}). %%-------------------------------------------------------------------- %% Function: request_done(RequestId, ProfileName) -> ok @@ -467,33 +451,13 @@ do_init(ProfileName, CookiesDir) -> %%-------------------------------------------------------------------- handle_call({request, Request}, _, State) -> ?hcri("request", [{request, Request}]), - case (catch handle_request(Request, State)) of + case (catch handle_request(Request, State, false)) of {reply, Msg, NewState} -> {reply, Msg, NewState}; Error -> {stop, Error, httpc_response:error(Request, Error), State} end; -handle_call({cancel_request, RequestId}, From, - #state{handler_db = HandlerDb} = State) -> - ?hcri("cancel_request", [{request_id, RequestId}]), - case ets:lookup(HandlerDb, RequestId) of - [] -> - %% The request has allready compleated make sure - %% it is deliverd to the client process queue so - %% it can be thrown away by httpc:cancel_request - %% This delay is hopfully a temporary workaround. - %% Note that it will not not delay the manager, - %% only the client that called httpc:cancel_request - timer:apply_after(?DELAY, gen_server, reply, [From, ok]), - {noreply, State}; - [{_, Pid, _}] -> - httpc_handler:cancel(RequestId, Pid, From), - {noreply, - State#state{cancel = - [{RequestId, Pid, From} | State#state.cancel]}} - end; - handle_call(reset_cookies, _, #state{cookie_db = CookieDb} = State) -> ?hcrv("reset cookies", []), httpc_cookie:reset_db(CookieDb), @@ -547,7 +511,7 @@ handle_cast({retry_or_redirect_request, {Time, Request}}, {noreply, State}; handle_cast({retry_or_redirect_request, Request}, State) -> - case (catch handle_request(Request, State)) of + case (catch handle_request(Request, State, true)) of {reply, {ok, _}, NewState} -> {noreply, NewState}; Error -> @@ -555,19 +519,19 @@ handle_cast({retry_or_redirect_request, Request}, State) -> {stop, Error, State} end; -handle_cast({request_canceled, RequestId}, State) -> - ?hcrv("request canceled", [{request_id, RequestId}]), - ets:delete(State#state.handler_db, RequestId), - case lists:keysearch(RequestId, 1, State#state.cancel) of - {value, Entry = {RequestId, _, From}} -> - ?hcrt("found in cancel", [{from, From}]), - {noreply, - State#state{cancel = lists:delete(Entry, State#state.cancel)}}; - Else -> - ?hcrt("not found in cancel", [{else, Else}]), - {noreply, State} +handle_cast({cancel_request, RequestId}, + #state{handler_db = HandlerDb} = State) -> + case ets:lookup(HandlerDb, RequestId) of + [] -> + %% Request already compleated nothing to + %% cancel + {noreply, State}; + [{_, Pid, _}] -> + httpc_handler:cancel(RequestId, Pid), + ets:delete(State#state.handler_db, RequestId), + {noreply, State} end; - + handle_cast({request_done, RequestId}, State) -> ?hcrv("request done", [{request_id, RequestId}]), ets:delete(State#state.handler_db, RequestId), @@ -629,22 +593,8 @@ handle_info({'EXIT', _, _}, State) -> %% Handled in DOWN {noreply, State}; handle_info({'DOWN', _, _, Pid, _}, State) -> - ets:match_delete(State#state.handler_db, {'_', Pid, '_'}), - - %% If there where any canceled request, handled by the - %% the process that now has terminated, the - %% cancelation can be viewed as sucessfull! - NewCanceldList = - lists:foldl(fun(Entry = {_, HandlerPid, From}, Acc) -> - case HandlerPid of - Pid -> - gen_server:reply(From, ok), - lists:delete(Entry, Acc); - _ -> - Acc - end - end, State#state.cancel, State#state.cancel), - {noreply, State#state{cancel = NewCanceldList}}; + ets:match_delete(State#state.handler_db, {'_', Pid, '_'}), + {noreply, State}; handle_info(Info, State) -> Report = io_lib:format("Unknown message in " "httpc_manager:handle_info ~p~n", [Info]), @@ -774,7 +724,7 @@ get_handler_info(Tab) -> handle_request(#request{settings = #http_options{version = "HTTP/0.9"}} = Request, - State) -> + State, _) -> %% Act as an HTTP/0.9 client that does not know anything %% about persistent connections @@ -787,7 +737,7 @@ handle_request(#request{settings = handle_request(#request{settings = #http_options{version = "HTTP/1.0"}} = Request, - State) -> + State, _) -> %% Act as an HTTP/1.0 client that does not %% use persistent connections @@ -798,13 +748,13 @@ handle_request(#request{settings = start_handler(NewRequest#request{headers = NewHeaders}, State), {reply, {ok, NewRequest#request.id}, State}; -handle_request(Request, State = #state{options = Options}) -> +handle_request(Request, State = #state{options = Options}, Retry) -> NewRequest = handle_cookies(generate_request_id(Request), State), SessionType = session_type(Options), case select_session(Request#request.method, Request#request.address, - Request#request.scheme, SessionType, State) of + Request#request.scheme, SessionType, State, Retry) of {ok, HandlerPid} -> pipeline_or_keep_alive(NewRequest, HandlerPid, State); no_connection -> @@ -828,6 +778,7 @@ start_handler(#request{id = Id, #state{profile_name = ProfileName, handler_db = HandlerDb, options = Options}) -> + ClientClose = httpc_request:is_client_closing(Request#request.headers), {ok, Pid} = case is_inets_manager() of true -> @@ -838,13 +789,18 @@ start_handler(#request{id = Id, end, HandlerInfo = {Id, Pid, From}, ets:insert(HandlerDb, HandlerInfo), + insert_session(#session{id = {Request#request.address, Pid}, + scheme = Request#request.scheme, + client_close = ClientClose, + type = session_type(Options) + }, ProfileName), erlang:monitor(process, Pid). select_session(Method, HostPort, Scheme, SessionType, #state{options = #options{max_pipeline_length = MaxPipe, max_keep_alive_length = MaxKeepAlive}, - session_db = SessionDb}) -> + session_db = SessionDb}, Retry) -> ?hcrd("select session", [{session_type, SessionType}, {max_pipeline_length, MaxPipe}, {max_keep_alive_length, MaxKeepAlive}]), @@ -857,19 +813,29 @@ select_session(Method, HostPort, Scheme, SessionType, %% client_close, scheme and type specified. %% The fields id (part of: HandlerPid) and queue_length %% specified. - Pattern = #session{id = {HostPort, '$1'}, - client_close = false, - scheme = Scheme, - queue_length = '$2', - type = SessionType, - available = true, - _ = '_'}, + Pattern = case (Retry andalso SessionType == pipeline) of + true -> + #session{id = {HostPort, '$1'}, + client_close = false, + scheme = Scheme, + queue_length = '$2', + type = SessionType, + persistent = true, + _ = '_'}; + false -> + #session{id = {HostPort, '$1'}, + client_close = false, + scheme = Scheme, + queue_length = '$2', + type = SessionType, + _ = '_'} + end, %% {'_', {HostPort, '$1'}, false, Scheme, '_', '$2', SessionTyp}, Candidates = ets:match(SessionDb, Pattern), ?hcrd("select session", [{host_port, HostPort}, {scheme, Scheme}, {type, SessionType}, - {candidates, Candidates}]), + {candidates, Candidates}]), select_session(Candidates, MaxKeepAlive, MaxPipe, SessionType); false -> no_connection diff --git a/lib/inets/src/http_server/httpd_conf.erl b/lib/inets/src/http_server/httpd_conf.erl index b3ca13e2fe..27446ca7fe 100644 --- a/lib/inets/src/http_server/httpd_conf.erl +++ b/lib/inets/src/http_server/httpd_conf.erl @@ -798,6 +798,8 @@ store({log_format, LogFormat}, _ConfigList) store({server_tokens, ServerTokens} = Entry, _ConfigList) -> Server = server(ServerTokens), {ok, [Entry, {server, Server}]}; +store({keep_alive_timeout, KeepAliveTimeout}, _ConfigList) -> + {ok, {keep_alive_timeout, KeepAliveTimeout * 1000}}; store(ConfigListEntry, _ConfigList) -> {ok, ConfigListEntry}. diff --git a/lib/inets/src/http_server/mod_cgi.erl b/lib/inets/src/http_server/mod_cgi.erl index f1b73810e6..d933b0a4ba 100644 --- a/lib/inets/src/http_server/mod_cgi.erl +++ b/lib/inets/src/http_server/mod_cgi.erl @@ -131,9 +131,9 @@ store({script_nocache, Value} = Conf, _) {ok, Conf}; store({script_nocache, Value}, _) -> {error, {wrong_type, {script_nocache, Value}}}; -store({script_timeout, Value} = Conf, _) +store({script_timeout, Value}, _) when is_integer(Value), Value >= 0 -> - {ok, Conf}; + {ok, {script_timeout, Value * 1000}}; store({script_timeout, Value}, _) -> {error, {wrong_type, {script_timeout, Value}}}. @@ -238,7 +238,7 @@ send_request_body_to_script(ModData, Port) -> end. deliver_webpage(#mod{config_db = Db} = ModData, Port) -> - Timeout = cgi_timeout(Db), + Timeout = script_timeout(Db), case receive_headers(Port, httpd_cgi, parse_headers, [<<>>, [], []], Timeout) of {Headers, Body} -> @@ -341,8 +341,8 @@ script_elements(#mod{method = "PUT", entity_body = Body}, _) -> script_elements(_, _) -> []. -cgi_timeout(Db) -> - httpd_util:lookup(Db, cgi_timeout, ?DEFAULT_CGI_TIMEOUT). +script_timeout(Db) -> + httpd_util:lookup(Db, script_timeout, ?DEFAULT_CGI_TIMEOUT). %% Convert error to printable string %% diff --git a/lib/inets/test/Makefile b/lib/inets/test/Makefile index dfa86906fd..2f2f6ec16e 100644 --- a/lib/inets/test/Makefile +++ b/lib/inets/test/Makefile @@ -215,7 +215,7 @@ INETS_FILES = inets.config $(INETS_SPECS) # inets_tftp_suite INETS_DATADIRS = inets_SUITE_data inets_sup_SUITE_data -HTTPD_DATADIRS = httpd_test_data httpd_SUITE_data +HTTPD_DATADIRS = httpd_test_data httpd_SUITE_data httpd_basic_SUITE_data HTTPC_DATADIRS = httpc_SUITE_data httpc_proxy_SUITE_data FTP_DATADIRS = ftp_SUITE_data diff --git a/lib/inets/test/httpc_SUITE.erl b/lib/inets/test/httpc_SUITE.erl index 0c35f284f7..818edc12ac 100644 --- a/lib/inets/test/httpc_SUITE.erl +++ b/lib/inets/test/httpc_SUITE.erl @@ -277,9 +277,6 @@ trace(Config) when is_list(Config) -> pipeline(Config) when is_list(Config) -> Request = {url(group_name(Config), "/dummy.html", Config), []}, {ok, _} = httpc:request(get, Request, [], [], pipeline), - - %% Make sure pipeline session is registerd - test_server:sleep(4000), keep_alive_requests(Request, pipeline). %%-------------------------------------------------------------------- @@ -287,9 +284,6 @@ pipeline(Config) when is_list(Config) -> persistent_connection(Config) when is_list(Config) -> Request = {url(group_name(Config), "/dummy.html", Config), []}, {ok, _} = httpc:request(get, Request, [], [], persistent), - - %% Make sure pipeline session is registerd - test_server:sleep(4000), keep_alive_requests(Request, persistent). %%------------------------------------------------------------------------- @@ -311,13 +305,8 @@ async(Config) when is_list(Config) -> {ok, NewRequestId} = httpc:request(get, Request, [], [{sync, false}]), - ok = httpc:cancel_request(NewRequestId), - receive - {http, {NewRequestId, _}} -> - ct:fail(http_cancel_request_failed) - after 3000 -> - ok - end. + ok = httpc:cancel_request(NewRequestId). + %%------------------------------------------------------------------------- save_to_file() -> [{doc, "Test to save the http body to a file"}]. @@ -1149,7 +1138,7 @@ receive_replys([ID|IDs]) -> {http, {ID, {{_, 200, _}, [_|_], _}}} -> receive_replys(IDs); {http, {Other, {{_, 200, _}, [_|_], _}}} -> - ct:fail({recived_canceld_id, Other}) + ct:pal({recived_canceld_id, Other}) end. %% Perform a synchronous stop diff --git a/lib/inets/test/httpc_SUITE_data/ssl_client_cert.pem b/lib/inets/test/httpc_SUITE_data/ssl_client_cert.pem index f274d2021d..427447958d 100644 --- a/lib/inets/test/httpc_SUITE_data/ssl_client_cert.pem +++ b/lib/inets/test/httpc_SUITE_data/ssl_client_cert.pem @@ -1,22 +1,31 @@ -----BEGIN RSA PRIVATE KEY----- -MIIBOwIBAAJBANz7eFvORmJDi1XJMM2U3uHC5wmp/DXTLMw08XaEvtZ73wgVg84E -V0oyX3Kh1thRE3Hch9AyrHjgpizCj9/Ra38CAwEAAQJACzpz2SZYCTIpaEh6xFdm -I86FcsZCXHHIeu/NvRntoHQ+nfM7Np379+z6XNJWIcWh/QgG/jNJalR1BO+eyc6/ -YQIhAP3m8M0LDxJwSgHFtGAGatQqaqw9l48Kq5xdMFqvdpiHAiEA3s7lld6yCJYu -6q7fZjTH+eKUwgg0vpgJutP7Fsok60kCIHHesQBEhW3vjkFdOZgXSLH+k/jLZr1w -O6bU5GrHZpjhAiEAyTvGYcjDtTunXjDY9l+fadK6FlEBCk8ZIpNIiTnDhHkCIQDr -QxxLLuNHRj8iWNbuVVZ99SJy8zC33pMgPFaFKaZesQ== +MIICXQIBAAKBgQCTFBPkOO98fDY3j6MIxIGKp+rampfIay50Lx4+EnCnRSSVwC+n +0VVmP7V5SGFJpuXJzN0hvqPUWOOjiMTNlNRaGy0pqu2oMXWAPLOxHWL1wT53h2Zr +3FUNU/N0Rvnkttse1KZJ9uYCLKUiuXXsv2rR62nH3OhRIiBHSAcSv0NRWwIDAQAB +AoGACdIVYe/LTeydUihtInC8lZ2QuPgJmoBNocRjqJFipEihoL4scHAx25n1bBvB +I0HZphffzBkGp28oBAtl2LRPWXqu527unc/RWRfLMqSK1xNSq1DxD1a30zkrZPna +QiV65vEJuNSJTtlDy/Zqc/BVZXCpxWlzYQedZgkmf0Qse8ECQQCmaz02Yur8zC9f +eSQKU5OSzGw3bSIumEzziCfHdTheK6MEoccf5TCAyLXhZwA7QlKja4tFXfeyVxws +/LlnUJN9AkEA4j+xnOeYUyGKXL5i+BAbnqpI4MzPiq+IoCYkaRlD/wAws24r5HNI +ZQmEHWqD/NNzOf/A2XuyLtMiTGJPW/DftwJBAKKpJP6Ytuh6xz8BUCnLwO12Y7vV +LtjuQiCzD3aUa5EYA9HOMqxJPxxRkf0LyR0i2VUkE8+sZiPpov+R0cJa7p0CQQCj +40GUiArGRSiF7/+e84QeVfl+pb29F1QftiFv5DZmFEwy3Z572KpbTh5edJbxYHY6 +UDHxGHJFCvnwXNJhpkVXAkBJqfEfiMJ3Q/E5Gpf3sQizacouW92iiN8ojlF1oB80 +t34RysJH7SgI3gdMhTribCo2UUaV0StjR6yodPN+TB2J -----END RSA PRIVATE KEY----- -----BEGIN CERTIFICATE----- -MIIB7jCCAZgCAQAwDQYJKoZIhvcNAQEEBQAwgYExCzAJBgNVBAYTAlNFMRIwEAYD -VQQHEwlTdG9ja2hvbG0xETAPBgNVBAoTCEVyaWNzc29uMQwwCgYDVQQLEwNFVFgx -FjAUBgNVBAMTDUhlbGVuIEFpcml5YW4xJTAjBgkqhkiG9w0BCQEWFmhlbGVuQGVy -aXguZXJpY3Nzb24uc2UwHhcNOTcwNzI4MDcxNDI1WhcNOTgxMjEwMDcxNDI1WjCB -gTELMAkGA1UEBhMCU0UxEjAQBgNVBAcTCVN0b2NraG9sbTERMA8GA1UEChMIRXJp -Y3Nzb24xDDAKBgNVBAsTA0VUWDEWMBQGA1UEAxMNSGVsZW4gQWlyaXlhbjElMCMG -CSqGSIb3DQEJARYWaGVsZW5AZXJpeC5lcmljc3Nvbi5zZTBcMA0GCSqGSIb3DQEB -AQUAA0sAMEgCQQDc+3hbzkZiQ4tVyTDNlN7hwucJqfw10yzMNPF2hL7We98IFYPO -BFdKMl9yodbYURNx3IfQMqx44KYswo/f0Wt/AgMBAAEwDQYJKoZIhvcNAQEEBQAD -QQC2++hLIaQJ4ChCjFE9UCfXO9cZ3Vq/FT9VjE+G4MRBDo4LQ5mBKNXcPF6EFZmi -7XrlvopXkVPlRguTi2SLRPkY +MIIChzCCAfCgAwIBAgIGAIsapa8BMA0GCSqGSIb3DQEBBQUAMHoxDjAMBgNVBAMT +BW90cENBMSAwHgYJKoZIhvcNAQkBFhF0ZXN0ZXJAZXJsYW5nLm9yZzESMBAGA1UE +BxMJU3RvY2tob2xtMQswCQYDVQQGEwJTRTEPMA0GA1UEChMGZXJsYW5nMRQwEgYD +VQQLEwt0ZXN0aW5nIGRlcDAiGA8yMDEwMDkwMTAwMDAwMFoYDzIwMjUwODI4MDAw +MDAwWjB7MQ8wDQYDVQQDEwZjbGllbnQxIDAeBgkqhkiG9w0BCQEWEXRlc3RlckBl +cmxhbmcub3JnMRIwEAYDVQQHEwlTdG9ja2hvbG0xCzAJBgNVBAYTAlNFMQ8wDQYD +VQQKEwZlcmxhbmcxFDASBgNVBAsTC3Rlc3RpbmcgZGVwMIGfMA0GCSqGSIb3DQEB +AQUAA4GNADCBiQKBgQCTFBPkOO98fDY3j6MIxIGKp+rampfIay50Lx4+EnCnRSSV +wC+n0VVmP7V5SGFJpuXJzN0hvqPUWOOjiMTNlNRaGy0pqu2oMXWAPLOxHWL1wT53 +h2Zr3FUNU/N0Rvnkttse1KZJ9uYCLKUiuXXsv2rR62nH3OhRIiBHSAcSv0NRWwID +AQABoxMwETAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBBQUAA4GBAG8t6f1A +PF7xayGxtUpG2r6W5ETylC3ZIKPS2kfJk9aYi7AZNTp7/xTU6SgqvFBN8aBPzxCD +4jHrSNC8DSb4X1x9uimarb6qdZDHEdij+DRAd2eygJHZxEf7+8B4Fx34thQeU9hZ +S1Izke5AlsyFMkvB7h0anE4k9BfuU70vl6v5 -----END CERTIFICATE----- diff --git a/lib/inets/test/httpc_SUITE_data/ssl_server_cert.pem b/lib/inets/test/httpc_SUITE_data/ssl_server_cert.pem index f01b6c992b..4aac86db49 100644 --- a/lib/inets/test/httpc_SUITE_data/ssl_server_cert.pem +++ b/lib/inets/test/httpc_SUITE_data/ssl_server_cert.pem @@ -1,22 +1,31 @@ -----BEGIN RSA PRIVATE KEY----- -MIIBOQIBAAJBAMe2WhP6s+JeKOwWPEjI9susfN4Vjn2dd1X4QUlOETcWVLoF916m -M4JU+ms7+ciMR8GRNCsIeqZGY8/GSqm74ccCAwEAAQJAF08YKlbLYfM9cXiS5qfV -7iWemUkIzW5wfC8yZ3zeE4Cp6R9ViUfs/dadQ/23Cw0Bpo2t8UdTUdCa4KpmqOem -cQIhAOnxTWZ5eo6h6PXDp7L5FZUACg8+wT3qf5f2is2mbSZPAiEA2orUY8JZDTSk -Rm7q9WxLiLNtORsXdTCmnCWhqBOYpwkCIErdowRxScxNekz0IT3AQqzdR1rbnWHg -IpcSGhd39CQ3AiA1XvQxjLP8wp9fyBS/bPwhXVhOOuyGpSP7PEF3b5m3KQIgGQWc -/a5wuWx3pc3mLx0ILwNoJr2ubFEuW1PJPsPJPv0= +MIICXQIBAAKBgQCf4Htxr99lLs5W8QQw7jdakqyAkIjOW4aqH8sr4va4SvZ9Adq6 +7k8jMHefCVZo+F8x4cwsBgB4aWzFIGBnvFTi6YsH27XW7f9O9IPCej8fdhRZ4UAt +NHa253buOWpDGla2JmIdkmfFvXFJycMIKbG5tYilVXoWKBMKmCwWaXz0nQIDAQAB +AoGAQIlma0r6W6bcRj4+Wd4fXCFvHuq5Psu1fYEeC5Yvz8761xVjjSfbrDHJZ9pm +FjOEgedK+s5lbDXqYVyjbdyZSugStBRocSmbG8SQHcAsxR2ZIkNzX2hYzB+lslWo +T3YJojDyB134O7XJznCu+ZFXP86jyJ1JT6k6a+OIHcwnJ+ECQQDYn57dY4Px3mEd +VBLStN3YkRF5oFyT+xk7IaKeLLB6n4gCnoVbBoHut7PFbPYPzoNzEwPk3MQKDIHb +Kig3S5CpAkEAvPA1VmoJWAlN6kUi+F2L8HXEArzE8x7vwdsslrwMKUe4dFS+ZC/7 +5iDOaxcZ7TYkCgwzBt341++DCgP6j3fY1QJBALB6AcOcwi52m6l4B8mu3ZkEPjdX +BHTuONTqhv/TqoaLlxODL2NDvvDKqeMp7KBd/srt79swW2lQXS4+fvrlTdkCQQCm +zxj4O1QWkthkfje6ubSkTwUIOatUzrp1F9GNH2dJRtX2dx9FCwxGCC7WY6XzRXqa +GF0wsedSllbGD+82nWQlAkAicMGqCqRq4hKR/cVmFatOqKVWCVkx6OFF2FhuiI5Z +h5eIOPGCt8dVRs1P9DNSld/D98Sfm65m85z8BtXovvYV -----END RSA PRIVATE KEY----- -----BEGIN CERTIFICATE----- -MIIB7jCCAZgCAQAwDQYJKoZIhvcNAQEEBQAwgYExCzAJBgNVBAYTAlNFMRIwEAYD -VQQHEwlTdG9ja2hvbG0xETAPBgNVBAoTCEVyaWNzc29uMQwwCgYDVQQLEwNFVFgx -FjAUBgNVBAMTDUhlbGVuIEFpcml5YW4xJTAjBgkqhkiG9w0BCQEWFmhlbGVuQGVy -aXguZXJpY3Nzb24uc2UwHhcNOTcwNzI4MDcyMTAwWhcNOTgxMjEwMDcyMTAwWjCB -gTELMAkGA1UEBhMCU0UxEjAQBgNVBAcTCVN0b2NraG9sbTERMA8GA1UEChMIRXJp -Y3Nzb24xDDAKBgNVBAsTA0VUWDEWMBQGA1UEAxMNSGVsZW4gQWlyaXlhbjElMCMG -CSqGSIb3DQEJARYWaGVsZW5AZXJpeC5lcmljc3Nvbi5zZTBcMA0GCSqGSIb3DQEB -AQUAA0sAMEgCQQDHtloT+rPiXijsFjxIyPbLrHzeFY59nXdV+EFJThE3FlS6Bfde -pjOCVPprO/nIjEfBkTQrCHqmRmPPxkqpu+HHAgMBAAEwDQYJKoZIhvcNAQEEBQAD -QQCnU1TkxmfbLdUwjdECb5x9QHCevAR7AmTms4Csn2oOEyPX+bgF2d94xhrV1sxO -Rs0yigk1PtN17Ci0Dey0LYkR +MIIChzCCAfCgAwIBAgIGANUxXM9BMA0GCSqGSIb3DQEBBQUAMHoxDjAMBgNVBAMT +BW90cENBMSAwHgYJKoZIhvcNAQkBFhF0ZXN0ZXJAZXJsYW5nLm9yZzESMBAGA1UE +BxMJU3RvY2tob2xtMQswCQYDVQQGEwJTRTEPMA0GA1UEChMGZXJsYW5nMRQwEgYD +VQQLEwt0ZXN0aW5nIGRlcDAiGA8yMDEwMDkwMTAwMDAwMFoYDzIwMjUwODI4MDAw +MDAwWjB7MQ8wDQYDVQQDEwZzZXJ2ZXIxIDAeBgkqhkiG9w0BCQEWEXRlc3RlckBl +cmxhbmcub3JnMRIwEAYDVQQHEwlTdG9ja2hvbG0xCzAJBgNVBAYTAlNFMQ8wDQYD +VQQKEwZlcmxhbmcxFDASBgNVBAsTC3Rlc3RpbmcgZGVwMIGfMA0GCSqGSIb3DQEB +AQUAA4GNADCBiQKBgQCf4Htxr99lLs5W8QQw7jdakqyAkIjOW4aqH8sr4va4SvZ9 +Adq67k8jMHefCVZo+F8x4cwsBgB4aWzFIGBnvFTi6YsH27XW7f9O9IPCej8fdhRZ +4UAtNHa253buOWpDGla2JmIdkmfFvXFJycMIKbG5tYilVXoWKBMKmCwWaXz0nQID +AQABoxMwETAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBBQUAA4GBAGF5Pfwk +QDdwJup/mVITPxbBls4Yl7anDooUQsq8066lA1g54H/PRfXscGkyCFGh1ifXvf1L +psMRoBAdDHL/wSJplk3rRavkC94eBgnTFZmfKL6844g1j53yameiYL8IEVExYMBg +/XGyc0qwq57WT8B/K4aElrvlBlQ0wF3wN54M -----END CERTIFICATE----- diff --git a/lib/inets/test/httpd_SUITE.erl b/lib/inets/test/httpd_SUITE.erl index 1efa78a63e..5dca76b76b 100644 --- a/lib/inets/test/httpd_SUITE.erl +++ b/lib/inets/test/httpd_SUITE.erl @@ -1919,7 +1919,7 @@ ticket_5865(Config) -> " HTTP/1.1\r\nHost:" ++Host++"\r\n\r\n", [{statuscode, 200}, - {no_last_modified, + {no_header, "last-modified"}]), ok; {error, Reason} -> diff --git a/lib/inets/test/httpd_SUITE_data/server_root/ssl/ssl_client.pem b/lib/inets/test/httpd_SUITE_data/server_root/ssl/ssl_client.pem index 8221139eb4..427447958d 100644 --- a/lib/inets/test/httpd_SUITE_data/server_root/ssl/ssl_client.pem +++ b/lib/inets/test/httpd_SUITE_data/server_root/ssl/ssl_client.pem @@ -1,22 +1,31 @@ -----BEGIN RSA PRIVATE KEY----- -MIIBPAIBAAJBAL6Ym/bgUvhhnPkw08sggGg8Tnp759ThGMEjkmDzhuJ3w3PfnF65 -mgHcgunku4G6LxAQfEUougJWf9Phmjj3oRUCAwEAAQJBAKMjvVvzZxFzfAlP4flc -OI0AEayFokp04dtvtzuFN09f+aBo2dP18xHmKLCZvxrBOaRAROoQYscALiIVpN07 -GAECIQDfi+sSfAFaDlT3vzpL3xE5UEH6IzY8jWpaZfM1QaToJQIhANpEF50H4wGO -8Sbh7dUutNd+s+NYUjsMySW2DjLKMsoxAiEAzzb2ftrdsempD0F+O0gZwiPIFKLB -Kp33YLYyHEKuJtUCIDGi+pvDh2R7VWw6RRQOIyI+tjolg83aAoSI+oGiahqBAiEA -xzmNNajwoaokvWvlaz0na8rhxu45grOvDrflBT9XvSQ= +MIICXQIBAAKBgQCTFBPkOO98fDY3j6MIxIGKp+rampfIay50Lx4+EnCnRSSVwC+n +0VVmP7V5SGFJpuXJzN0hvqPUWOOjiMTNlNRaGy0pqu2oMXWAPLOxHWL1wT53h2Zr +3FUNU/N0Rvnkttse1KZJ9uYCLKUiuXXsv2rR62nH3OhRIiBHSAcSv0NRWwIDAQAB +AoGACdIVYe/LTeydUihtInC8lZ2QuPgJmoBNocRjqJFipEihoL4scHAx25n1bBvB +I0HZphffzBkGp28oBAtl2LRPWXqu527unc/RWRfLMqSK1xNSq1DxD1a30zkrZPna +QiV65vEJuNSJTtlDy/Zqc/BVZXCpxWlzYQedZgkmf0Qse8ECQQCmaz02Yur8zC9f +eSQKU5OSzGw3bSIumEzziCfHdTheK6MEoccf5TCAyLXhZwA7QlKja4tFXfeyVxws +/LlnUJN9AkEA4j+xnOeYUyGKXL5i+BAbnqpI4MzPiq+IoCYkaRlD/wAws24r5HNI +ZQmEHWqD/NNzOf/A2XuyLtMiTGJPW/DftwJBAKKpJP6Ytuh6xz8BUCnLwO12Y7vV +LtjuQiCzD3aUa5EYA9HOMqxJPxxRkf0LyR0i2VUkE8+sZiPpov+R0cJa7p0CQQCj +40GUiArGRSiF7/+e84QeVfl+pb29F1QftiFv5DZmFEwy3Z572KpbTh5edJbxYHY6 +UDHxGHJFCvnwXNJhpkVXAkBJqfEfiMJ3Q/E5Gpf3sQizacouW92iiN8ojlF1oB80 +t34RysJH7SgI3gdMhTribCo2UUaV0StjR6yodPN+TB2J -----END RSA PRIVATE KEY----- -----BEGIN CERTIFICATE----- -MIICDDCCAbYCAQAwDQYJKoZIhvcNAQEEBQAwgZAxCzAJBgNVBAYTAlNFMRIwEAYD -VQQIEwlTdG9ja2hvbG0xDzANBgNVBAcTBkFsdnNqbzEMMAoGA1UEChMDRVRYMQ4w -DAYDVQQLEwVETi9TUDEXMBUGA1UEAxMOSm9ha2ltIEdyZWJlbm8xJTAjBgkqhkiG -9w0BCQEWFmpvY2tlQGVyaXguZXJpY3Nzb24uc2UwHhcNOTcwNzE1MTUzNDM2WhcN -MDMwMjIyMTUzNDM2WjCBkDELMAkGA1UEBhMCU0UxEjAQBgNVBAgTCVN0b2NraG9s -bTEPMA0GA1UEBxMGQWx2c2pvMQwwCgYDVQQKEwNFVFgxDjAMBgNVBAsTBUROL1NQ -MRcwFQYDVQQDEw5Kb2FraW0gR3JlYmVubzElMCMGCSqGSIb3DQEJARYWam9ja2VA -ZXJpeC5lcmljc3Nvbi5zZTBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQC+mJv24FL4 -YZz5MNPLIIBoPE56e+fU4RjBI5Jg84bid8Nz35xeuZoB3ILp5LuBui8QEHxFKLoC -Vn/T4Zo496EVAgMBAAEwDQYJKoZIhvcNAQEEBQADQQBYxQVfTydyZCE0UXvZd7Ei -josNsAaWJk9fFIJaG9uyXCEfg2dVgoT2eBk3D9DI+7OB+78isM5CVlFbL7hilvP8 +MIIChzCCAfCgAwIBAgIGAIsapa8BMA0GCSqGSIb3DQEBBQUAMHoxDjAMBgNVBAMT +BW90cENBMSAwHgYJKoZIhvcNAQkBFhF0ZXN0ZXJAZXJsYW5nLm9yZzESMBAGA1UE +BxMJU3RvY2tob2xtMQswCQYDVQQGEwJTRTEPMA0GA1UEChMGZXJsYW5nMRQwEgYD +VQQLEwt0ZXN0aW5nIGRlcDAiGA8yMDEwMDkwMTAwMDAwMFoYDzIwMjUwODI4MDAw +MDAwWjB7MQ8wDQYDVQQDEwZjbGllbnQxIDAeBgkqhkiG9w0BCQEWEXRlc3RlckBl +cmxhbmcub3JnMRIwEAYDVQQHEwlTdG9ja2hvbG0xCzAJBgNVBAYTAlNFMQ8wDQYD +VQQKEwZlcmxhbmcxFDASBgNVBAsTC3Rlc3RpbmcgZGVwMIGfMA0GCSqGSIb3DQEB +AQUAA4GNADCBiQKBgQCTFBPkOO98fDY3j6MIxIGKp+rampfIay50Lx4+EnCnRSSV +wC+n0VVmP7V5SGFJpuXJzN0hvqPUWOOjiMTNlNRaGy0pqu2oMXWAPLOxHWL1wT53 +h2Zr3FUNU/N0Rvnkttse1KZJ9uYCLKUiuXXsv2rR62nH3OhRIiBHSAcSv0NRWwID +AQABoxMwETAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBBQUAA4GBAG8t6f1A +PF7xayGxtUpG2r6W5ETylC3ZIKPS2kfJk9aYi7AZNTp7/xTU6SgqvFBN8aBPzxCD +4jHrSNC8DSb4X1x9uimarb6qdZDHEdij+DRAd2eygJHZxEf7+8B4Fx34thQeU9hZ +S1Izke5AlsyFMkvB7h0anE4k9BfuU70vl6v5 -----END CERTIFICATE----- diff --git a/lib/inets/test/httpd_SUITE_data/server_root/ssl/ssl_server.pem b/lib/inets/test/httpd_SUITE_data/server_root/ssl/ssl_server.pem index fe739c15f7..4aac86db49 100644 --- a/lib/inets/test/httpd_SUITE_data/server_root/ssl/ssl_server.pem +++ b/lib/inets/test/httpd_SUITE_data/server_root/ssl/ssl_server.pem @@ -1,22 +1,31 @@ -----BEGIN RSA PRIVATE KEY----- -MIIBOwIBAAJBAL9Bozj3BIjL5Cy8b3rjMT2kPZRychX4wz9bHoIIiKnKo1xXHYjw -g3N9zWM1f1ZzMADwVry1uAInA8q09+7hL20CAwEAAQJACwu2ao7RozjrV64WXimK -6X131P/7GMvCMwGHNIlbozqoOqmZcYrbKaF61l+XuwA2QvTo3ywW1Ivxcyr6TeAr -PQIhAOX+WXT6yiqqwjt08kjBCJyMgfZtdAO6pc/6pKjNWiZfAiEA1OH1iPW/OQe5 -tlQXpiRVdLyneNsPygPRJc4Bdwu3hbMCIQDbI5pA56QxOzqOREOGJsb5wrciAfAE -jZbnr72sSN2YqQIgAWFpvzagw9Tp/mWzNY+cwkIK7/yzsIKv04fveH8p9IMCIQCr -td4IiukeUwXmPSvYM4uCE/+J89wEL9qU8Mlc3gDLXA== +MIICXQIBAAKBgQCf4Htxr99lLs5W8QQw7jdakqyAkIjOW4aqH8sr4va4SvZ9Adq6 +7k8jMHefCVZo+F8x4cwsBgB4aWzFIGBnvFTi6YsH27XW7f9O9IPCej8fdhRZ4UAt +NHa253buOWpDGla2JmIdkmfFvXFJycMIKbG5tYilVXoWKBMKmCwWaXz0nQIDAQAB +AoGAQIlma0r6W6bcRj4+Wd4fXCFvHuq5Psu1fYEeC5Yvz8761xVjjSfbrDHJZ9pm +FjOEgedK+s5lbDXqYVyjbdyZSugStBRocSmbG8SQHcAsxR2ZIkNzX2hYzB+lslWo +T3YJojDyB134O7XJznCu+ZFXP86jyJ1JT6k6a+OIHcwnJ+ECQQDYn57dY4Px3mEd +VBLStN3YkRF5oFyT+xk7IaKeLLB6n4gCnoVbBoHut7PFbPYPzoNzEwPk3MQKDIHb +Kig3S5CpAkEAvPA1VmoJWAlN6kUi+F2L8HXEArzE8x7vwdsslrwMKUe4dFS+ZC/7 +5iDOaxcZ7TYkCgwzBt341++DCgP6j3fY1QJBALB6AcOcwi52m6l4B8mu3ZkEPjdX +BHTuONTqhv/TqoaLlxODL2NDvvDKqeMp7KBd/srt79swW2lQXS4+fvrlTdkCQQCm +zxj4O1QWkthkfje6ubSkTwUIOatUzrp1F9GNH2dJRtX2dx9FCwxGCC7WY6XzRXqa +GF0wsedSllbGD+82nWQlAkAicMGqCqRq4hKR/cVmFatOqKVWCVkx6OFF2FhuiI5Z +h5eIOPGCt8dVRs1P9DNSld/D98Sfm65m85z8BtXovvYV -----END RSA PRIVATE KEY----- -----BEGIN CERTIFICATE----- -MIICDDCCAbYCAQAwDQYJKoZIhvcNAQEEBQAwgZAxCzAJBgNVBAYTAlNFMRIwEAYD -VQQIEwlTdG9ja2hvbG0xDzANBgNVBAcTBkFsdnNqbzEMMAoGA1UEChMDRVRYMQ4w -DAYDVQQLEwVETi9TUDEXMBUGA1UEAxMOSm9ha2ltIEdyZWJlbm8xJTAjBgkqhkiG -9w0BCQEWFmpvY2tlQGVyaXguZXJpY3Nzb24uc2UwHhcNOTcwNzE1MTUzMzQxWhcN -MDMwMjIyMTUzMzQxWjCBkDELMAkGA1UEBhMCU0UxEjAQBgNVBAgTCVN0b2NraG9s -bTEPMA0GA1UEBxMGQWx2c2pvMQwwCgYDVQQKEwNFVFgxDjAMBgNVBAsTBUROL1NQ -MRcwFQYDVQQDEw5Kb2FraW0gR3JlYmVubzElMCMGCSqGSIb3DQEJARYWam9ja2VA -ZXJpeC5lcmljc3Nvbi5zZTBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQC/QaM49wSI -y+QsvG964zE9pD2UcnIV+MM/Wx6CCIipyqNcVx2I8INzfc1jNX9WczAA8Fa8tbgC -JwPKtPfu4S9tAgMBAAEwDQYJKoZIhvcNAQEEBQADQQAmXDY1CyJjzvQZX442kkHG -ic9QFY1UuVfzokzNMwlHYl1Qx9zaodx0cJCrcH5GF9O9LJbhhV77LzoxT1Q5wZp5 +MIIChzCCAfCgAwIBAgIGANUxXM9BMA0GCSqGSIb3DQEBBQUAMHoxDjAMBgNVBAMT +BW90cENBMSAwHgYJKoZIhvcNAQkBFhF0ZXN0ZXJAZXJsYW5nLm9yZzESMBAGA1UE +BxMJU3RvY2tob2xtMQswCQYDVQQGEwJTRTEPMA0GA1UEChMGZXJsYW5nMRQwEgYD +VQQLEwt0ZXN0aW5nIGRlcDAiGA8yMDEwMDkwMTAwMDAwMFoYDzIwMjUwODI4MDAw +MDAwWjB7MQ8wDQYDVQQDEwZzZXJ2ZXIxIDAeBgkqhkiG9w0BCQEWEXRlc3RlckBl +cmxhbmcub3JnMRIwEAYDVQQHEwlTdG9ja2hvbG0xCzAJBgNVBAYTAlNFMQ8wDQYD +VQQKEwZlcmxhbmcxFDASBgNVBAsTC3Rlc3RpbmcgZGVwMIGfMA0GCSqGSIb3DQEB +AQUAA4GNADCBiQKBgQCf4Htxr99lLs5W8QQw7jdakqyAkIjOW4aqH8sr4va4SvZ9 +Adq67k8jMHefCVZo+F8x4cwsBgB4aWzFIGBnvFTi6YsH27XW7f9O9IPCej8fdhRZ +4UAtNHa253buOWpDGla2JmIdkmfFvXFJycMIKbG5tYilVXoWKBMKmCwWaXz0nQID +AQABoxMwETAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBBQUAA4GBAGF5Pfwk +QDdwJup/mVITPxbBls4Yl7anDooUQsq8066lA1g54H/PRfXscGkyCFGh1ifXvf1L +psMRoBAdDHL/wSJplk3rRavkC94eBgnTFZmfKL6844g1j53yameiYL8IEVExYMBg +/XGyc0qwq57WT8B/K4aElrvlBlQ0wF3wN54M -----END CERTIFICATE----- diff --git a/lib/inets/test/httpd_basic_SUITE.erl b/lib/inets/test/httpd_basic_SUITE.erl index fef0a1f0f4..2d06f3e70c 100644 --- a/lib/inets/test/httpd_basic_SUITE.erl +++ b/lib/inets/test/httpd_basic_SUITE.erl @@ -19,6 +19,7 @@ %% -module(httpd_basic_SUITE). +-include_lib("kernel/include/file.hrl"). -include_lib("common_test/include/ct.hrl"). -include("inets_test_lib.hrl"). @@ -35,8 +36,11 @@ all() -> uri_too_long_414, header_too_long_413, erl_script_nocache_opt, + script_nocache, escaped_url_in_error_body, - slowdose + script_timeout, + slowdose, + keep_alive_timeout ]. groups() -> @@ -63,6 +67,7 @@ init_per_suite(Config) -> "~n Config: ~p", [Config]), ok = inets:start(), PrivDir = ?config(priv_dir, Config), + DataDir = ?config(data_dir, Config), Dummy = "<HTML> @@ -75,6 +80,21 @@ DUMMY </HTML>", DummyFile = filename:join([PrivDir,"dummy.html"]), + CgiDir = filename:join(PrivDir, "cgi-bin"), + ok = file:make_dir(CgiDir), + {CgiPrintEnv, CgiSleep} = case test_server:os_type() of + {win32, _} -> + {"printenv.bat", "cgi_sleep.exe"}; + _ -> + {"printenv.sh", "cgi_sleep"} + end, + lists:foreach( + fun(Cgi) -> + inets_test_lib:copy_file(Cgi, DataDir, CgiDir), + AbsCgi = filename:join([CgiDir, Cgi]), + {ok, FileInfo} = file:read_file_info(AbsCgi), + ok = file:write_file_info(AbsCgi, FileInfo#file_info{mode = 8#00755}) + end, [CgiPrintEnv, CgiSleep]), {ok, Fd} = file:open(DummyFile, [write]), ok = file:write(Fd, Dummy), ok = file:close(Fd), @@ -85,7 +105,8 @@ DUMMY {document_root, PrivDir}, {bind_address, "localhost"}], - [{httpd_conf, HttpdConf} | Config]. + [{httpd_conf, HttpdConf}, {cgi_dir, CgiDir}, + {cgi_printenv, CgiPrintEnv}, {cgi_sleep, CgiSleep} | Config]. %%-------------------------------------------------------------------- %% Function: end_per_suite(Config) -> _ @@ -205,6 +226,52 @@ erl_script_nocache_opt(Config) when is_list(Config) -> %%------------------------------------------------------------------------- %%------------------------------------------------------------------------- +script_nocache(doc) -> + ["Test nocache option for mod_cgi and mod_esi"]; +script_nocache(suite) -> + []; +script_nocache(Config) when is_list(Config) -> + Normal = {no_header, "cache-control"}, + NoCache = {header, "cache-control", "no-cache"}, + verify_script_nocache(Config, false, false, Normal, Normal), + verify_script_nocache(Config, true, false, NoCache, Normal), + verify_script_nocache(Config, false, true, Normal, NoCache), + verify_script_nocache(Config, true, true, NoCache, NoCache), + ok. + +verify_script_nocache(Config, CgiNoCache, EsiNoCache, CgiOption, EsiOption) -> + HttpdConf = ?config(httpd_conf, Config), + CgiScript = ?config(cgi_printenv, Config), + CgiDir = ?config(cgi_dir, Config), + {ok, Pid} = inets:start(httpd, [{port, 0}, + {script_alias, + {"/cgi-bin/", CgiDir ++ "/"}}, + {script_nocache, CgiNoCache}, + {erl_script_alias, + {"/cgi-bin/erl", [httpd_example,io]}}, + {erl_script_nocache, EsiNoCache} + | HttpdConf]), + Info = httpd:info(Pid), + Port = proplists:get_value(port, Info), + Address = proplists:get_value(bind_address, Info), + ok = httpd_test_lib:verify_request(ip_comm, Address, Port, node(), + "GET /cgi-bin/" ++ CgiScript ++ + " HTTP/1.0\r\n\r\n", + [{statuscode, 200}, + CgiOption, + {version, "HTTP/1.0"}]), + ok = httpd_test_lib:verify_request(ip_comm, Address, Port, node(), + "GET /cgi-bin/erl/httpd_example:get " + "HTTP/1.0\r\n\r\n", + [{statuscode, 200}, + EsiOption, + {version, "HTTP/1.0"}]), + inets:stop(httpd, Pid). + + +%%------------------------------------------------------------------------- +%%------------------------------------------------------------------------- + escaped_url_in_error_body(doc) -> ["Test Url-encoding see OTP-8940"]; escaped_url_in_error_body(suite) -> @@ -302,6 +369,63 @@ escaped_url_in_error_body(Config) when is_list(Config) -> inets:stop(httpd, Pid), tsp("escaped_url_in_error_body -> done"), ok. + + +%%------------------------------------------------------------------------- +%%------------------------------------------------------------------------- + +keep_alive_timeout(doc) -> + ["Test the keep_alive_timeout option"]; +keep_alive_timeout(suite) -> + []; +keep_alive_timeout(Config) when is_list(Config) -> + HttpdConf = ?config(httpd_conf, Config), + {ok, Pid} = inets:start(httpd, [{port, 0}, {keep_alive, true}, {keep_alive_timeout, 2} | HttpdConf]), + Info = httpd:info(Pid), + Port = proplists:get_value(port, Info), + _Address = proplists:get_value(bind_address, Info), + {ok, S} = gen_tcp:connect("localhost", Port, []), + receive + after 3000 -> + {error, closed} = gen_tcp:send(S, "hey") + end, + inets:stop(httpd, Pid). + +%%------------------------------------------------------------------------- +%%------------------------------------------------------------------------- + +script_timeout(doc) -> + ["Test the httpd script_timeout option"]; +script_timeout(suite) -> + []; +script_timeout(Config) when is_list(Config) -> + verify_script_timeout(Config, 20, 200), + verify_script_timeout(Config, 5, 403), + ok. + +verify_script_timeout(Config, ScriptTimeout, StatusCode) -> + HttpdConf = ?config(httpd_conf, Config), + CgiScript = ?config(cgi_sleep, Config), + CgiDir = ?config(cgi_dir, Config), + {ok, Pid} = inets:start(httpd, [{port, 0}, + {script_alias, + {"/cgi-bin/", CgiDir ++ "/"}}, + {script_timeout, ScriptTimeout} + | HttpdConf]), + Info = httpd:info(Pid), + Port = proplists:get_value(port, Info), + Address = proplists:get_value(bind_address, Info), + ok = httpd_test_lib:verify_request(ip_comm, Address, Port, node(), + "GET /cgi-bin/" ++ CgiScript ++ + " HTTP/1.0\r\n\r\n", + [{statuscode, StatusCode}, + {version, "HTTP/1.0"}]), + inets:stop(httpd, Pid). + + +%%------------------------------------------------------------------------- +%%------------------------------------------------------------------------- + slowdose(doc) -> ["Testing minimum bytes per second option"]; slowdose(Config) when is_list(Config) -> diff --git a/lib/inets/test/httpd_basic_SUITE_data/Makefile.src b/lib/inets/test/httpd_basic_SUITE_data/Makefile.src new file mode 100644 index 0000000000..9da2ed583f --- /dev/null +++ b/lib/inets/test/httpd_basic_SUITE_data/Makefile.src @@ -0,0 +1,14 @@ +CC = @CC@ +LD = @LD@ +CFLAGS = @CFLAGS@ -I@erl_include@ @DEFS@ +CROSSLDFLAGS = @CROSSLDFLAGS@ + +PROGS = cgi_sleep@exe@ + +all: $(PROGS) + +cgi_sleep@exe@: cgi_sleep@obj@ + $(LD) $(CROSSLDFLAGS) -o cgi_sleep cgi_sleep@obj@ @LIBS@ + +cgi_sleep@obj@: cgi_sleep.c + $(CC) -c -o cgi_sleep@obj@ $(CFLAGS) cgi_sleep.c diff --git a/lib/inets/test/httpd_basic_SUITE_data/cgi_sleep.c b/lib/inets/test/httpd_basic_SUITE_data/cgi_sleep.c new file mode 100644 index 0000000000..126bb23987 --- /dev/null +++ b/lib/inets/test/httpd_basic_SUITE_data/cgi_sleep.c @@ -0,0 +1,26 @@ +#include <stdlib.h> +#include <stdio.h> + +#ifdef __WIN32__ +#include <windows.h> +#include <fcntl.h> +#include <io.h> +#else +#include <unistd.h> +#endif + +int main(void) +{ + unsigned int seconds = 10; + +#ifdef __WIN32__ + Sleep(seconds * 1000); + _setmode(_fileno(stdout), _O_BINARY); +#else + sleep(seconds); +#endif + + printf("Content-type: text/plain\r\n\r\n"); + printf("Slept for %u seconds.\r\n", seconds); + exit(EXIT_SUCCESS); +} diff --git a/lib/inets/test/httpd_basic_SUITE_data/printenv.bat b/lib/inets/test/httpd_basic_SUITE_data/printenv.bat new file mode 120000 index 0000000000..1bc8e52059 --- /dev/null +++ b/lib/inets/test/httpd_basic_SUITE_data/printenv.bat @@ -0,0 +1 @@ +../httpd_SUITE_data/server_root/cgi-bin/printenv.bat
\ No newline at end of file diff --git a/lib/inets/test/httpd_basic_SUITE_data/printenv.sh b/lib/inets/test/httpd_basic_SUITE_data/printenv.sh new file mode 120000 index 0000000000..0136a3fa23 --- /dev/null +++ b/lib/inets/test/httpd_basic_SUITE_data/printenv.sh @@ -0,0 +1 @@ +../httpd_SUITE_data/server_root/cgi-bin/printenv.sh
\ No newline at end of file diff --git a/lib/inets/test/httpd_mod.erl b/lib/inets/test/httpd_mod.erl index df4ed6b179..7d3326fb65 100644 --- a/lib/inets/test/httpd_mod.erl +++ b/lib/inets/test/httpd_mod.erl @@ -842,6 +842,14 @@ cgi(Type, Port, Host, Node) -> {version, "HTTP/1.0"}]), %% tsp("cgi -> done"), + + %% Check "ScriptNoCache" directive (default: false) + ok = httpd_test_lib:verify_request(Type, Host, Port, Node, + "GET /cgi-bin/" ++ Script ++ + " HTTP/1.0\r\n\r\n", + [{statuscode, 200}, + {no_header, "cache-control"}, + {version, "HTTP/1.0"}]), ok. @@ -899,6 +907,13 @@ esi(Type, Port, Host, Node) -> " HTTP/1.0\r\n\r\n", [{statuscode, 302}, {version, "HTTP/1.0"}]), + %% Check "ErlScriptNoCache" directive (default: false) + ok = httpd_test_lib:verify_request(Type, Host, Port, Node, + "GET /cgi-bin/erl/httpd_example:get" + " HTTP/1.0\r\n\r\n", + [{statuscode, 200}, + {no_header, "cache-control"}, + {version, "HTTP/1.0"}]), ok. diff --git a/lib/inets/test/httpd_test_lib.erl b/lib/inets/test/httpd_test_lib.erl index 13584c50f6..3e82324a30 100644 --- a/lib/inets/test/httpd_test_lib.erl +++ b/lib/inets/test/httpd_test_lib.erl @@ -361,7 +361,7 @@ do_validate(Header, [{header, HeaderField, Value}|Rest],N,P) -> tsf({wrong_header_field_value, LowerHeaderField, Header}) end, do_validate(Header, Rest, N, P); -do_validate(Header,[{no_last_modified, HeaderField}|Rest],N,P) -> +do_validate(Header,[{no_header, HeaderField}|Rest],N,P) -> case lists:keysearch(HeaderField,1,Header) of {value,_} -> tsf({wrong_header_field_value, HeaderField, Header}); diff --git a/lib/inets/vsn.mk b/lib/inets/vsn.mk index 3f464c8684..36463d9388 100644 --- a/lib/inets/vsn.mk +++ b/lib/inets/vsn.mk @@ -18,7 +18,7 @@ # %CopyrightEnd% APPLICATION = inets -INETS_VSN = 5.9.5 +INETS_VSN = 5.9.6 PRE_VSN = APP_VSN = "$(APPLICATION)-$(INETS_VSN)$(PRE_VSN)" diff --git a/lib/kernel/doc/src/gen_sctp.xml b/lib/kernel/doc/src/gen_sctp.xml index dacea7a239..986260638d 100644 --- a/lib/kernel/doc/src/gen_sctp.xml +++ b/lib/kernel/doc/src/gen_sctp.xml @@ -496,9 +496,11 @@ orthogonal to the sets of TCP, UDP and generic INET options: only those options which are explicitly listed below are allowed for SCTP sockets. Options can be set on the socket using - <c>gen_sctp:open/1,2</c> or <c>inet:setopts/2</c>, - retrieved using <c>inet:getopts/2</c>, and when calling - <c>gen_sctp:connect/4,5</c> options can be changed.</p> + <seealso marker="#open/1"><c>gen_sctp:open/1,2</c></seealso> + or <seealso marker="inet#setopts/2"><c>inet:setopts/2</c></seealso>, + retrieved using <seealso marker="inet#getopts/2"><c>inet:getopts/2</c></seealso>, + and when calling <seealso marker="#connect/4"><c>gen_sctp:connect/4,5</c></seealso> + options can be changed.</p> <marker id="option-binary"></marker> <marker id="option-list"></marker> <taglist> @@ -507,7 +509,7 @@ <p>Determines the type of data returned from <c>gen_sctp:recv/1,2</c>.</p> <marker id="option-active"></marker> </item> - <tag><c>{active, true|false|once}</c></tag> + <tag><c>{active, true|false|once|N}</c></tag> <item> <list type="bulleted"> <item> @@ -524,11 +526,28 @@ </item> <item> <p>If <c>once</c>, only one message is automatically placed - in the message queue, after that the mode is automatically - re-set to passive. This provides flow control as well as + in the message queue, and after that the mode is automatically + reset to passive. This provides flow control as well as the possibility for the receiver to listen for its incoming SCTP data interleaved with other inter-process messages.</p> </item> + <item> + <p>If <c>active</c> is specified as an integer <c>N</c> in the + range -32768 to 32767 (inclusive), then that number is added to + the socket's count of the number of data messages to be + delivered to the controlling process. If the result of the + addition would be negative, the count is set to 0. Once the + count reaches 0, either through the delivery of messages or by + being explicitly set with <seealso + marker="inet#setopts/2">inet:setopts/2</seealso>, the socket's + mode is automatically reset to passive (<c>{active, + false}</c>) mode. When a socket in this active mode transitions to + passive mode, the message <c>{sctp_passive, Socket}</c> is sent + to the controlling process to notify it that if it wants to + receive more data messages from the socket, it must call + <seealso marker="inet#setopts/2">inet:setopts/2</seealso> to set + the socket back into an active mode.</p> + </item> </list> </item> <tag><c>{tos, integer()}</c></tag> diff --git a/lib/kernel/doc/src/gen_tcp.xml b/lib/kernel/doc/src/gen_tcp.xml index 7afd73f4bf..dbd0d3c815 100644 --- a/lib/kernel/doc/src/gen_tcp.xml +++ b/lib/kernel/doc/src/gen_tcp.xml @@ -148,6 +148,12 @@ do_recv(Sock, Bs) -> as messages:</p> <code type="none"> {tcp, Socket, Data}</code> + <p>If the socket is in <c>{active, N}</c> mode (see <seealso marker="inet#setopts/2"> + inet:setopts/2</seealso> for details) and its message counter + drops to 0, the following message is delivered to indicate that the + socket has transitioned to passive (<c>{active, false}</c>) mode:</p> + <code type="none"> +{tcp_passive, Socket}</code> <p>If the socket is closed, the following message is delivered:</p> <code type="none"> {tcp_closed, Socket}</code> diff --git a/lib/kernel/doc/src/gen_udp.xml b/lib/kernel/doc/src/gen_udp.xml index faca31e928..503725fe18 100644 --- a/lib/kernel/doc/src/gen_udp.xml +++ b/lib/kernel/doc/src/gen_udp.xml @@ -145,14 +145,23 @@ <seealso marker="inet#setopts/2">inet:setopts/2</seealso>.</p> </item> </taglist> - <p>The returned socket <c><anno>Socket</anno></c> is used to send packets - from this port with <c>send/4</c>. When UDP packets arrive at - the opened port, they are delivered as messages:</p> + <p>The returned socket <c><anno>Socket</anno></c> is used to send + packets from this port with <c>send/4</c>. When UDP packets arrive + at the opened port, if the socket is in an active mode the packets + are delivered as messages to the controlling process:</p> <code type="none"> {udp, Socket, IP, InPortNo, Packet}</code> - <p>Note that arriving UDP packets that are longer than + <p>If the socket is not in an active mode, data can be + retrieved via the <seealso marker="#recv/2">recv/2,3</seealso> calls. + Note that arriving UDP packets that are longer than the receive buffer option specifies, might be truncated without warning.</p> + <p>When a socket in <c>{active, N}</c> mode (see <seealso marker="inet#setopts/2"> + inet:setopts/2</seealso> for details) transitions to passive + (<c>{active, false}</c>) mode, the controlling process is notified by a + message of the following form:</p> + <code type="none"> +{udp_passive, Socket}</code> <p><c>IP</c> and <c>InPortNo</c> define the address from which <c>Packet</c> came. <c>Packet</c> is a list of bytes if the option <c>list</c> was specified. <c>Packet</c> is a diff --git a/lib/kernel/doc/src/inet.xml b/lib/kernel/doc/src/inet.xml index 4a3796a15b..fb8bf32978 100644 --- a/lib/kernel/doc/src/inet.xml +++ b/lib/kernel/doc/src/inet.xml @@ -456,47 +456,66 @@ fe80::204:acff:fe17:bf38 <p>Sets one or more options for a socket. The following options are available:</p> <taglist> - <tag><c>{active, true | false | once}</c></tag> + <tag><c>{active, true | false | once | N}</c></tag> <item> <p>If the value is <c>true</c>, which is the default, everything received from the socket will be sent as messages to the receiving process. If the value is <c>false</c> (passive mode), the process must explicitly - receive incoming data by calling <c>gen_tcp:recv/2,3</c> - or <c>gen_udp:recv/2,3</c> (depending on the type of - socket).</p> + receive incoming data by calling + <seealso marker="gen_tcp#recv/2"><c>gen_tcp:recv/2,3</c></seealso>, + <seealso marker="gen_udp#recv/2"><c>gen_udp:recv/2,3</c></seealso> + or <seealso marker="gen_sctp#recv/1"><c>gen_sctp:recv/1,2</c></seealso> + (depending on the type of socket).</p> <p>If the value is <c>once</c> (<c>{active, once}</c>), <em>one</em> data message from the socket will be sent to the process. To receive one more message, <c>setopts/2</c> must be called again with the <c>{active, once}</c> option.</p> - <p>When using <c>{active, once}</c>, the socket changes - behaviour automatically when data is received. This can - sometimes be confusing in combination with connection - oriented sockets (i.e. <c>gen_tcp</c>) as a socket with - <c>{active, false}</c> behaviour reports closing + <p>If the value is an integer <c>N</c> in the range -32768 to 32767 + (inclusive), the value is added to the socket's count of data + messages sent to the controlling process. A socket's default + message count is 0. If a negative value is specified and its + magnitude is equal to or greater than the socket's current + message count, the socket's message count is set to 0. Once + the socket's message count reaches 0, either due to sending + received data messages to the process or by being explicitly set, + the process is then notified by a special message, specific to + the type of socket, that the socket has entered passive + mode. Once the socket enters passive mode, to receive more + messages <c>setopts/2</c> must be called again to set the + socket back into an active mode.</p> + <p>When using <c>{active, once}</c> or <c>{active, N}</c>, the + socket changes behaviour automatically when data is received. + This can sometimes be confusing in combination with + connection-oriented sockets (i.e. <c>gen_tcp</c>) as a socket + with <c>{active, false}</c> behaviour reports closing differently than a socket with <c>{active, true}</c> behaviour. To make programming easier, a socket where the peer closed and this was detected while in <c>{active, false}</c> mode, will still generate the message - <c>{tcp_closed,Socket}</c> when set to <c>{active, once}</c> or <c>{active, true}</c> mode. It is therefore + <c>{tcp_closed,Socket}</c> when set to <c>{active, once}</c>, + <c>{active, true}</c> or <c>{active, N}</c> mode. It is therefore safe to assume that the message <c>{tcp_closed,Socket}</c>, possibly followed by socket port termination (depending on the <c>exit_on_close</c> option) will eventually appear when a socket changes back and forth between <c>{active, true}</c> and - <c>{active, false}</c> mode. However, + <c>{active, false}</c> mode. However, <em>when</em> peer closing is detected is all up to the underlying TCP/IP stack and protocol.</p> - <p>Note that <c>{active,true}</c> mode provides no flow + <p>Note that <c>{active, true}</c> mode provides no flow control; a fast sender could easily overflow the - receiver with incoming messages. Use active mode only if + receiver with incoming messages. The same is true of + <c>{active, N}</c> mode while the message count is greater + than zero. Use active mode only if your high-level protocol provides its own flow control (for instance, acknowledging received messages) or the - amount of data exchanged is small. <c>{active,false}</c> - mode or use of the <c>{active, once}</c> mode provides - flow control; the other side will not be able send + amount of data exchanged is small. <c>{active, false}</c> + mode, use of the <c>{active, once}</c> mode or <c>{active, N}</c> + mode with values of <c>N</c> appropriate for the application + provides flow control; the other side will not be able send faster than the receiver can read.</p> </item> @@ -722,6 +741,59 @@ fe80::204:acff:fe17:bf38 <p>Received <c>Packet</c> is delivered as defined by Mode.</p> </item> + <tag><c>{netns, Namespace :: file:filename_all()}</c></tag> + <item> + <p>Set a network namespace for the socket. The <c>Namespace</c> + parameter is a filename defining the namespace for example + <c>"/var/run/netns/example"</c> typically created by the command + <c>ip netns add example</c>. This option must be used in a + function call that creates a socket i.e + <seealso marker="gen_tcp#connect/3"> + gen_tcp:connect/3,4</seealso>, + <seealso marker="gen_tcp#listen/2"> + gen_tcp:listen/2</seealso>, + <seealso marker="gen_udp#open/1"> + gen_udp:open/1,2</seealso> or + <seealso marker="gen_sctp#open/0"> + gen_sctp:open/0-2</seealso>. + </p> + <p>This option uses the Linux specific syscall + <c>setns()</c> such as in Linux kernel 3.0 or later + and therefore only exists when the runtime system + has been compiled for such an operating system. + </p> + <p> + The virtual machine also needs elevated privileges either + running as superuser or (for Linux) having the capability + <c>CAP_SYS_ADMIN</c> according to the documentation for setns(2). + However, during testing also <c>CAP_SYS_PTRACE</c> + and <c>CAP_DAC_READ_SEARCH</c> has proven to be necessary. + Example:<code> +setcap cap_sys_admin,cap_sys_ptrace,cap_dac_read_search+epi beam.smp +</code> + Note also that the filesystem containing the virtual machine + executable (<c>beam.smp</c> in the example above) has to be local, + mounted without the <c>nosetuid</c> flag, + support extended attributes and that + the kernel has to support file capabilities. + All this runs out of the box on at least Ubuntu 12.04 LTS, + except that SCTP sockets appears to not support + network namespaces. + </p> + <p>The <c>Namespace</c> is a file name and is encoded + and decoded as discussed in + <seealso marker="file">file</seealso> + except that the emulator flag <c>+fnu</c> is ignored and + <seealso marker="#getopts/2">getopts/2</seealso> + for this option will return a binary for the filename + if the stored filename can not be decoded, + which should only happen if you set the option using a binary + that can not be decoded with the emulator's filename encoding: + <seealso marker="file#native_name_encoding/0"> + file:native_name_encoding/0</seealso>. + </p> + </item> + <tag><c>list</c></tag> <item> <p>Received <c>Packet</c> is delivered as a list.</p> diff --git a/lib/kernel/doc/src/notes.xml b/lib/kernel/doc/src/notes.xml index 6b703b7c2b..6cdc3a9d17 100644 --- a/lib/kernel/doc/src/notes.xml +++ b/lib/kernel/doc/src/notes.xml @@ -30,6 +30,66 @@ </header> <p>This document describes the changes made to the Kernel application.</p> +<section><title>Kernel 2.16.3</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Fix indentation of User switch command help in Erlang + shell. Thanks to Sylvain Benner.</p> + <p> + Own Id: OTP-11209</p> + </item> + </list> + </section> + + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + The previous undocumented function ntoa/1 has been added + to inet docs and exported in the inet module.</p> + <p> + Own Id: OTP-10676 Aux Id: OTP-10314 </p> + </item> + <item> + <p> + Fix typo in abcast() function comment. Thanks to Johannes + Weissl.</p> + <p> + Own Id: OTP-11219</p> + </item> + <item> + <p> + Add application:ensure_all_started/1-2. Thanks to Fred + Hebert.</p> + <p> + Own Id: OTP-11250</p> + </item> + <item> + <p> + Make edlin understand a few important control keys. + Thanks to Stefan Zegenhagen.</p> + <p> + Own Id: OTP-11251</p> + </item> + <item> + <p> + Cleanup of hipe_unified_loader, eliminating uses of + is_subtype/2 in specs, change module-local void functions + to return 'ok' instead of [] and made sure there are no + dialyzer warnings with --Wunmatched_returns. Thanks to + Kostis Sagonas.</p> + <p> + Own Id: OTP-11301</p> + </item> + </list> + </section> + +</section> + <section><title>Kernel 2.16.2</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/kernel/src/gen_sctp.erl b/lib/kernel/src/gen_sctp.erl index 0d005eb651..23a698f9b2 100644 --- a/lib/kernel/src/gen_sctp.erl +++ b/lib/kernel/src/gen_sctp.erl @@ -36,7 +36,7 @@ -type assoc_id() :: term(). -type option() :: - {active, true | false | once} | + {active, true | false | once | -32768..32767} | {buffer, non_neg_integer()} | {dontroute, boolean()} | {high_msgq_watermark, pos_integer()} | diff --git a/lib/kernel/src/gen_tcp.erl b/lib/kernel/src/gen_tcp.erl index 96026aa428..bc8ffbe5e3 100644 --- a/lib/kernel/src/gen_tcp.erl +++ b/lib/kernel/src/gen_tcp.erl @@ -30,7 +30,7 @@ -include("file.hrl"). -type option() :: - {active, true | false | once} | + {active, true | false | once | -32768..32767} | {buffer, non_neg_integer()} | {delay_send, boolean()} | {deliver, port | term} | diff --git a/lib/kernel/src/gen_udp.erl b/lib/kernel/src/gen_udp.erl index e82b11d2ef..70dceb3679 100644 --- a/lib/kernel/src/gen_udp.erl +++ b/lib/kernel/src/gen_udp.erl @@ -26,7 +26,7 @@ -include("inet_int.hrl"). -type option() :: - {active, true | false | once} | + {active, true | false | once | -32768..32767} | {add_membership, {inet:ip_address(), inet:ip_address()}} | {broadcast, boolean()} | {buffer, non_neg_integer()} | diff --git a/lib/kernel/src/hipe_unified_loader.erl b/lib/kernel/src/hipe_unified_loader.erl index cc51b5ae07..e111cb800e 100644 --- a/lib/kernel/src/hipe_unified_loader.erl +++ b/lib/kernel/src/hipe_unified_loader.erl @@ -85,7 +85,7 @@ chunk_name(Architecture) -> %%======================================================================== -spec load_native_code(Mod, binary()) -> 'no_native' | {'module', Mod} - when is_subtype(Mod, atom()). + when Mod :: atom(). %% @doc %% Loads the native code of a module Mod. %% Returns {module,Mod} on success (for compatibility with @@ -148,8 +148,8 @@ version_check(Version, Mod) when is_atom(Mod) -> %%======================================================================== --spec load_module(Mod, binary(), _) -> 'bad_crc' | {'module',Mod} - when is_subtype(Mod,atom()). +-spec load_module(Mod, binary(), _) -> 'bad_crc' | {'module', Mod} + when Mod :: atom(). load_module(Mod, Bin, Beam) -> erlang:system_flag(multi_scheduling, block), try @@ -169,8 +169,8 @@ load_module(Mod, Bin, Beam, OldReferencesToPatch) -> %%======================================================================== --spec load(Mod, binary()) -> 'bad_crc' | {'module',Mod} - when is_subtype(Mod,atom()). +-spec load(Mod, binary()) -> 'bad_crc' | {'module', Mod} when Mod :: atom(). + load(Mod, Bin) -> erlang:system_flag(multi_scheduling, block), try @@ -204,15 +204,17 @@ load_common(Mod, Bin, Beam, OldReferencesToPatch) -> bad_crc; true -> %% Create data segment - {ConstAddr,ConstMap2} = create_data_segment(ConstAlign, ConstSize, ConstMap), + {ConstAddr,ConstMap2} = + create_data_segment(ConstAlign, ConstSize, ConstMap), %% Find callees for which we may need trampolines. CalleeMFAs = find_callee_mfas(Refs), %% Write the code to memory. - {CodeAddress,Trampolines} = enter_code(CodeSize, CodeBinary, CalleeMFAs, Mod, Beam), + {CodeAddress,Trampolines} = + enter_code(CodeSize, CodeBinary, CalleeMFAs, Mod, Beam), %% Construct CalleeMFA-to-trampoline mapping. TrampolineMap = mk_trampoline_map(CalleeMFAs, Trampolines), %% Patch references to code labels in data seg. - patch_consts(LabelMap, ConstAddr, CodeAddress), + ok = patch_consts(LabelMap, ConstAddr, CodeAddress), %% Find out which functions are being loaded (and where). %% Note: Addresses are sorted descending. {MFAs,Addresses} = exports(ExportMap, CodeAddress), @@ -221,7 +223,7 @@ load_common(Mod, Bin, Beam, OldReferencesToPatch) -> ok = remove_refs_from(MFAs), %% Patch all dynamic references in the code. %% Function calls, Atoms, Constants, System calls - patch(Refs, CodeAddress, ConstMap2, Addresses, TrampolineMap), + ok = patch(Refs, CodeAddress, ConstMap2, Addresses, TrampolineMap), %% Tell the system where the loaded funs are. %% (patches the BEAM code to redirect to native.) case Beam of @@ -324,7 +326,7 @@ trampoline_map_get(MFA, Map) -> gb_trees:get(MFA, Map). trampoline_map_lookup(_, []) -> []; % archs not using trampolines trampoline_map_lookup(Primop, Map) -> case gb_trees:lookup(Primop, Map) of - {value,X} -> X; + {value, X} -> X; _ -> [] end. @@ -371,7 +373,7 @@ offsets_to_addresses(Os, Base) -> find_closure_patches([{Type,Refs} | Rest]) -> case ?EXT2PATCH_TYPE(Type) of load_address -> - find_closure_refs(Refs,Rest); + find_closure_refs(Refs, Rest); _ -> find_closure_patches(Rest) end; @@ -406,16 +408,17 @@ export_funs([FunDef | Addresses]) -> hipe_bifs:set_native_address(MFA, Address, IsClosure), export_funs(Addresses); export_funs([]) -> - true. + ok. export_funs(Mod, Beam, Addresses, ClosuresToPatch) -> - Fs = [{F,A,Address} || #fundef{address=Address, mfa={_M,F,A}} <- Addresses], - code:make_stub_module(Mod, Beam, {Fs,ClosuresToPatch}). + Fs = [{F,A,Address} || #fundef{address=Address, mfa={_M,F,A}} <- Addresses], + Mod = code:make_stub_module(Mod, Beam, {Fs,ClosuresToPatch}), + ok. %%======================================================================== %% Patching %% @spec patch(refs(), BaseAddress::integer(), ConstAndZone::term(), -%% Addresses::term(), TrampolineMap::term()) -> term() +%% Addresses::term(), TrampolineMap::term()) -> 'ok'. %% @type refs()=[{RefType::integer(), Reflist::reflist()} | refs()] %% %% @type reflist()= [{Data::term(), Offsets::offests()}|reflist()] @@ -428,7 +431,7 @@ export_funs(Mod, Beam, Addresses, ClosuresToPatch) -> %% patch([{Type,SortedRefs}|Rest], CodeAddress, ConstMap2, Addresses, TrampolineMap) -> - ?debug_msg("Patching ~w at [~w+offset] with ~w\n", + ?debug_msg("Patching ~w at [~w+offset] with ~w\n", [Type,CodeAddress,SortedRefs]), case ?EXT2PATCH_TYPE(Type) of call_local -> @@ -439,7 +442,7 @@ patch([{Type,SortedRefs}|Rest], CodeAddress, ConstMap2, Addresses, TrampolineMap patch_all(Other, SortedRefs, CodeAddress, {ConstMap2,CodeAddress}, Addresses) end, patch(Rest, CodeAddress, ConstMap2, Addresses, TrampolineMap); -patch([], _, _, _, _) -> true. +patch([], _, _, _, _) -> ok. %%---------------------------------------------------------------- %% Handle a 'call_local' or 'call_remote' patch. @@ -461,14 +464,14 @@ patch_call([{DestMFA,Offsets}|SortedRefs], BaseAddress, Addresses, RemoteOrLocal end, patch_call(SortedRefs, BaseAddress, Addresses, RemoteOrLocal, TrampolineMap); patch_call([], _, _, _, _) -> - true. + ok. patch_bif_call_list([Offset|Offsets], BaseAddress, BifAddress, Trampoline) -> CallAddress = BaseAddress+Offset, ?ASSERT(assert_local_patch(CallAddress)), patch_call_insn(CallAddress, BifAddress, Trampoline), patch_bif_call_list(Offsets, BaseAddress, BifAddress, Trampoline); -patch_bif_call_list([], _, _, _) -> []. +patch_bif_call_list([], _, _, _) -> ok. patch_mfa_call_list([Offset|Offsets], BaseAddress, DestMFA, DestAddress, Addresses, RemoteOrLocal, Trampoline) -> CallAddress = BaseAddress+Offset, @@ -476,7 +479,7 @@ patch_mfa_call_list([Offset|Offsets], BaseAddress, DestMFA, DestAddress, Address ?ASSERT(assert_local_patch(CallAddress)), patch_call_insn(CallAddress, DestAddress, Trampoline), patch_mfa_call_list(Offsets, BaseAddress, DestMFA, DestAddress, Addresses, RemoteOrLocal, Trampoline); -patch_mfa_call_list([], _, _, _, _, _, _) -> []. +patch_mfa_call_list([], _, _, _, _, _, _) -> ok. patch_call_insn(CallAddress, DestAddress, Trampoline) -> %% This assertion is false when we're called from redirect/2. @@ -489,7 +492,7 @@ patch_call_insn(CallAddress, DestAddress, Trampoline) -> patch_all(Type, [{Dest,Offsets}|Rest], BaseAddress, ConstAndZone, Addresses)-> patch_all_offsets(Type, Dest, Offsets, BaseAddress, ConstAndZone, Addresses), patch_all(Type, Rest, BaseAddress, ConstAndZone, Addresses); -patch_all(_, [], _, _, _) -> true. +patch_all(_, [], _, _, _) -> ok. patch_all_offsets(Type, Data, [Offset|Offsets], BaseAddress, ConstAndZone, Addresses) -> @@ -499,7 +502,7 @@ patch_all_offsets(Type, Data, [Offset|Offsets], BaseAddress, patch_offset(Type, Data, Address, ConstAndZone, Addresses), ?debug_msg("Patching done\n",[]), patch_all_offsets(Type, Data, Offsets, BaseAddress, ConstAndZone, Addresses); -patch_all_offsets(_, _, [], _, _, _) -> true. +patch_all_offsets(_, _, [], _, _, _) -> ok. %%---------------------------------------------------------------- %% Handle any patch type except 'call_local' or 'call_remote'. diff --git a/lib/kernel/src/inet.erl b/lib/kernel/src/inet.erl index 7a516c3947..ea06a07bb3 100644 --- a/lib/kernel/src/inet.erl +++ b/lib/kernel/src/inet.erl @@ -120,6 +120,17 @@ 'addr' | 'broadaddr' | 'dstaddr' | 'mtu' | 'netmask' | 'flags' |'hwaddr'. +-type if_getopt_result() :: + {'addr', ip_address()} | + {'broadaddr', ip_address()} | + {'dstaddr', ip_address()} | + {'mtu', non_neg_integer()} | + {'netmask', ip_address()} | + {'flags', ['up' | 'down' | 'broadcast' | 'no_broadcast' | + 'pointtopoint' | 'no_pointtopoint' | + 'running' | 'multicast' | 'loopback']} | + {'hwaddr', ether_address()}. + -type address_family() :: 'inet' | 'inet6'. -type socket_protocol() :: 'tcp' | 'udp' | 'sctp'. -type socket_type() :: 'stream' | 'dgram' | 'seqpacket'. @@ -200,7 +211,14 @@ send(Socket, Packet) -> Options :: [socket_setopt()]. setopts(Socket, Opts) -> - prim_inet:setopts(Socket, Opts). + SocketOpts = + [case Opt of + {netns,NS} -> + {netns,filename2binary(NS)}; + _ -> + Opt + end || Opt <- Opts], + prim_inet:setopts(Socket, SocketOpts). -spec getopts(Socket, Options) -> {'ok', OptionValues} | {'error', posix()} when @@ -209,7 +227,18 @@ setopts(Socket, Opts) -> OptionValues :: [socket_setopt()]. getopts(Socket, Opts) -> - prim_inet:getopts(Socket, Opts). + case prim_inet:getopts(Socket, Opts) of + {ok,OptionValues} -> + {ok, + [case OptionValue of + {netns,Bin} -> + {netns,binary2filename(Bin)}; + _ -> + OptionValue + end || OptionValue <- OptionValues]}; + Other -> + Other + end. -spec getifaddrs(Socket :: socket()) -> {'ok', [string()]} | {'error', posix()}. @@ -248,13 +277,13 @@ getiflist() -> -spec ifget(Socket :: socket(), Name :: string() | atom(), Opts :: [if_getopt()]) -> - {'ok', [if_setopt()]} | {'error', posix()}. + {'ok', [if_getopt_result()]} | {'error', posix()}. ifget(Socket, Name, Opts) -> prim_inet:ifget(Socket, Name, Opts). -spec ifget(Name :: string() | atom(), Opts :: [if_getopt()]) -> - {'ok', [if_setopt()]} | {'error', posix()}. + {'ok', [if_getopt_result()]} | {'error', posix()}. ifget(Name, Opts) -> withsocket(fun(S) -> prim_inet:ifget(S, Name, Opts) end). @@ -641,6 +670,17 @@ con_opt([Opt | Opts], R, As) -> {tcp_module,_} -> con_opt(Opts, R, As); inet -> con_opt(Opts, R, As); inet6 -> con_opt(Opts, R, As); + {netns,NS} -> + BinNS = filename2binary(NS), + case prim_inet:is_sockopt_val(netns, BinNS) of + true -> + con_opt(Opts, R#connect_opts { fd = [{netns,BinNS}] }, As); + false -> + {error, badarg} + end; + {active,N} when is_integer(N), N < 32768, N >= -32768 -> + NOpts = lists:keydelete(active, 1, R#connect_opts.opts), + con_opt(Opts, R#connect_opts { opts = [{active,N}|NOpts] }, As); {Name,Val} when is_atom(Name) -> con_add(Name, Val, R, Opts, As); _ -> {error, badarg} end; @@ -699,6 +739,17 @@ list_opt([Opt | Opts], R, As) -> {tcp_module,_} -> list_opt(Opts, R, As); inet -> list_opt(Opts, R, As); inet6 -> list_opt(Opts, R, As); + {netns,NS} -> + BinNS = filename2binary(NS), + case prim_inet:is_sockopt_val(netns, BinNS) of + true -> + list_opt(Opts, R#listen_opts { fd = [{netns,BinNS}] }, As); + false -> + {error, badarg} + end; + {active,N} when is_integer(N), N < 32768, N >= -32768 -> + NOpts = lists:keydelete(active, 1, R#listen_opts.opts), + list_opt(Opts, R#listen_opts { opts = [{active,N}|NOpts] }, As); {Name,Val} when is_atom(Name) -> list_add(Name, Val, R, Opts, As); _ -> {error, badarg} end; @@ -745,6 +796,17 @@ udp_opt([Opt | Opts], R, As) -> {udp_module,_} -> udp_opt(Opts, R, As); inet -> udp_opt(Opts, R, As); inet6 -> udp_opt(Opts, R, As); + {netns,NS} -> + BinNS = filename2binary(NS), + case prim_inet:is_sockopt_val(netns, BinNS) of + true -> + list_opt(Opts, R#udp_opts { fd = [{netns,BinNS}] }, As); + false -> + {error, badarg} + end; + {active,N} when is_integer(N), N < 32768, N >= -32768 -> + NOpts = lists:keydelete(active, 1, R#udp_opts.opts), + udp_opt(Opts, R#udp_opts { opts = [{active,N}|NOpts] }, As); {Name,Val} when is_atom(Name) -> udp_add(Name, Val, R, Opts, As); _ -> {error, badarg} end; @@ -763,7 +825,7 @@ udp_add(Name, Val, R, Opts, As) -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Currently supported options include: % (*) {mode, list|binary} or just list|binary -% (*) {active, true|false|once} +% (*) {active, true|false|once|N} % (*) {sctp_module, inet_sctp|inet6_sctp} or just inet|inet6 % (*) options set via setsockopt. % The full list is below in sctp_options/0 . @@ -814,6 +876,20 @@ sctp_opt([Opt|Opts], Mod, R, As) -> {sctp_module,_} -> sctp_opt (Opts, Mod, R, As); % Done with inet -> sctp_opt (Opts, Mod, R, As); % Done with inet6 -> sctp_opt (Opts, Mod, R, As); % Done with + {netns,NS} -> + BinNS = filename2binary(NS), + case prim_inet:is_sockopt_val(netns, BinNS) of + true -> + sctp_opt( + Opts, Mod, + R#sctp_opts { fd = [{netns,BinNS}] }, + As); + false -> + {error, badarg} + end; + {active,N} when is_integer(N), N < 32768, N >= -32768 -> + NOpts = lists:keydelete(active, 1, R#sctp_opts.opts), + sctp_opt(Opts, Mod, R#sctp_opts { opts = [{active,N}|NOpts] }, As); {Name,Val} -> sctp_opt (Opts, Mod, R, As, Name, Val); _ -> {error,badarg} end; @@ -858,6 +934,39 @@ add_opt(Name, Val, Opts, As) -> end. +%% Passthrough all unknown - catch type errors later +filename2binary(List) when is_list(List) -> + OutEncoding = file:native_name_encoding(), + try unicode:characters_to_binary(List, unicode, OutEncoding) of + Bin when is_binary(Bin) -> + Bin; + _ -> + List + catch + error:badarg -> + List + end; +filename2binary(Bin) -> + Bin. + +binary2filename(Bin) -> + InEncoding = file:native_name_encoding(), + case unicode:characters_to_list(Bin, InEncoding) of + Filename when is_list(Filename) -> + Filename; + _ -> + %% For getopt/setopt of netns this should only happen if + %% a binary with wrong encoding was used when setting the + %% option, hence the user shall eat his/her own medicine. + %% + %% I.e passthrough here too for now. + %% Future usecases will most probably not want this, + %% rather Unicode error or warning + %% depending on emulator flag instead. + Bin + end. + + translate_ip(any, inet) -> {0,0,0,0}; translate_ip(loopback, inet) -> {127,0,0,1}; translate_ip(any, inet6) -> {0,0,0,0,0,0,0,0}; @@ -1070,7 +1179,7 @@ gethostbyaddr_tm_native(Addr, Timer, Opts) -> Result -> Result end. --spec open(Fd :: integer(), +-spec open(Fd_or_OpenOpts :: integer() | list(), Addr :: ip_address(), Port :: port_number(), Opts :: [socket_setopt()], @@ -1080,8 +1189,14 @@ gethostbyaddr_tm_native(Addr, Timer, Opts) -> Module :: atom()) -> {'ok', socket()} | {'error', posix()}. -open(Fd, Addr, Port, Opts, Protocol, Family, Type, Module) when Fd < 0 -> - case prim_inet:open(Protocol, Family, Type) of +open(FdO, Addr, Port, Opts, Protocol, Family, Type, Module) + when is_integer(FdO), FdO < 0; + is_list(FdO) -> + OpenOpts = + if is_list(FdO) -> FdO; + true -> [] + end, + case prim_inet:open(Protocol, Family, Type, OpenOpts) of {ok,S} -> case prim_inet:setopts(S, Opts) of ok -> @@ -1104,7 +1219,8 @@ open(Fd, Addr, Port, Opts, Protocol, Family, Type, Module) when Fd < 0 -> Error -> Error end; -open(Fd, _Addr, _Port, Opts, Protocol, Family, Type, Module) -> +open(Fd, _Addr, _Port, Opts, Protocol, Family, Type, Module) + when is_integer(Fd) -> fdopen(Fd, Opts, Protocol, Family, Type, Module). bindx(S, [Addr], Port0) -> diff --git a/lib/kernel/src/inet_int.hrl b/lib/kernel/src/inet_int.hrl index 67a99913a1..024a5fd3b6 100644 --- a/lib/kernel/src/inet_int.hrl +++ b/lib/kernel/src/inet_int.hrl @@ -46,6 +46,7 @@ -define(INET_PASSIVE, 0). -define(INET_ACTIVE, 1). -define(INET_ONCE, 2). % Active once then passive +-define(INET_MULTI, 3). % Active N then passive %% state codes (getstatus, INET_REQ_GETSTATUS) -define(INET_F_OPEN, 16#0001). @@ -143,6 +144,7 @@ -define(INET_LOPT_TCP_SEND_TIMEOUT_CLOSE, 35). -define(INET_LOPT_MSGQ_HIWTRMRK, 36). -define(INET_LOPT_MSGQ_LOWTRMRK, 37). +-define(INET_LOPT_NETNS, 38). % Specific SCTP options: separate range: -define(SCTP_OPT_RTOINFO, 100). -define(SCTP_OPT_ASSOCINFO, 101). diff --git a/lib/kernel/test/gen_sctp_SUITE.erl b/lib/kernel/test/gen_sctp_SUITE.erl index e89cb44797..6dad52395b 100644 --- a/lib/kernel/test/gen_sctp_SUITE.erl +++ b/lib/kernel/test/gen_sctp_SUITE.erl @@ -35,8 +35,9 @@ open_unihoming_ipv6_socket/1, open_multihoming_ipv6_socket/1, open_multihoming_ipv4_and_ipv6_socket/1, - basic_stream/1, xfer_stream_min/1, peeloff_active_once/1, - peeloff_active_true/1, buffers/1]). + basic_stream/1, xfer_stream_min/1, active_n/1, + peeloff_active_once/1, peeloff_active_true/1, peeloff_active_n/1, + buffers/1]). suite() -> [{ct_hooks,[ts_install_cth]}]. @@ -46,9 +47,9 @@ all() -> open_multihoming_ipv4_socket, open_unihoming_ipv6_socket, open_multihoming_ipv6_socket, - open_multihoming_ipv4_and_ipv6_socket, + open_multihoming_ipv4_and_ipv6_socket, active_n, basic_stream, xfer_stream_min, peeloff_active_once, - peeloff_active_true, buffers]. + peeloff_active_true, peeloff_active_n, buffers]. groups() -> []. @@ -767,6 +768,106 @@ implicit_inet6(S1, Addr) -> end, ?line ok = gen_sctp:close(S2). +active_n(doc) -> + "Verify {active,N} socket management"; +active_n(suite) -> + []; +active_n(Config) when is_list(Config) -> + N = 3, + S1 = ok(gen_sctp:open([{active,N}])), + [{active,N}] = ok(inet:getopts(S1, [active])), + ok = inet:setopts(S1, [{active,-N}]), + receive + {sctp_passive, S1} -> ok + after + 5000 -> + exit({error,sctp_passive_failure}) + end, + [{active,false}] = ok(inet:getopts(S1, [active])), + ok = inet:setopts(S1, [{active,0}]), + receive + {sctp_passive, S1} -> ok + after + 5000 -> + exit({error,sctp_passive_failure}) + end, + ok = inet:setopts(S1, [{active,32767}]), + {error,einval} = inet:setopts(S1, [{active,1}]), + {error,einval} = inet:setopts(S1, [{active,-32769}]), + ok = inet:setopts(S1, [{active,-32768}]), + receive + {sctp_passive, S1} -> ok + after + 5000 -> + exit({error,sctp_passive_failure}) + end, + [{active,false}] = ok(inet:getopts(S1, [active])), + ok = inet:setopts(S1, [{active,N}]), + ok = inet:setopts(S1, [{active,true}]), + [{active,true}] = ok(inet:getopts(S1, [active])), + receive + _ -> exit({error,active_n}) + after + 0 -> + ok + end, + ok = inet:setopts(S1, [{active,N}]), + ok = inet:setopts(S1, [{active,once}]), + [{active,once}] = ok(inet:getopts(S1, [active])), + receive + _ -> exit({error,active_n}) + after + 0 -> + ok + end, + {error,einval} = inet:setopts(S1, [{active,32768}]), + ok = inet:setopts(S1, [{active,false}]), + [{active,false}] = ok(inet:getopts(S1, [active])), + ok = gen_sctp:listen(S1, true), + S1Port = ok(inet:port(S1)), + S2 = ok(gen_sctp:open(0, [{active,false}])), + Assoc = ok(gen_sctp:connect(S2, "localhost", S1Port, [])), + ok = inet:setopts(S1, [{active,N}]), + [{active,N}] = ok(inet:getopts(S1, [active])), + LoopFun = fun(Count, Count, _Fn) -> + receive + {sctp_passive,S1} -> + ok + after + 5000 -> + exit({error,timeout}) + end; + (I, Count, Fn) -> + Msg = list_to_binary("message "++integer_to_list(I)), + ok = gen_sctp:send(S2, Assoc, 0, Msg), + receive + {sctp,S1,_,_,{[SR],Msg}} when is_record(SR, sctp_sndrcvinfo) -> + Fn(I+1, Count, Fn); + {sctp,S1,_,_,_} -> + %% ignore non-data messages + ok = inet:setopts(S1, [{active,1}]), + Fn(I, Count, Fn); + Other -> + exit({unexpected, Other}) + after + 5000 -> + exit({error,timeout}) + end + end, + ok = LoopFun(1, N, LoopFun), + S3 = ok(gen_sctp:open([{active,0}])), + receive + {sctp_passive,S3} -> + [{active,false}] = ok(inet:getopts(S3, [active])) + after + 5000 -> + exit({error,udp_passive}) + end, + ok = gen_sctp:close(S3), + ok = gen_sctp:close(S2), + ok = gen_sctp:close(S1), + ok. + basic_stream(doc) -> "Hello world stream socket"; basic_stream(suite) -> @@ -941,6 +1042,14 @@ peeloff_active_true(suite) -> peeloff_active_true(Config) -> peeloff(Config, [{active,true}]). +peeloff_active_n(doc) -> + "Peel off an SCTP stream socket ({active,N})"; +peeloff_active_n(suite) -> + []; + +peeloff_active_n(Config) -> + peeloff(Config, [{active,1}]). + peeloff(Config, SockOpts) when is_list(Config) -> ?line Addr = {127,0,0,1}, ?line Stream = 0, @@ -1519,7 +1628,13 @@ s_loop(Socket, Timeout, Parent, Handler, State) -> end. again(Socket) -> - inet:setopts(Socket, [{active,once}]). + receive + {sctp_passive,Socket} -> + [{active, false}] = ok(inet:getopts(Socket, [active])), + ok = inet:setopts(Socket,[{active,1}]) + after 0 -> + ok = inet:setopts(Socket, [{active,once}]) + end. gb_push(Key, Val, GBT) -> case gb_trees:lookup(Key, GBT) of diff --git a/lib/kernel/test/gen_tcp_misc_SUITE.erl b/lib/kernel/test/gen_tcp_misc_SUITE.erl index ee271fbdfa..ee8bfcceb1 100644 --- a/lib/kernel/test/gen_tcp_misc_SUITE.erl +++ b/lib/kernel/test/gen_tcp_misc_SUITE.erl @@ -25,7 +25,7 @@ -export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1, init_per_group/2,end_per_group/2, controlling_process/1, controlling_process_self/1, - no_accept/1, close_with_pending_output/1, + no_accept/1, close_with_pending_output/1, active_n/1, data_before_close/1, iter_max_socks/1, get_status/1, passive_sockets/1, accept_closed_by_other_process/1, init_per_testcase/2, end_per_testcase/2, @@ -70,7 +70,7 @@ suite() -> [{ct_hooks,[ts_install_cth]}]. all() -> [controlling_process, controlling_process_self, no_accept, close_with_pending_output, data_before_close, - iter_max_socks, passive_sockets, + iter_max_socks, passive_sockets, active_n, accept_closed_by_other_process, otp_3924, closed_socket, shutdown_active, shutdown_passive, shutdown_pending, default_options, http_bad_packet, busy_send, @@ -407,6 +407,114 @@ send_loop(Sock, Data, Left) -> ok = gen_tcp:send(Sock, Data), send_loop(Sock, Data, Left-1). +%% Test {active,N} option +active_n(doc) -> + ["Verify operation of the {active,N} option."]; +active_n(suite) -> []; +active_n(Config) when is_list(Config) -> + N = 3, + LS = ok(gen_tcp:listen(0, [{active,N}])), + [{active,N}] = ok(inet:getopts(LS, [active])), + ok = inet:setopts(LS, [{active,-N}]), + receive + {tcp_passive, LS} -> ok + after + 5000 -> + exit({error,tcp_passive_failure}) + end, + [{active,false}] = ok(inet:getopts(LS, [active])), + ok = inet:setopts(LS, [{active,0}]), + receive + {tcp_passive, LS} -> ok + after + 5000 -> + exit({error,tcp_passive_failure}) + end, + ok = inet:setopts(LS, [{active,32767}]), + {error,einval} = inet:setopts(LS, [{active,1}]), + {error,einval} = inet:setopts(LS, [{active,-32769}]), + ok = inet:setopts(LS, [{active,-32768}]), + receive + {tcp_passive, LS} -> ok + after + 5000 -> + exit({error,tcp_passive_failure}) + end, + [{active,false}] = ok(inet:getopts(LS, [active])), + ok = inet:setopts(LS, [{active,N}]), + ok = inet:setopts(LS, [{active,true}]), + [{active,true}] = ok(inet:getopts(LS, [active])), + receive + _ -> exit({error,active_n}) + after + 0 -> + ok + end, + ok = inet:setopts(LS, [{active,N}]), + ok = inet:setopts(LS, [{active,once}]), + [{active,once}] = ok(inet:getopts(LS, [active])), + receive + _ -> exit({error,active_n}) + after + 0 -> + ok + end, + {error,einval} = inet:setopts(LS, [{active,32768}]), + ok = inet:setopts(LS, [{active,false}]), + [{active,false}] = ok(inet:getopts(LS, [active])), + Port = ok(inet:port(LS)), + C = ok(gen_tcp:connect("localhost", Port, [{active,N}])), + [{active,N}] = ok(inet:getopts(C, [active])), + S = ok(gen_tcp:accept(LS)), + ok = inet:setopts(S, [{active,N}]), + [{active,N}] = ok(inet:getopts(S, [active])), + repeat(3, + fun(I) -> + Msg = "message "++integer_to_list(I), + ok = gen_tcp:send(C, Msg), + receive + {tcp,S,Msg} -> + ok = gen_tcp:send(S, Msg) + after + 5000 -> + exit({error,timeout}) + end, + receive + {tcp,C,Msg} -> + ok + after + 5000 -> + exit({error,timeout}) + end + end), + receive + {tcp_passive,S} -> + [{active,false}] = ok(inet:getopts(S, [active])) + after + 5000 -> + exit({error,tcp_passive}) + end, + receive + {tcp_passive,C} -> + [{active,false}] = ok(inet:getopts(C, [active])) + after + 5000 -> + exit({error,tcp_passive}) + end, + LS2 = ok(gen_tcp:listen(0, [{active,0}])), + receive + {tcp_passive,LS2} -> + [{active,false}] = ok(inet:getopts(LS2, [active])) + after + 5000 -> + exit({error,tcp_passive}) + end, + ok = gen_tcp:close(LS2), + ok = gen_tcp:close(C), + ok = gen_tcp:close(S), + ok = gen_tcp:close(LS), + ok. + -define(OTP_3924_MAX_DELAY, 100). %% Taken out of the blue, but on intra host connections %% I expect propagation of a close to be quite fast @@ -2659,3 +2767,5 @@ oct_aloop(S,X,Times) -> gen_tcp:close(S), closed end. + +ok({ok,V}) -> V. diff --git a/lib/kernel/test/gen_udp_SUITE.erl b/lib/kernel/test/gen_udp_SUITE.erl index 4cc6018614..6bb41999c5 100644 --- a/lib/kernel/test/gen_udp_SUITE.erl +++ b/lib/kernel/test/gen_udp_SUITE.erl @@ -33,7 +33,7 @@ init_per_group/2,end_per_group/2]). -export([init_per_testcase/2, end_per_testcase/2]). --export([send_to_closed/1, +-export([send_to_closed/1, active_n/1, buffer_size/1, binary_passive_recv/1, bad_address/1, read_packets/1, open_fd/1, connect/1, implicit_inet6/1]). @@ -42,7 +42,7 @@ suite() -> [{ct_hooks,[ts_install_cth]}]. all() -> [send_to_closed, buffer_size, binary_passive_recv, bad_address, read_packets, open_fd, connect, - implicit_inet6]. + implicit_inet6, active_n]. groups() -> []. @@ -465,6 +465,108 @@ open_fd(Config) when is_list(Config) -> ?t:fail(io_lib:format("~w", [flush()])) end. +active_n(Config) when is_list(Config) -> + N = 3, + S1 = ok(gen_udp:open(0, [{active,N}])), + [{active,N}] = ok(inet:getopts(S1, [active])), + ok = inet:setopts(S1, [{active,-N}]), + receive + {udp_passive, S1} -> ok + after + 5000 -> + exit({error,udp_passive_failure}) + end, + [{active,false}] = ok(inet:getopts(S1, [active])), + ok = inet:setopts(S1, [{active,0}]), + receive + {udp_passive, S1} -> ok + after + 5000 -> + exit({error,udp_passive_failure}) + end, + ok = inet:setopts(S1, [{active,32767}]), + {error,einval} = inet:setopts(S1, [{active,1}]), + {error,einval} = inet:setopts(S1, [{active,-32769}]), + ok = inet:setopts(S1, [{active,-32768}]), + receive + {udp_passive, S1} -> ok + after + 5000 -> + exit({error,udp_passive_failure}) + end, + [{active,false}] = ok(inet:getopts(S1, [active])), + ok = inet:setopts(S1, [{active,N}]), + ok = inet:setopts(S1, [{active,true}]), + [{active,true}] = ok(inet:getopts(S1, [active])), + receive + _ -> exit({error,active_n}) + after + 0 -> + ok + end, + ok = inet:setopts(S1, [{active,N}]), + ok = inet:setopts(S1, [{active,once}]), + [{active,once}] = ok(inet:getopts(S1, [active])), + receive + _ -> exit({error,active_n}) + after + 0 -> + ok + end, + {error,einval} = inet:setopts(S1, [{active,32768}]), + ok = inet:setopts(S1, [{active,false}]), + [{active,false}] = ok(inet:getopts(S1, [active])), + S1Port = ok(inet:port(S1)), + S2 = ok(gen_udp:open(0, [{active,N}])), + S2Port = ok(inet:port(S2)), + [{active,N}] = ok(inet:getopts(S2, [active])), + ok = inet:setopts(S1, [{active,N}]), + [{active,N}] = ok(inet:getopts(S1, [active])), + lists:foreach( + fun(I) -> + Msg = "message "++integer_to_list(I), + ok = gen_udp:send(S2, "localhost", S1Port, Msg), + receive + {udp,S1,_,S2Port,Msg} -> + ok = gen_udp:send(S1, "localhost", S2Port, Msg) + after + 5000 -> + exit({error,timeout}) + end, + receive + {udp,S2,_,S1Port,Msg} -> + ok + after + 5000 -> + exit({error,timeout}) + end + end, lists:seq(1,N)), + receive + {udp_passive,S1} -> + [{active,false}] = ok(inet:getopts(S1, [active])) + after + 5000 -> + exit({error,udp_passive}) + end, + receive + {udp_passive,S2} -> + [{active,false}] = ok(inet:getopts(S2, [active])) + after + 5000 -> + exit({error,udp_passive}) + end, + S3 = ok(gen_udp:open(0, [{active,0}])), + receive + {udp_passive,S3} -> + [{active,false}] = ok(inet:getopts(S3, [active])) + after + 5000 -> + exit({error,udp_passive}) + end, + ok = gen_udp:close(S3), + ok = gen_udp:close(S2), + ok = gen_udp:close(S1), + ok. % % Utils diff --git a/lib/kernel/test/inet_SUITE.erl b/lib/kernel/test/inet_SUITE.erl index 46c8c0b88b..ed43749cc0 100644 --- a/lib/kernel/test/inet_SUITE.erl +++ b/lib/kernel/test/inet_SUITE.erl @@ -38,10 +38,10 @@ gethostnative_debug_level/0, gethostnative_debug_level/1, getif/1, getif_ifr_name_overflow/1,getservbyname_overflow/1, getifaddrs/1, - parse_strict_address/1]). + parse_strict_address/1, simple_netns/1]). -export([get_hosts/1, get_ipv6_hosts/1, parse_hosts/1, parse_address/1, - kill_gethost/0, parallell_gethost/0]). + kill_gethost/0, parallell_gethost/0, test_netns/0]). -export([init_per_testcase/2, end_per_testcase/2]). suite() -> [{ct_hooks,[ts_install_cth]}]. @@ -53,7 +53,7 @@ all() -> t_gethostnative, gethostnative_parallell, cname_loop, gethostnative_debug_level, gethostnative_soft_restart, getif, getif_ifr_name_overflow, getservbyname_overflow, - getifaddrs, parse_strict_address]. + getifaddrs, parse_strict_address, simple_netns]. groups() -> [{parse, [], [parse_hosts, parse_address]}]. @@ -1099,3 +1099,96 @@ toupper([C|Cs]) when is_integer(C) -> end; toupper([]) -> []. + + +simple_netns(Config) when is_list(Config) -> + {ok,U} = gen_udp:open(0), + case inet:setopts(U, [{netns,""}]) of + ok -> + jog_netns_opt(U), + ok = gen_udp:close(U), + %% + {ok,L} = gen_tcp:listen(0, []), + jog_netns_opt(L), + ok = gen_tcp:close(L), + %% + {ok,S} = gen_sctp:open(), + jog_netns_opt(S), + ok = gen_sctp:close(S); + {error,einval} -> + {skip,"setns() not supported"} + end. + +jog_netns_opt(S) -> + %% This is just jogging the option mechanics + ok = inet:setopts(S, [{netns,""}]), + {ok,[{netns,""}]} = inet:getopts(S, [netns]), + ok = inet:setopts(S, [{netns,"/proc/self/ns/net"}]), + {ok,[{netns,"/proc/self/ns/net"}]} = inet:getopts(S, [netns]), + ok. + + +%% Manual test to be run outside test_server in an emulator +%% started by root, in a machine with setns() support... +test_netns() -> + DefaultIF = v1, + DefaultIP = {192,168,1,17}, + Namespace = "test", + NamespaceIF = v2, + NamespaceIP = {192,168,1,18}, + %% + DefaultIPString = inet_parse:ntoa(DefaultIP), + NamespaceIPString = inet_parse:ntoa(NamespaceIP), + cmd("ip netns add ~s", + [Namespace]), + cmd("ip link add name ~w type veth peer name ~w netns ~s", + [DefaultIF,NamespaceIF,Namespace]), + cmd("ip netns exec ~s ip addr add ~s/30 dev ~w", + [Namespace,NamespaceIPString,NamespaceIF]), + cmd("ip netns exec ~s ip link set ~w up", + [Namespace,NamespaceIF]), + cmd("ip addr add ~s/30 dev ~w", + [DefaultIPString,DefaultIF]), + cmd("ip link set ~w up", + [DefaultIF]), + try test_netns( + {DefaultIF,DefaultIP}, + filename:join("/var/run/netns/", Namespace), + {NamespaceIF,NamespaceIP}) of + Result -> + io:put_chars(["#### Test done",io_lib:nl()]), + Result + after + cmd("ip link delete ~w type veth", + [DefaultIF]), + cmd("ip netns delete ~s", + [Namespace]) + end. + +test_netns({DefaultIF,DefaultIP}, Namespace, {NamespaceIF,NamespaceIP}) -> + {ok,ListenSocket} = gen_tcp:listen(0, [{active,false}]), + {ok,[{addr,DefaultIP}]} = inet:ifget(ListenSocket, DefaultIF, [addr]), + {ok,ListenPort} = inet:port(ListenSocket), + {ok,ConnectSocket} = + gen_tcp:connect( + DefaultIP, ListenPort, [{active,false},{netns,Namespace}], 3000), + {ok,[{addr,NamespaceIP}]} = inet:ifget(ConnectSocket, NamespaceIF, [addr]), + {ok,ConnectPort} = inet:port(ConnectSocket), + {ok,AcceptSocket} = gen_tcp:accept(ListenSocket, 0), + {ok,AcceptPort} = inet:port(AcceptSocket), + {ok,{NamespaceIP,ConnectPort}} = inet:peername(AcceptSocket), + {ok,{DefaultIP,AcceptPort}} = inet:peername(ConnectSocket), + ok = gen_tcp:send(ConnectSocket, "data"), + ok = gen_tcp:close(ConnectSocket), + {ok,"data"} = gen_tcp:recv(AcceptSocket, 4, 1000), + {error,closed} = gen_tcp:recv(AcceptSocket, 1, 1000), + ok = gen_tcp:close(AcceptSocket), + ok = gen_tcp:close(ListenSocket). + +cmd(Cmd, Args) -> + cmd(io_lib:format(Cmd, Args)). +%% +cmd(CmdString) -> + io:put_chars(["# ",CmdString,io_lib:nl()]), + io:put_chars([os:cmd(CmdString++" ; echo ' =>' $?")]), + ok. diff --git a/lib/megaco/doc/src/notes.xml b/lib/megaco/doc/src/notes.xml index 50b2661c57..a1039cbda0 100644 --- a/lib/megaco/doc/src/notes.xml +++ b/lib/megaco/doc/src/notes.xml @@ -36,7 +36,23 @@ section is the version number of Megaco.</p> - <section><title>Megaco 3.17.0.1</title> + <section><title>Megaco 3.17.0.2</title> + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Introduced functionality for inspection of system and + build configuration.</p> + <p> + Own Id: OTP-11196</p> + </item> + </list> + </section> + +</section> + +<section><title>Megaco 3.17.0.1</title> <section><title>Improvements and New Features</title> <list> diff --git a/lib/megaco/src/app/megaco.appup.src b/lib/megaco/src/app/megaco.appup.src index b3659366a4..da171e0c18 100644 --- a/lib/megaco/src/app/megaco.appup.src +++ b/lib/megaco/src/app/megaco.appup.src @@ -170,6 +170,8 @@ {"%VSN%", [ + {"3.17.0.1", []}, + {"3.17", []}, {"3.16.0.3", [ {update, megaco_flex_scanner_handler, {advanced, upgrade_from_pre_3_17}, @@ -178,6 +180,8 @@ } ], [ + {"3.17.0.1", []}, + {"3.17", []}, {"3.16.0.3", [ {update, megaco_flex_scanner_handler, {advanced, downgrade_to_pre_3_17}, diff --git a/lib/megaco/vsn.mk b/lib/megaco/vsn.mk index db956102a6..ea4e9f2eb8 100644 --- a/lib/megaco/vsn.mk +++ b/lib/megaco/vsn.mk @@ -18,6 +18,6 @@ # %CopyrightEnd% APPLICATION = megaco -MEGACO_VSN = 3.17.0.1 +MEGACO_VSN = 3.17.0.2 PRE_VSN = APP_VSN = "$(APPLICATION)-$(MEGACO_VSN)$(PRE_VSN)" diff --git a/lib/mnesia/doc/src/notes.xml b/lib/mnesia/doc/src/notes.xml index 99a26dd281..da66a647f5 100644 --- a/lib/mnesia/doc/src/notes.xml +++ b/lib/mnesia/doc/src/notes.xml @@ -38,7 +38,36 @@ thus constitutes one section in this document. The title of each section is the version number of Mnesia.</p> - <section><title>Mnesia 4.9</title> + <section><title>Mnesia 4.10</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Fix timing issues in checkpoint creation.</p> + <p> + Own Id: OTP-10957</p> + </item> + </list> + </section> + + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Fixed a problem where the fallback BUP file is removed + when calling mnesia:uninstall_fallback and mnesia is not + started.</p> + <p> + Own Id: OTP-11241</p> + </item> + </list> + </section> + +</section> + +<section><title>Mnesia 4.9</title> <section><title>Fixed Bugs and Malfunctions</title> <list> diff --git a/lib/mnesia/src/mnesia_checkpoint.erl b/lib/mnesia/src/mnesia_checkpoint.erl index eb8fe38908..173e3be2f5 100644 --- a/lib/mnesia/src/mnesia_checkpoint.erl +++ b/lib/mnesia/src/mnesia_checkpoint.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1996-2009. All Rights Reserved. +%% Copyright Ericsson AB 1996-2013 %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -31,8 +31,7 @@ tm_retain/5, tm_enter_pending/1, tm_enter_pending/3, - tm_exit_pending/1, - convert_cp_record/1 + tm_exit_pending/1 ]). %% Public interface @@ -88,25 +87,6 @@ pid }). -%% Old record definition --record(checkpoint, {name, - allow_remote, - ram_overrides_dump, - nodes, - node, - now, - min, - max, - pending_tab, - wait_for_old, - is_activated, - ignore_new, - retainers, - iterators, - supervisor, - pid - }). - -record(retainer, {cp_name, tab_name, store, writers = [], really_retain = true}). -record(iter, {tab_name, oid_tab, main_tab, retainer_tab, source, val, pid}). @@ -129,15 +109,6 @@ tm_prepare(Cp) when is_record(Cp, checkpoint_args) -> start_retainer(Cp); true -> {error, {already_exists, Name, node()}} - end; -tm_prepare(Cp) when is_record(Cp, checkpoint) -> - %% Node with old protocol sent an old checkpoint record - %% and we have to convert it - case convert_cp_record(Cp) of - {ok, NewCp} -> - tm_prepare(NewCp); - {error, Reason} -> - {error, Reason} end. tm_mnesia_down(Node) -> @@ -156,6 +127,7 @@ tm_enter_pending(Pending) -> tm_enter_pending([], Pending) -> Pending; tm_enter_pending([Tab | Tabs], Pending) -> + %% io:format("Add ~p ~p ~p~n",[Tab, Pending, hd(tl(element(2, process_info(self(), current_stacktrace))))]), catch ?ets_insert(Tab, Pending), tm_enter_pending(Tabs, Pending). @@ -371,9 +343,7 @@ activate(Args) -> end. args2cp(Args) when is_list(Args)-> - case catch lists:foldl(fun check_arg/2, #checkpoint_args{}, Args) of - {'EXIT', Reason} -> - {error, Reason}; + try lists:foldl(fun check_arg/2, #checkpoint_args{}, Args) of Cp -> case check_tables(Cp) of {error, Reason} -> @@ -381,6 +351,10 @@ args2cp(Args) when is_list(Args)-> {ok, Overriders, AllTabs} -> arrange_retainers(Cp, Overriders, AllTabs) end + catch exit:Reason -> + {error, Reason}; + error:Reason -> + {error, Reason} end; args2cp(Args) -> {error, {badarg, Args}}. @@ -390,10 +364,10 @@ check_arg({name, Name}, Cp) -> true -> exit({already_exists, Name}); false -> - case catch tab2retainer({foo, Name}) of - List when is_list(List) -> - Cp#checkpoint_args{name = Name}; - _ -> + try + [_|_] = tab2retainer({foo, Name}), + Cp#checkpoint_args{name = Name} + catch _:_ -> exit({badarg, Name}) end end; @@ -641,11 +615,7 @@ init(Cp) -> process_flag(priority, high), %% Needed dets files might starve the system Name = Cp#checkpoint_args.name, Props = [set, public, {keypos, 2}], - case catch ?ets_new_table(mnesia_pending_checkpoint, Props) of - {'EXIT', Reason} -> %% system limit - Msg = "Cannot create an ets table for pending transactions", - Error = {error, {system_limit, Name, Msg, Reason}}, - proc_lib:init_ack(Cp#checkpoint_args.supervisor, Error); + try ?ets_new_table(mnesia_pending_checkpoint, Props) of PendingTab -> Rs = [prepare_tab(Cp, R) || R <- Cp#checkpoint_args.retainers], Cp2 = Cp#checkpoint_args{retainers = Rs, @@ -658,6 +628,10 @@ init(Cp) -> dbg_out("Checkpoint ~p (~p) started~n", [Name, self()]), proc_lib:init_ack(Cp2#checkpoint_args.supervisor, {ok, self()}), retainer_loop(Cp2) + catch error:Reason -> %% system limit + Msg = "Cannot create an ets table for pending transactions", + Error = {error, {system_limit, Name, Msg, Reason}}, + proc_lib:init_ack(Cp#checkpoint_args.supervisor, Error) end. prepare_tab(Cp, R) -> @@ -798,104 +772,142 @@ retainer_delete({dets, Store}) -> Fname = tab2retainer(Store), file:delete(Fname). -retainer_loop(Cp) -> - Name = Cp#checkpoint_args.name, +retainer_loop(Cp = #checkpoint_args{is_activated=false, name=Name}) -> receive - {_From, {retain, Tid, Tab, Key, OldRecs}} - when Cp#checkpoint_args.wait_for_old == [] -> - R = val({Tab, {retainer, Name}}), - PendingTab = Cp#checkpoint_args.pending_tab, - case R#retainer.really_retain of - true when PendingTab =:= undefined -> - Store = R#retainer.store, - case retainer_get(Store, Key) of - [] -> retainer_put(Store, {Tab, Key, OldRecs}); - _ -> already_retained - end; - true -> - case ets:member(PendingTab, Tid) of - true -> ignore; - false -> - Store = R#retainer.store, - case retainer_get(Store, Key) of - [] -> retainer_put(Store, {Tab, Key, OldRecs}); - _ -> already_retained - end - end; - false -> - ignore - end, - retainer_loop(Cp); - %% Adm + {From, {activate, Pending}} -> + StillPending = mnesia_recover:still_pending(Pending), + enter_still_pending(StillPending, Cp#checkpoint_args.pending_tab), + Local = [Tid || #tid{pid=Pid} = Tid <- StillPending, node(Pid) =/= node()], + Cp2 = maybe_activate(Cp#checkpoint_args{wait_for_old = Local}), + + reply(From, Name, activated), + retainer_loop(Cp2); + + {_From, {exit_pending, Tid}} when is_list(Cp#checkpoint_args.wait_for_old) -> + StillPending = lists:delete(Tid, Cp#checkpoint_args.wait_for_old), + Cp2 = Cp#checkpoint_args{wait_for_old = StillPending}, + Cp3 = maybe_activate(Cp2), + retainer_loop(Cp3); + {From, deactivate} -> do_stop(Cp), reply(From, Name, deactivated), unlink(From), exit(shutdown); + {From, get_checkpoint} -> + reply(From, Name, Cp), + retainer_loop(Cp); + {_From, {add_retainer, R, Node}} -> + Cp2 = do_add_retainer(Cp, R, Node), + retainer_loop(Cp2); + + {From, collect_pending} -> + PendingTab = Cp#checkpoint_args.pending_tab, + del(pending_checkpoints, PendingTab), + Pending = ?ets_match_object(PendingTab, '_'), + reply(From, Name, {ok, Pending}), + retainer_loop(Cp); + + {_From, {mnesia_down, Node}} -> + Cp2 = do_del_retainers(Cp, Node), + retainer_loop(Cp2); + {'EXIT', Parent, _} when Parent == Cp#checkpoint_args.supervisor -> %% do_stop(Cp), %% assume that entire Mnesia is terminating exit(shutdown); - {_From, {mnesia_down, Node}} -> - Cp2 = do_del_retainers(Cp, Node), - retainer_loop(Cp2); + {'EXIT', From, _Reason} -> + Iters = [Iter || Iter <- Cp#checkpoint_args.iterators, + check_iter(From, Iter)], + retainer_loop(Cp#checkpoint_args{iterators = Iters}); + + {system, From, Msg} -> + dbg_out("~p got {system, ~p, ~p}~n", [?MODULE, From, Msg]), + sys:handle_system_msg(Msg, From, Cp#checkpoint_args.supervisor, + ?MODULE, [], Cp) + end; + +retainer_loop(Cp = #checkpoint_args{name=Name}) -> + receive + {_From, {retain, Tid, Tab, Key, OldRecs}} -> + R = val({Tab, {retainer, Name}}), + PendingTab = Cp#checkpoint_args.pending_tab, + case R#retainer.really_retain of + true -> + Store = R#retainer.store, + try true = ets:member(PendingTab, Tid), + %% io:format("CP: ~p ~p ~p ~p~n",[true, Tab, Key, Tid]), + case retainer_get(Store, Key) of + [] -> ignore; + _ -> ets:delete(element(2,Store), Key) + end + catch _:_ -> + %% io:format("CP: ~p ~p ~p ~p~n",[false, Tab, Key, Tid]), + case retainer_get(Store, Key) of + [] -> retainer_put(Store, {Tab, Key, OldRecs}); + _ -> already_retained + end + end; + false -> + ignore + end, + retainer_loop(Cp); + + %% Adm {From, get_checkpoint} -> reply(From, Name, Cp), retainer_loop(Cp); - {From, {add_copy, Tab, Node}} when Cp#checkpoint_args.wait_for_old == [] -> + {From, {add_copy, Tab, Node}} -> {Res, Cp2} = do_add_copy(Cp, Tab, Node), reply(From, Name, Res), retainer_loop(Cp2); - {From, {del_copy, Tab, Node}} when Cp#checkpoint_args.wait_for_old == [] -> + {From, {del_copy, Tab, Node}} -> Cp2 = do_del_copy(Cp, Tab, Node), reply(From, Name, ok), retainer_loop(Cp2); - {From, {change_copy, Tab, From, To}} when Cp#checkpoint_args.wait_for_old == [] -> + {From, {change_copy, Tab, From, To}} -> Cp2 = do_change_copy(Cp, Tab, From, To), reply(From, Name, ok), retainer_loop(Cp2); {_From, {add_retainer, R, Node}} -> Cp2 = do_add_retainer(Cp, R, Node), retainer_loop(Cp2); - {_From, {del_retainer, R, Node}} when Cp#checkpoint_args.wait_for_old == [] -> + {_From, {del_retainer, R, Node}} -> Cp2 = do_del_retainer(Cp, R, Node), retainer_loop(Cp2); %% Iteration - {From, {iter_begin, Iter}} when Cp#checkpoint_args.wait_for_old == [] -> + {From, {iter_begin, Iter}} -> Cp2 = iter_begin(Cp, From, Iter), retainer_loop(Cp2); - {From, {iter_end, Iter}} when Cp#checkpoint_args.wait_for_old == [] -> + {From, {iter_end, Iter}} -> retainer_fixtable(Iter#iter.oid_tab, false), Iters = Cp#checkpoint_args.iterators -- [Iter], reply(From, Name, ok), - retainer_loop(Cp#checkpoint_args{iterators = Iters}); - - {_From, {exit_pending, Tid}} - when is_list(Cp#checkpoint_args.wait_for_old) -> - StillPending = lists:delete(Tid, Cp#checkpoint_args.wait_for_old), - Cp2 = Cp#checkpoint_args{wait_for_old = StillPending}, - Cp3 = maybe_activate(Cp2), - retainer_loop(Cp3); + retainer_loop(Cp#checkpoint_args{iterators = Iters}); - {From, collect_pending} -> - PendingTab = Cp#checkpoint_args.pending_tab, - del(pending_checkpoints, PendingTab), - Pending = ?ets_match_object(PendingTab, '_'), - reply(From, Name, {ok, Pending}), + {_From, {exit_pending, _Tid}} -> retainer_loop(Cp); - {From, {activate, Pending}} -> - StillPending = mnesia_recover:still_pending(Pending), - enter_still_pending(StillPending, Cp#checkpoint_args.pending_tab), - Cp2 = maybe_activate(Cp#checkpoint_args{wait_for_old = StillPending}), - reply(From, Name, activated), + {From, deactivate} -> + do_stop(Cp), + reply(From, Name, deactivated), + unlink(From), + exit(shutdown); + + {_From, {mnesia_down, Node}} -> + Cp2 = do_del_retainers(Cp, Node), retainer_loop(Cp2); + {'EXIT', Parent, _} when Parent == Cp#checkpoint_args.supervisor -> + %% do_stop(Cp), + %% assume that entire Mnesia is terminating + exit(shutdown); + {'EXIT', From, _Reason} -> Iters = [Iter || Iter <- Cp#checkpoint_args.iterators, check_iter(From, Iter)], @@ -903,13 +915,17 @@ retainer_loop(Cp) -> {system, From, Msg} -> dbg_out("~p got {system, ~p, ~p}~n", [?MODULE, From, Msg]), - sys:handle_system_msg(Msg, From, no_parent, ?MODULE, [], Cp) + sys:handle_system_msg(Msg, From, Cp#checkpoint_args.supervisor, + ?MODULE, [], Cp); + Msg -> + dbg_out("~p got ~p~n", [?MODULE, Msg]) end. maybe_activate(Cp) - when Cp#checkpoint_args.wait_for_old == [], - Cp#checkpoint_args.is_activated == false -> - Cp#checkpoint_args{pending_tab = undefined, is_activated = true}; + when Cp#checkpoint_args.wait_for_old == [], + Cp#checkpoint_args.is_activated == false -> + Cp#checkpoint_args{%% pending_tab = undefined, + is_activated = true}; maybe_activate(Cp) -> Cp. @@ -1226,65 +1242,6 @@ system_terminate(_Reason, _Parent,_Debug, Cp) -> system_code_change(Cp, _Module, _OldVsn, _Extra) -> {ok, Cp}. -convert_cp_record(Cp) when is_record(Cp, checkpoint) -> - ROD = - case Cp#checkpoint.ram_overrides_dump of - true -> Cp#checkpoint.min ++ Cp#checkpoint.max; - false -> [] - end, - - {ok, #checkpoint_args{name = Cp#checkpoint.name, - allow_remote = Cp#checkpoint.name, - ram_overrides_dump = ROD, - nodes = Cp#checkpoint.nodes, - node = Cp#checkpoint.node, - now = Cp#checkpoint.now, - cookie = ?unique_cookie, - min = Cp#checkpoint.min, - max = Cp#checkpoint.max, - pending_tab = Cp#checkpoint.pending_tab, - wait_for_old = Cp#checkpoint.wait_for_old, - is_activated = Cp#checkpoint.is_activated, - ignore_new = Cp#checkpoint.ignore_new, - retainers = Cp#checkpoint.retainers, - iterators = Cp#checkpoint.iterators, - supervisor = Cp#checkpoint.supervisor, - pid = Cp#checkpoint.pid - }}; -convert_cp_record(Cp) when is_record(Cp, checkpoint_args) -> - AllTabs = Cp#checkpoint_args.min ++ Cp#checkpoint_args.max, - ROD = case Cp#checkpoint_args.ram_overrides_dump of - [] -> - false; - AllTabs -> - true; - _ -> - error - end, - if - ROD == error -> - {error, {"Old node cannot handle new checkpoint protocol", - ram_overrides_dump}}; - true -> - {ok, #checkpoint{name = Cp#checkpoint_args.name, - allow_remote = Cp#checkpoint_args.name, - ram_overrides_dump = ROD, - nodes = Cp#checkpoint_args.nodes, - node = Cp#checkpoint_args.node, - now = Cp#checkpoint_args.now, - min = Cp#checkpoint_args.min, - max = Cp#checkpoint_args.max, - pending_tab = Cp#checkpoint_args.pending_tab, - wait_for_old = Cp#checkpoint_args.wait_for_old, - is_activated = Cp#checkpoint_args.is_activated, - ignore_new = Cp#checkpoint_args.ignore_new, - retainers = Cp#checkpoint_args.retainers, - iterators = Cp#checkpoint_args.iterators, - supervisor = Cp#checkpoint_args.supervisor, - pid = Cp#checkpoint_args.pid - }} - end. - %%%%%%%%%%%%%%%%%%%%%%%%%% val(Var) -> diff --git a/lib/mnesia/test/mnesia_consistency_test.erl b/lib/mnesia/test/mnesia_consistency_test.erl index 922b89ec2b..a76a0116d5 100644 --- a/lib/mnesia/test/mnesia_consistency_test.erl +++ b/lib/mnesia/test/mnesia_consistency_test.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1997-2012. All Rights Reserved. +%% Copyright Ericsson AB 1997-2013. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -39,7 +39,6 @@ all() -> {group, consistency_after_move_replica}, {group, consistency_after_transform_table}, consistency_after_change_table_copy_type, - {group, consistency_after_fallback}, {group, consistency_after_restore}, consistency_after_rename_of_node, {group, checkpoint_retainer_consistency}, @@ -99,10 +98,14 @@ groups() -> [{group, updates_during_checkpoint_activation}, {group, updates_during_checkpoint_iteration}, {group, load_table_with_activated_checkpoint}, - {group, - add_table_copy_to_table_checkpoint}]}, + {group, add_table_copy_to_table_checkpoint}, + {group, consistency_after_fallback} + ]}, {updates_during_checkpoint_activation, [], - [updates_during_checkpoint_activation_2_ram, + [updates_during_checkpoint_activation_1_ram, + updates_during_checkpoint_activation_1_disc, + updates_during_checkpoint_activation_1_disc_only, + updates_during_checkpoint_activation_2_ram, updates_during_checkpoint_activation_2_disc, updates_during_checkpoint_activation_2_disc_only, updates_during_checkpoint_activation_3_ram, @@ -730,6 +733,18 @@ consistency_after_rename_of_node(doc) -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +updates_during_checkpoint_activation_1_ram(suite) -> []; +updates_during_checkpoint_activation_1_ram(Config) when is_list(Config) -> + updates_during_checkpoint_activation(ram_copies, 1, Config). + +updates_during_checkpoint_activation_1_disc(suite) -> []; +updates_during_checkpoint_activation_1_disc(Config) when is_list(Config) -> + updates_during_checkpoint_activation(disc_copies, 1, Config). + +updates_during_checkpoint_activation_1_disc_only(suite) -> []; +updates_during_checkpoint_activation_1_disc_only(Config) when is_list(Config) -> + updates_during_checkpoint_activation(disc_only_copies, 1, Config). + updates_during_checkpoint_activation_2_ram(suite) -> []; updates_during_checkpoint_activation_2_ram(Config) when is_list(Config) -> updates_during_checkpoint_activation(ram_copies, 2, Config). @@ -771,7 +786,8 @@ updates_during_checkpoint_activation(ReplicaType,NodeConfig,Config) -> timer:sleep(timer:seconds(Delay)), {ok, CPName, _NodeList} = - mnesia:activate_checkpoint([{max, mnesia:system_info(tables)}]), + mnesia:activate_checkpoint([{max, mnesia:system_info(tables)}, + {ram_overrides_dump, true}]), timer:sleep(timer:seconds(Delay)), %% Stop tpcb diff --git a/lib/mnesia/vsn.mk b/lib/mnesia/vsn.mk index d7a132bc1a..c8187013be 100644 --- a/lib/mnesia/vsn.mk +++ b/lib/mnesia/vsn.mk @@ -1 +1 @@ -MNESIA_VSN = 4.9 +MNESIA_VSN = 4.10 diff --git a/lib/observer/doc/src/notes.xml b/lib/observer/doc/src/notes.xml index 998a4e4f9f..8a7a5cc41b 100644 --- a/lib/observer/doc/src/notes.xml +++ b/lib/observer/doc/src/notes.xml @@ -31,6 +31,23 @@ <p>This document describes the changes made to the Observer application.</p> +<section><title>Observer 1.3.1.1</title> + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + The encoding of the <c>notes.xml</c> file has been + changed from latin1 to utf-8 to avoid future merge + problems.</p> + <p> + Own Id: OTP-11310</p> + </item> + </list> + </section> + +</section> + <section><title>Observer 1.3.1</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/observer/doc/src/ttb.xml b/lib/observer/doc/src/ttb.xml index b48febc2a9..6e60a9cb3b 100644 --- a/lib/observer/doc/src/ttb.xml +++ b/lib/observer/doc/src/ttb.xml @@ -105,8 +105,9 @@ ttb:p(all, call)</code> <v>Nodes = atom() | [atom()] | all | existing | new</v> <v>Opts = Opt | [Opt]</v> <v>Opt = {file,Client} | {handler, FormatHandler} | {process_info,PI} | - shell | {shell, ShellSpec} | {timer, TimerSpec} | {overload, {MSec, Module, Function}} - | {flush, MSec} | resume | {resume, FetchTimeout}</v> + shell | {shell, ShellSpec} | {timer, TimerSpec} | + {overload_check, {MSec, Module, Function}} | + {flush, MSec} | resume | {resume, FetchTimeout}</v> <v>TimerSpec = MSec | {MSec, StopOpts}</v> <v>MSec = FetchTimeout = integer()</v> <v>Module = Function = atom() </v> @@ -158,7 +159,7 @@ ttb:p(all, call)</code> network communication are always present. The timer starts after <c>ttb:p/2</c> is issued, so you can set up your trace patterns before. </p> - <p>The <c>overload</c> option allows to enable overload + <p>The <c>overload_check</c> option allows to enable overload checking on the nodes under trace. <c>Module:Function(check)</c> is performed each <c>MSec</c> milliseconds. If the check returns <c>true</c>, the tracing is disabled on a given node.<br/> diff --git a/lib/observer/vsn.mk b/lib/observer/vsn.mk index 96d9d885da..e933f7480c 100644 --- a/lib/observer/vsn.mk +++ b/lib/observer/vsn.mk @@ -1 +1 @@ -OBSERVER_VSN = 1.3.1 +OBSERVER_VSN = 1.3.1.1 diff --git a/lib/odbc/doc/src/notes.xml b/lib/odbc/doc/src/notes.xml index a1c6f999e0..13dff1489f 100644 --- a/lib/odbc/doc/src/notes.xml +++ b/lib/odbc/doc/src/notes.xml @@ -31,7 +31,44 @@ <p>This document describes the changes made to the odbc application. </p> - <section><title>ODBC 2.10.16</title> + <section><title>ODBC 2.10.17</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + The format of the xml source for documentation is + corrected in order to conform to the DTDs and to pass + xmllint without errors.</p> + <p> + Own Id: OTP-11193</p> + </item> + </list> + </section> + + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Introduced functionality for inspection of system and + build configuration.</p> + <p> + Own Id: OTP-11196</p> + </item> + <item> + <p> + Prevent odbcserver crash if it's executed and supplied + incorrect data to stdin. Thanks to Sergei Golovan.</p> + <p> + Own Id: OTP-11233</p> + </item> + </list> + </section> + +</section> + +<section><title>ODBC 2.10.16</title> <section><title>Improvements and New Features</title> <list> diff --git a/lib/odbc/doc/src/odbc.xml b/lib/odbc/doc/src/odbc.xml index 0e9505390b..99b9bbbe88 100644 --- a/lib/odbc/doc/src/odbc.xml +++ b/lib/odbc/doc/src/odbc.xml @@ -213,12 +213,13 @@ Note that this information is probably of little use when writing database-independent code, but can be of assistance in providing more sophisticated error handling when dealing with a known underlying database. + </p> <list type="bulleted"> <item><c>ODBCErrorCode</c> is the ODBC error string returned by the ODBC driver.</item> <item><c>NativeErrorCode</c> is the numberic error code returned by the underlying database. The possible values and their meanings are dependent on the database being used.</item> <item><c>Reason</c> is as per the <c>Reason</c> field when extended errors are not enabled.</item> - </list></p> + </list> </desc> </func> <func> diff --git a/lib/odbc/test/odbc_connect_SUITE.erl b/lib/odbc/test/odbc_connect_SUITE.erl index 74ae2c96e6..2a16388929 100644 --- a/lib/odbc/test/odbc_connect_SUITE.erl +++ b/lib/odbc/test/odbc_connect_SUITE.erl @@ -77,6 +77,8 @@ end_per_group(_GroupName, Config) -> %% variable, but should NOT alter/remove any existing entries. %%-------------------------------------------------------------------- init_per_suite(Config) when is_list(Config) -> + file:write_file(filename:join([proplists:get_value(priv_dir,Config), + "..","..","..","ignore_core_files"]),""), case odbc_test_lib:skip() of true -> {skip, "ODBC not supported"}; diff --git a/lib/odbc/vsn.mk b/lib/odbc/vsn.mk index 98a9f4ab4a..34c3eff933 100644 --- a/lib/odbc/vsn.mk +++ b/lib/odbc/vsn.mk @@ -1 +1 @@ -ODBC_VSN = 2.10.16 +ODBC_VSN = 2.10.17 diff --git a/lib/os_mon/c_src/Makefile.in b/lib/os_mon/c_src/Makefile.in index 51569f6ec9..f84ccf7c87 100644 --- a/lib/os_mon/c_src/Makefile.in +++ b/lib/os_mon/c_src/Makefile.in @@ -84,6 +84,7 @@ debug opt: $(TARGET_FILES) clean: rm -f $(TARGET_FILES) + rm -rf $(OBJDIR) rm -f core *~ docs: diff --git a/lib/os_mon/c_src/cpu_sup.c b/lib/os_mon/c_src/cpu_sup.c index 7372d5b0e8..e9fd75a32c 100644 --- a/lib/os_mon/c_src/cpu_sup.c +++ b/lib/os_mon/c_src/cpu_sup.c @@ -29,6 +29,7 @@ #include <stdio.h> #include <stdlib.h> #include <unistd.h> +#include <string.h> #if defined(__sun__) #include <kstat.h> @@ -120,7 +121,9 @@ typedef struct { static void util_measure(unsigned int **result_vec, int *result_sz); +#if defined(__sun__) static unsigned int misc_measure(char* name); +#endif static void send(unsigned int data); static void sendv(unsigned int data[], int ints); static void error(char* err_msg); @@ -140,7 +143,9 @@ int main(int argc, char** argv) { int rc; int sz; unsigned int *rv; +#if defined(__linux__) unsigned int no_of_cpus = 0; +#endif #if defined(__sun__) kstat_ctl = kstat_open(); @@ -288,10 +293,10 @@ static unsigned int misc_measure(char* name) { if(!entry) return -1; - if(entry->data_type != KSTAT_DATA_ULONG) + if(entry->data_type != KSTAT_DATA_UINT32) return -1; - return entry->value.ul; + return entry->value.ui32; } diff --git a/lib/os_mon/doc/src/notes.xml b/lib/os_mon/doc/src/notes.xml index a5099a0829..c6b5bc8895 100644 --- a/lib/os_mon/doc/src/notes.xml +++ b/lib/os_mon/doc/src/notes.xml @@ -30,6 +30,43 @@ </header> <p>This document describes the changes made to the OS_Mon application.</p> +<section><title>Os_Mon 2.2.13</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Use 'df -k -l' to query FreeBSD and OpenBSD about + diskspace on local disks. Previously 'df' -k -t ufs' was + used but this will not handle zfs or other disks. Just + use '-l' instead of listing potential filesystems.</p> + <p> + Own Id: OTP-11207</p> + </item> + </list> + </section> + + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Fix compilation on Solaris. Thanks to Maciej Malecki.</p> + <p> + Own Id: OTP-11213</p> + </item> + <item> + <p> + Fix broken cpu_sup:nprocs and others on Solaris 64-bit. + Thanks to Simon Cornish.</p> + <p> + Own Id: OTP-11298</p> + </item> + </list> + </section> + +</section> + <section><title>Os_Mon 2.2.12</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/os_mon/test/cpu_sup_SUITE.erl b/lib/os_mon/test/cpu_sup_SUITE.erl index d04adbb6d3..e0382cb0c7 100644 --- a/lib/os_mon/test/cpu_sup_SUITE.erl +++ b/lib/os_mon/test/cpu_sup_SUITE.erl @@ -88,6 +88,7 @@ load_api(Config) when is_list(Config) -> ?line N = cpu_sup:nprocs(), ?line true = is_integer(N), ?line true = N>0, + ?line true = N<1000000, %% avg1() ?line Load1 = cpu_sup:avg1(), diff --git a/lib/os_mon/vsn.mk b/lib/os_mon/vsn.mk index e3acea0258..0af587b9ae 100644 --- a/lib/os_mon/vsn.mk +++ b/lib/os_mon/vsn.mk @@ -1 +1 @@ -OS_MON_VSN = 2.2.12 +OS_MON_VSN = 2.2.13 diff --git a/lib/parsetools/doc/src/leex.xml b/lib/parsetools/doc/src/leex.xml index 0fd5a77e37..7ee0633dac 100644 --- a/lib/parsetools/doc/src/leex.xml +++ b/lib/parsetools/doc/src/leex.xml @@ -38,19 +38,21 @@ Token = tuple()</code> </section> <funcs> <func> - <name>file(FileName) -> ok | error</name> - <name>file(FileName, Options) -> ok | error</name> + <name>file(FileName, [, Options]) -> LeexRet</name> <fsummary>Generate a lexical analyzer</fsummary> <type> <v>FileName = filename()</v> <v>Options = Option | [Option]</v> <v>Option = - see below -</v> - <v>FileReturn = {ok, Scannerfile} - | {ok, Scannerfile, Warnings} - | error - | {error, Warnings, Errors}</v> + <v>LeexRet = {ok, Scannerfile} + | {ok, Scannerfile, Warnings} + | error + | {error, Warnings, Errors}</v> <v>Scannerfile = filename()</v> <v>Warnings = Errors = [{filename(), [ErrorInfo]}]</v> + <v>ErrorInfo = {ErrorLine, module(), Reason}</v> + <v>ErrorLine = integer()</v> + <v>Reason = - formatable by format_error/1 -</v> </type> <desc> <p>Generates a lexical analyzer from the definition in the input diff --git a/lib/parsetools/doc/src/notes.xml b/lib/parsetools/doc/src/notes.xml index bfcc38dedd..929daedf74 100644 --- a/lib/parsetools/doc/src/notes.xml +++ b/lib/parsetools/doc/src/notes.xml @@ -30,6 +30,41 @@ </header> <p>This document describes the changes made to the Parsetools application.</p> +<section><title>Parsetools 2.0.10</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> A bug causing Yecc to generate badly formed parsers + when encountering very simple recursive rules has been + fixed. (Thanks to Eric Pailleau.) </p> + <p> + Own Id: OTP-11269</p> + </item> + <item> + <p> A bug where Unicode filenames combined with Latin-1 + encoding could crash Yecc and Leex has been fixed. </p> + <p> + Own Id: OTP-11286</p> + </item> + </list> + </section> + + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Fix leex module`s inability to build unicode-aware + lexers. Thanks to Pierre Fenoll.</p> + <p> + Own Id: OTP-11313</p> + </item> + </list> + </section> + +</section> + <section><title>Parsetools 2.0.9</title> <section><title>Improvements and New Features</title> diff --git a/lib/parsetools/src/leex.erl b/lib/parsetools/src/leex.erl index e531b78a5b..03f864ff03 100644 --- a/lib/parsetools/src/leex.erl +++ b/lib/parsetools/src/leex.erl @@ -436,7 +436,7 @@ parse_defs(_, {eof,L}, St) -> parse_defs(Ifile, {ok,Chars,L}=Line, Ms, St) -> %% This little beauty matches out a macro definition, RE's are so clear. MS = "^[ \t]*([A-Z_][A-Za-z0-9_]*)[ \t]*=[ \t]*([^ \t\r\n]*)[ \t\r\n]*\$", - case re:run(Chars, MS, [{capture,all_but_first,list}]) of + case re:run(Chars, MS, [{capture,all_but_first,list},unicode]) of {match,[Name,Def]} -> %%io:fwrite("~p = ~p\n", [Name,Def]), parse_defs(Ifile, nextline(Ifile, L, St), [{Name,Def}|Ms], St); @@ -491,7 +491,7 @@ parse_rules_end(_, NextLine, REAs, As, St) -> collect_rule(Ifile, Chars, L0) -> %% Erlang strings are 1 based, but re 0 :-( - {match,[{St0,Len}|_]} = re:run(Chars, "[^ \t\r\n]+"), + {match,[{St0,Len}|_]} = re:run(Chars, "[^ \t\r\n]+", [unicode]), St = St0 + 1, %%io:fwrite("RE = ~p~n", [substr(Chars, St, Len)]), case collect_action(Ifile, substr(Chars, St+Len), L0, []) of @@ -548,7 +548,7 @@ var_used(Name, Toks) -> %% here as it uses info in replace string (&). parse_rule_regexp(RE0, [{M,Exp}|Ms], St) -> - Split= re:split(RE0, "\\{" ++ M ++ "\\}", [{return,list}]), + Split= re:split(RE0, "\\{" ++ M ++ "\\}", [{return,list},unicode]), RE1 = string:join(Split, Exp), parse_rule_regexp(RE1, Ms, St); parse_rule_regexp(RE, [], St) -> @@ -1645,10 +1645,14 @@ output_encoding_comment(File, #leex{encoding = Encoding}) -> output_file_directive(File, Filename, Line) -> io:fwrite(File, <<"-file(~ts, ~w).\n">>, - [format_filename(Filename), Line]). + [format_filename(Filename, File), Line]). -format_filename(Filename) -> - io_lib:write_string(filename:flatten(Filename)). +format_filename(Filename0, File) -> + Filename = filename:flatten(Filename0), + case lists:keyfind(encoding, 1, io:getopts(File)) of + {encoding, unicode} -> io_lib:write_string(Filename); + _ -> io_lib:write_string_as_latin1(Filename) + end. quote($^) -> "\\^"; quote($.) -> "\\."; diff --git a/lib/parsetools/src/yecc.erl b/lib/parsetools/src/yecc.erl index f9207d926e..b698beb558 100644 --- a/lib/parsetools/src/yecc.erl +++ b/lib/parsetools/src/yecc.erl @@ -482,7 +482,7 @@ generate(St0) -> F = case member(time, St1#yecc.options) of true -> io:fwrite(<<"Generating parser from grammar in ~ts\n">>, - [format_filename(St1#yecc.infile)]), + [format_filename(St1#yecc.infile, St1)]), fun timeit/3; false -> fun(_Name, Fn, St) -> Fn(St) end @@ -2519,7 +2519,7 @@ output_encoding_comment(#yecc{encoding = Encoding}=St) -> output_file_directive(St, Filename, Line) when St#yecc.file_attrs -> fwrite(St, <<"-file(~ts, ~w).\n">>, - [format_filename(Filename), Line]); + [format_filename(Filename, St), Line]); output_file_directive(St, _Filename, _Line) -> St. @@ -2547,8 +2547,12 @@ nl(#yecc{outport = Outport, line = Line}=St) -> io:nl(Outport), St#yecc{line = Line + 1}. -format_filename(Filename) -> - io_lib:write_string(filename:flatten(Filename)). +format_filename(Filename0, St) -> + Filename = filename:flatten(Filename0), + case lists:keyfind(encoding, 1, io:getopts(St#yecc.outport)) of + {encoding, unicode} -> io_lib:write_string(Filename); + _ -> io_lib:write_string_as_latin1(Filename) + end. format_assoc(left) -> "Left"; diff --git a/lib/parsetools/test/leex_SUITE.erl b/lib/parsetools/test/leex_SUITE.erl index 576c42dd8e..eb15bebf63 100644 --- a/lib/parsetools/test/leex_SUITE.erl +++ b/lib/parsetools/test/leex_SUITE.erl @@ -44,7 +44,7 @@ pt/1, man/1, ex/1, ex2/1, not_yet/1, - otp_10302/1]). + otp_10302/1, otp_11286/1, unicode/1]). % Default timetrap timeout (set in init_per_testcase). -define(default_timeout, ?t:minutes(1)). @@ -65,8 +65,8 @@ all() -> groups() -> [{checks, [], [file, compile, syntax]}, - {examples, [], [pt, man, ex, ex2, not_yet]}, - {tickets, [], [otp_10302]}]. + {examples, [], [pt, man, ex, ex2, not_yet, unicode]}, + {tickets, [], [otp_10302, otp_11286]}]. init_per_suite(Config) -> Config. @@ -400,6 +400,24 @@ pt(Config) when is_list(Config) -> ?line run(Config, Ts), ok. +unicode(suite) -> + []; +unicode(Config) when is_list(Config) -> + Ts = [{unicode_1, + <<"%% -*- coding: utf-8 -*-\n" + "Definitions.\n" + "RTLarrow = (←)\n" + "Rules.\n" + "{RTLarrow} : {token,{'<-',TokenLine}}.\n" + "Erlang code.\n" + "-export([t/0]).\n" + "t() -> {ok, [{'<-', 1}], 1} = string(\"←\"), ok.">>, + default, + ok}], + + ?line run(Config, Ts), + ok. + man(doc) -> "Examples from the manpage."; man(suite) -> []; @@ -982,6 +1000,68 @@ otp_10302(Config) when is_list(Config) -> ok. +otp_11286(doc) -> + "OTP-11286. A Unicode filename bug; both Leex and Yecc."; +otp_11286(suite) -> []; +otp_11286(Config) when is_list(Config) -> + Node = start_node(otp_11286, "+fnu"), + Dir = ?privdir, + UName = [1024] ++ "u", + UDir = filename:join(Dir, UName), + ok = rpc:call(Node, file, make_dir, [UDir]), + + %% Note: Cannot use UName as filename since the filename is used + %% as module name. To be fixed in R18. + Filename = filename:join(UDir, 'OTP-11286.xrl'), + Scannerfile = filename:join(UDir, 'OTP-11286.erl'), + Options = [return, {scannerfile, Scannerfile}], + + Mini1 = <<"%% coding: utf-8\n" + "Definitions.\n" + "D = [0-9]\n" + "Rules.\n" + "{L}+ : {token,{word,TokenLine,TokenChars}}.\n" + "Erlang code.\n">>, + ok = rpc:call(Node, file, write_file, [Filename, Mini1]), + {ok, _, []} = rpc:call(Node, leex, file, [Filename, Options]), + {ok,_,_} = rpc:call(Node, compile, file, + [Scannerfile,[basic_validation,return]]), + + Mini2 = <<"Definitions.\n" + "D = [0-9]\n" + "Rules.\n" + "{L}+ : {token,{word,TokenLine,TokenChars}}.\n" + "Erlang code.\n">>, + ok = rpc:call(Node, file, write_file, [Filename, Mini2]), + {ok, _, []} = rpc:call(Node, leex, file, [Filename, Options]), + {ok,_,_} = rpc:call(Node, compile, file, + [Scannerfile,[basic_validation,return]]), + + Mini3 = <<"%% coding: latin-1\n" + "Definitions.\n" + "D = [0-9]\n" + "Rules.\n" + "{L}+ : {token,{word,TokenLine,TokenChars}}.\n" + "Erlang code.\n">>, + ok = rpc:call(Node, file, write_file, [Filename, Mini3]), + {ok, _, []} = rpc:call(Node, leex, file, [Filename, Options]), + {ok,_,_} = rpc:call(Node, compile, file, + [Scannerfile,[basic_validation,return]]), + + true = test_server:stop_node(Node), + ok. + +start_node(Name, Args) -> + [_,Host] = string:tokens(atom_to_list(node()), "@"), + ct:log("Trying to start ~w@~s~n", [Name,Host]), + case test_server:start_node(Name, peer, [{args,Args}]) of + {error,Reason} -> + test_server:fail(Reason); + {ok,Node} -> + ct:log("Node ~p started~n", [Node]), + Node + end. + unwritable(Fname) -> {ok, Info} = file:read_file_info(Fname), Mode = Info#file_info.mode - 8#00200, @@ -1013,7 +1093,7 @@ run_test(Config, Def, Pre) -> XrlFile = filename:join(DataDir, DefFile), ErlFile = filename:join(DataDir, Filename), Opts = [return, warn_unused_vars,{outdir,DataDir}], - ok = file:write_file(XrlFile, Def), + ok = file:write_file(XrlFile, Def, [{encoding, unicode}]), LOpts = [return, {report, false} | case Pre of default -> diff --git a/lib/parsetools/test/yecc_SUITE.erl b/lib/parsetools/test/yecc_SUITE.erl index 38bcd52ffc..d308d21f82 100644 --- a/lib/parsetools/test/yecc_SUITE.erl +++ b/lib/parsetools/test/yecc_SUITE.erl @@ -48,7 +48,8 @@ otp_5369/1, otp_6362/1, otp_7945/1, otp_8483/1, otp_8486/1, - otp_7292/1, otp_7969/1, otp_8919/1, otp_10302/1, otp_11269/1]). + otp_7292/1, otp_7969/1, otp_8919/1, otp_10302/1, otp_11269/1, + otp_11286/1]). % Default timetrap timeout (set in init_per_testcase). -define(default_timeout, ?t:minutes(1)). @@ -76,7 +77,7 @@ groups() -> {bugs, [], [otp_5369, otp_6362, otp_7945, otp_8483, otp_8486]}, {improvements, [], [otp_7292, otp_7969, otp_8919, otp_10302, - otp_11269]}]. + otp_11269, otp_11286]}]. init_per_suite(Config) -> Config. @@ -1995,6 +1996,64 @@ otp_11269(Config) when is_list(Config) -> {ok,'OTP-11269',_Warnings} = compile:file(ErlFile, Opts), ok. +otp_11286(doc) -> + "OTP-11286. A Unicode filename bug; both Leex and Yecc."; +otp_11286(suite) -> []; +otp_11286(Config) when is_list(Config) -> + Node = start_node(otp_11286, "+fnu"), + Dir = ?privdir, + UName = [1024] ++ "u", + UDir = filename:join(Dir, UName), + ok = rpc:call(Node, file, make_dir, [UDir]), + + %% Note: Cannot use UName as filename since the filename is used + %% as module name. To be fixed in R18. + Filename = filename:join(UDir, 'OTP-11286.yrl'), + Ret = [return, {report, false}, time], + + Mini1 = <<"%% coding: utf-8 + Terminals t. + Nonterminals nt. + Rootsymbol nt. + nt -> t.">>, + ok = rpc:call(Node, file, write_file, [Filename, Mini1]), + {ok,ErlFile,[]} = rpc:call(Node, yecc, file, [Filename, Ret]), + Opts = [return, warn_unused_vars,{outdir,Dir}], + {ok,_,_Warnings} = rpc:call(Node, compile, file, [ErlFile, Opts]), + + Mini2 = <<"Terminals t. + Nonterminals nt. + Rootsymbol nt. + nt -> t.">>, + ok = rpc:call(Node, file, write_file, [Filename, Mini2]), + {ok,ErlFile,[]} = rpc:call(Node, yecc, file, [Filename, Ret]), + Opts = [return, warn_unused_vars,{outdir,Dir}], + {ok,_,_Warnings} = rpc:call(Node, compile, file, [ErlFile, Opts]), + + Mini3 = <<"%% coding: latin-1 + Terminals t. + Nonterminals nt. + Rootsymbol nt. + nt -> t.">>, + ok = rpc:call(Node, file, write_file, [Filename, Mini3]), + {ok,ErlFile,[]} = rpc:call(Node, yecc, file, [Filename, Ret]), + Opts = [return, warn_unused_vars,{outdir,Dir}], + {ok,_,_Warnings} = rpc:call(Node, compile, file, [ErlFile, Opts]), + + true = test_server:stop_node(Node), + ok. + +start_node(Name, Args) -> + [_,Host] = string:tokens(atom_to_list(node()), "@"), + ct:log("Trying to start ~w@~s~n", [Name,Host]), + case test_server:start_node(Name, peer, [{args,Args}]) of + {error,Reason} -> + test_server:fail(Reason); + {ok,Node} -> + ct:log("Node ~p started~n", [Node]), + Node + end. + yeccpre_size() -> yeccpre_size(default_yeccpre()). diff --git a/lib/parsetools/vsn.mk b/lib/parsetools/vsn.mk index 444caf44a1..d62962c54a 100644 --- a/lib/parsetools/vsn.mk +++ b/lib/parsetools/vsn.mk @@ -1 +1 @@ -PARSETOOLS_VSN = 2.0.9 +PARSETOOLS_VSN = 2.0.10 diff --git a/lib/percept/doc/src/notes.xml b/lib/percept/doc/src/notes.xml index 391f4d6d47..3cead186c4 100644 --- a/lib/percept/doc/src/notes.xml +++ b/lib/percept/doc/src/notes.xml @@ -32,6 +32,23 @@ </header> <p>This document describes the changes made to the Percept application.</p> +<section><title>Percept 0.8.8.2</title> + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + The encoding of the <c>notes.xml</c> file has been + changed from latin1 to utf-8 to avoid future merge + problems.</p> + <p> + Own Id: OTP-11310</p> + </item> + </list> + </section> + +</section> + <section><title>Percept 0.8.8.1</title> <section><title>Improvements and New Features</title> diff --git a/lib/percept/vsn.mk b/lib/percept/vsn.mk index 2ea0341ddf..99729c11e2 100644 --- a/lib/percept/vsn.mk +++ b/lib/percept/vsn.mk @@ -1 +1 @@ -PERCEPT_VSN = 0.8.8.1 +PERCEPT_VSN = 0.8.8.2 diff --git a/lib/public_key/asn1/PKCS-7.asn1 b/lib/public_key/asn1/PKCS-7.asn1 index a6dfd57d80..e76f928acb 100644 --- a/lib/public_key/asn1/PKCS-7.asn1 +++ b/lib/public_key/asn1/PKCS-7.asn1 @@ -78,6 +78,49 @@ signingTime ATTRIBUTE ::= { SigningTime ::= Time -- imported from ISO/IEC 9594-8 +-- begin added for VCE SCEP-support +transactionID ATTRIBUTE ::= { + WITH SYNTAX PrintableString + ID id-transId +} + +messageType ATTRIBUTE ::= { + WITH SYNTAX PrintableString + ID id-messageType +} + +pkiStatus ATTRIBUTE ::= { + WITH SYNTAX PrintableString + ID id-pkiStatus +} + +failInfo ATTRIBUTE ::= { + WITH SYNTAX PrintableString + ID id-failInfo +} + +senderNonce ATTRIBUTE ::= { + WITH SYNTAX OCTET STRING + ID id-senderNonce +} + +recipientNonce ATTRIBUTE ::= { + WITH SYNTAX OCTET STRING + ID id-recipientNonce +} + +-- This is the authenticatedAttributes -member from SignerInfo +-- added here to generate decode/encode functions for it which are +-- needed to build the pkcs-7 used by SCEP, the resulting encoding are +-- used to make a signed digest +SignerInfoAuthenticatedAttributes ::= CHOICE { + aaSet [0] IMPLICIT SET OF AttributePKCS-7 {{Authenticated}}, + aaSequence [2] EXPLICIT SEQUENCE OF AttributePKCS-7 {{Authenticated}} + -- Explicit because easier to compute digest on sequence of attributes and then reuse + -- encoded sequence in aaSequence. + } +-- end added for VCE SCEP-support + -- Also defined in X.509 -- Redeclared here as a parameterized type @@ -224,12 +267,9 @@ SignerInfo ::= SEQUENCE { issuerAndSerialNumber IssuerAndSerialNumber, digestAlgorithm DigestAlgorithmIdentifier, - authenticatedAttributes CHOICE { - aaSet [0] IMPLICIT SET OF AttributePKCS-7 {{Authenticated}}, - aaSequence [2] EXPLICIT SEQUENCE OF AttributePKCS-7 {{Authenticated}} - -- Explicit because easier to compute digest on sequence of attributes and then reuse - -- encoded sequence in aaSequence. - } OPTIONAL, + -- Added explicit type for authenticatedAttributes to be able to + -- encode/decode this type separately + authenticatedAttributes SignerInfoAuthenticatedAttributes OPTIONAL, digestEncryptionAlgorithm DigestEncryptionAlgorithmIdentifier, encryptedDigest EncryptedDigest, @@ -247,7 +287,15 @@ SignerInfo ::= SEQUENCE { Authenticated ATTRIBUTE ::= { contentType | - messageDigest, + messageDigest | +-- begin added for VCE SCEP-support + transactionID | + messageType | + pkiStatus | + failInfo | + senderNonce | + recipientNonce, +-- end added for VCE SCEP-support ..., -- add application-specific attributes here signingTime } @@ -384,4 +432,18 @@ signedAndEnvelopedData OBJECT IDENTIFIER ::= { pkcs-7 4 } digestedData OBJECT IDENTIFIER ::= { pkcs-7 5 } encryptedData OBJECT IDENTIFIER ::= { pkcs-7 6 } +-- begin added for VCE SCEP-support +id-VeriSign OBJECT IDENTIFIER ::= {2 16 us(840) 1 veriSign(113733)} +id-pki OBJECT IDENTIFIER ::= {id-VeriSign pki(1)} +id-attributes OBJECT IDENTIFIER ::= {id-pki attributes(9)} +id-messageType OBJECT IDENTIFIER ::= {id-attributes messageType(2)} +id-pkiStatus OBJECT IDENTIFIER ::= {id-attributes pkiStatus(3)} +id-failInfo OBJECT IDENTIFIER ::= {id-attributes failInfo(4)} +id-senderNonce OBJECT IDENTIFIER ::= {id-attributes senderNonce(5)} +id-recipientNonce OBJECT IDENTIFIER ::= {id-attributes recipientNonce(6)} +id-transId OBJECT IDENTIFIER ::= {id-attributes transId(7)} +id-extensionReq OBJECT IDENTIFIER ::= {id-attributes extensionReq(8)} +-- end added for VCE SCEP-support + + END diff --git a/lib/public_key/doc/src/notes.xml b/lib/public_key/doc/src/notes.xml index e18d350dc5..add324dae2 100644 --- a/lib/public_key/doc/src/notes.xml +++ b/lib/public_key/doc/src/notes.xml @@ -34,6 +34,29 @@ <file>notes.xml</file> </header> +<section><title>Public_Key 0.20</title> + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Extend PKCS-7 to support SCEP (Simple Certificate + Enrollment Protocol).</p> + <p> + Own Id: OTP-10874</p> + </item> + <item> + <p> + public_key:pem_entry_decode/2 now handles AES-128-CBC + ciphered keys. Thanks to Simon Cornish.</p> + <p> + Own Id: OTP-11281</p> + </item> + </list> + </section> + +</section> + <section><title>Public_Key 0.19</title> <section><title>Improvements and New Features</title> diff --git a/lib/public_key/doc/src/using_public_key.xml b/lib/public_key/doc/src/using_public_key.xml index 267a76ab65..450bd7e35f 100644 --- a/lib/public_key/doc/src/using_public_key.xml +++ b/lib/public_key/doc/src/using_public_key.xml @@ -350,7 +350,7 @@ ok</code> <p> or </p> - <code>1> PemBin = public_key:pem_entry_encode('SubjectPublicKeyInfo', RSAPubKey). + <code>1> PemEntry = public_key:pem_entry_encode('SubjectPublicKeyInfo', RSAPubKey). {'SubjectPublicKeyInfo', <<48,92...>>, not_encrypted} 2> PemBin = public_key:pem_encode([PemEntry]). diff --git a/lib/public_key/src/pubkey_pbe.erl b/lib/public_key/src/pubkey_pbe.erl index 6f0be53db9..460624163b 100644 --- a/lib/public_key/src/pubkey_pbe.erl +++ b/lib/public_key/src/pubkey_pbe.erl @@ -66,7 +66,13 @@ decode(Data, Password,"DES-EDE3-CBC" = Cipher, KeyDevParams) -> decode(Data, Password,"RC2-CBC"= Cipher, KeyDevParams) -> {Key, IV} = password_to_key_and_iv(Password, Cipher, KeyDevParams), - crypto:block_decrypt(rc2_cbc, Key, IV, Data). + crypto:block_decrypt(rc2_cbc, Key, IV, Data); + +decode(Data, Password,"AES-128-CBC"= Cipher, IV) -> + %% PKCS5_SALT_LEN is 8 bytes + <<Salt:8/binary,_/binary>> = IV, + {Key, _} = password_to_key_and_iv(Password, Cipher, Salt), + crypto:block_decrypt(aes_cbc128, Key, IV, Data). %%-------------------------------------------------------------------- -spec pbdkdf1(string(), iodata(), integer(), atom()) -> binary(). @@ -200,7 +206,9 @@ derived_key_length(Cipher,_) when (Cipher == ?'rc2CBC') or 16; derived_key_length(Cipher,_) when (Cipher == ?'des-EDE3-CBC') or (Cipher == "DES-EDE3-CBC") -> - 24. + 24; +derived_key_length(Cipher,_) when (Cipher == "AES-128-CBC") -> + 16. cipher(#'PBES2-params_encryptionScheme'{algorithm = ?'desCBC'}) -> "DES-CBC"; diff --git a/lib/public_key/src/public_key.erl b/lib/public_key/src/public_key.erl index cdbfe6e07c..a4b6b8ad15 100644 --- a/lib/public_key/src/public_key.erl +++ b/lib/public_key/src/public_key.erl @@ -118,6 +118,13 @@ pem_entry_decode({Asn1Type, CryptDer, {Cipher, Salt}} = PemEntry, is_list(Cipher) andalso is_binary(Salt) andalso erlang:byte_size(Salt) == 8 -> + do_pem_entry_decode(PemEntry, Password); +pem_entry_decode({Asn1Type, CryptDer, {"AES-128-CBC"=Cipher, IV}} = PemEntry, + Password) when is_atom(Asn1Type) andalso + is_binary(CryptDer) andalso + is_list(Cipher) andalso + is_binary(IV) andalso + erlang:byte_size(IV) == 16 -> do_pem_entry_decode(PemEntry, Password). %%-------------------------------------------------------------------- diff --git a/lib/public_key/test/pbe_SUITE.erl b/lib/public_key/test/pbe_SUITE.erl index 2c9b17478d..b68ffbd5fd 100644 --- a/lib/public_key/test/pbe_SUITE.erl +++ b/lib/public_key/test/pbe_SUITE.erl @@ -218,6 +218,14 @@ encrypted_private_key_info(Config) when is_list(Config) -> [{'PrivateKeyInfo', _, {"RC2-CBC",_}} = PubEntry2] = PemRc2Entry, KeyInfo = public_key:pem_entry_decode(PubEntry2, "password"), + %% key generated with ssh-keygen -N hello_aes -f aes_128_cbc_enc_key + {ok, PemAesCbc} = file:read_file(filename:join(Datadir, "aes_128_cbc_enc_key")), + + PemAesCbcEntry = public_key:pem_decode(PemAesCbc), + ct:print("Pem entry: ~p" , [PemAesCbcEntry]), + [{'RSAPrivateKey', _, {"AES-128-CBC",_}} = PubAesCbcEntry] = PemAesCbcEntry, + #'RSAPrivateKey'{} = public_key:pem_entry_decode(PubAesCbcEntry, "hello_aes"), + check_key_info(KeyInfo). diff --git a/lib/public_key/test/pbe_SUITE_data/aes_128_cbc_enc_key b/lib/public_key/test/pbe_SUITE_data/aes_128_cbc_enc_key new file mode 100644 index 0000000000..34c7543f30 --- /dev/null +++ b/lib/public_key/test/pbe_SUITE_data/aes_128_cbc_enc_key @@ -0,0 +1,30 @@ +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: AES-128-CBC,D64FF97327558643763BE17BD50FDDAD + +oS4LbrLbQHPxfQILHl0KPswnkC1QqJ4RX6SkcQGVoYJJkPcavupABDYD1PSJf/MD +aPiN2OHsYAFLHxa1NGEAH6wKSvgdUJyaQ6jbSBNh9we9p2i3tpMnWsJMCZzXsCQh +RJj23/cFhb2UsqPM3OH6x6/VxX5VmD9Dnt1iU9b+WS6KdU45zP+QWpRd54uBrFab +Pw0kW7o84VFH6ahUDnzT8JUIk4P4G43G2F7wrOCbiK6AS0S8sCh5E83MrGEoJ6jB +NIW4xnLdBOLeV65NTgwWEn7bjLz+8IYSg2/wodjj5GL/ciMgiF+/krdQhzbHJhcm +dXV3SB/lTyjYUUGYU/3wm10f0iLJLFZxVU70yfV0eKhdYtWdR+2RxZjHvstBTGoI +BMtcaGwfMBh3wBHjS2M9AVh35DUYQIGW6QATf1VF+chhgESj6Qktkmfe4R9uAhP0 +r8Qkql/lq19K653c6ZIcUIYWvpAQ4Y/Q6Fdd92GY45FQdXYlZ/dXkwdq+ZYAhe6g +GUNmpwHf5N2a6lgXR3YytPYdhQbYMdy29RjXJsFWJh3sKTxgG/Y+FX2Ua7J1G4IW +wO6yZgQc9GyYzNn1TpT/TQ32GuHbw0u/oQqbNOJEjE0BTsQelEPpnNnEmkgPqSlI +3PNtsBvS6antvJ3CiCnmkQlT7/dLR9ym8nU+jo/hrtIStNUrdopCLB4+iUt7tJdz +jpW3Kc5fWmnGbp1UOXHoOghENfjIN+yUxIx9qCgBmWliY1nncUgzEHM34eGqGdek +nf6PowS4gIbJmO5Uc+0MwPld5HFou21da2M48FKolp3+CO1mX5MhvMLGVoFqNiE3 +dXYJG4bcMdxZncdaMn+c6ycA9iFTufF/qZPF/rGO5I+gc9M50bJjewbixqXM/LJ5 +1OnP/x7DN1Td3PTjAfjFX9yLWRMIjbihG43Htk5bOifaBtnOYj1e7WMjN8uBx91x +OCnfC3rngF4B9WmdYEkEvp9QZixbDlp0oh6/4HiRjjDkUfADnKuU/At7dd8sDOGD +NgaWVskJsulp8d9s3CozM7LmowlNpHV9BvAguckx/B7ZqV10mgAKOqZKk4LDlu2Y +MgQvSLJfyJsz/1q4z4jcXhYtSuZXXHk9lX9dgCZbQfVGnlsptNuV5KwupV2cz0Vi +Uh1mwvDXWFNIFwexZi0z27FJ1pKAKK+sf/GFqoAvdmYgYS6d5bmxh68bGZMZ2C6P +eehHkEZm1pv4CVDxrUTk+bNtqhDXglSdfxR0Xm1QDN95hM0dHq1kDZH6HgD6krJ6 +BBfd7mPRExH3+5JSQXoSUDO8LqP5phxLWKS0B8HDburnP/x9QzBOIKvmtDF1lQEk +FAI/6Lv8GJ0R7WYd2vFfGeqS94iw1BpmO/xS6WINOFpfwVCBuuYmLEdEWcXJgvy9 +zyaTX/mk1RMXo7I1X7aWviaIF7ykGxs1dJdrxQonwJ3oyTySNl2xf8bziKlqB/Ml +LDjeMNX91G8fJE0MdKPWd94PUoLN0CutM5sY5yHzwCvJQV9oQ1qvrQYUbnvtCEyQ +xT+bawt+ODgVb/QnyNeiIyEN5lXc8meJFLr1uMeEwX8WaJ7/KBKGk1V0XqVZTmga +-----END RSA PRIVATE KEY----- diff --git a/lib/public_key/test/public_key_SUITE.erl b/lib/public_key/test/public_key_SUITE.erl index c3aa2e2366..f8d167e770 100644 --- a/lib/public_key/test/public_key_SUITE.erl +++ b/lib/public_key/test/public_key_SUITE.erl @@ -46,7 +46,7 @@ all() -> groups() -> [{pem_decode_encode, [], [dsa_pem, rsa_pem, encrypted_pem, - dh_pem, cert_pem, pkcs10_pem]}, + dh_pem, cert_pem, pkcs7_pem, pkcs10_pem]}, {ssh_public_key_decode_encode, [], [ssh_rsa_public_key, ssh_dsa_public_key, ssh_rfc4716_rsa_comment, ssh_rfc4716_dsa_comment, ssh_rfc4716_rsa_subject, ssh_known_hosts, @@ -188,15 +188,9 @@ dh_pem() -> [{doc, "DH parametrs PEM-file decode/encode"}]. dh_pem(Config) when is_list(Config) -> Datadir = ?config(data_dir, Config), - [{'DHParameter', DerDH, not_encrypted} = Entry] = + [{'DHParameter', _DerDH, not_encrypted} = Entry] = erl_make_certs:pem_to_der(filename:join(Datadir, "dh.pem")), - - erl_make_certs:der_to_pem(filename:join(Datadir, "new_dh.pem"), [Entry]), - - DHParameter = public_key:der_decode('DHParameter', DerDH), - DHParameter = public_key:pem_entry_decode(Entry), - - Entry = public_key:pem_entry_encode('DHParameter', DHParameter). + asn1_encode_decode(Entry). %%-------------------------------------------------------------------- @@ -204,57 +198,38 @@ pkcs10_pem() -> [{doc, "PKCS-10 PEM-file decode/encode"}]. pkcs10_pem(Config) when is_list(Config) -> Datadir = ?config(data_dir, Config), - [{'CertificationRequest', DerPKCS10, not_encrypted} = Entry] = + [{'CertificationRequest', _DerPKCS10, not_encrypted} = Entry] = erl_make_certs:pem_to_der(filename:join(Datadir, "req.pem")), - - erl_make_certs:der_to_pem(filename:join(Datadir, "new_req.pem"), [Entry]), - - PKCS10 = public_key:der_decode('CertificationRequest', DerPKCS10), - PKCS10 = public_key:pem_entry_decode(Entry), - - Entry = public_key:pem_entry_encode('CertificationRequest', PKCS10). - + asn1_encode_decode(Entry). %%-------------------------------------------------------------------- pkcs7_pem() -> [{doc, "PKCS-7 PEM-file decode/encode"}]. pkcs7_pem(Config) when is_list(Config) -> Datadir = ?config(data_dir, Config), - [{'ContentInfo', DerPKCS7, not_encrypted} = Entry] = + [{'ContentInfo', _, not_encrypted} = Entry0] = erl_make_certs:pem_to_der(filename:join(Datadir, "pkcs7_cert.pem")), - - erl_make_certs:der_to_pem(filename:join(Datadir, "new_pkcs7_cert.pem"), [Entry]), - - PKCS7 = public_key:der_decode('ContentInfo', DerPKCS7), - PKCS7 = public_key:pem_entry_decode(Entry), - - Entry = public_key:pem_entry_encode('ContentInfo', PKCS7). - + [{'ContentInfo', _, not_encrypted} = Entry1] = + erl_make_certs:pem_to_der(filename:join(Datadir, "pkcs7_ext.pem")), + asn1_encode_decode(Entry0), + asn1_encode_decode(Entry1). + %%-------------------------------------------------------------------- cert_pem() -> [{doc, "Certificate PEM-file decode/encode"}]. cert_pem(Config) when is_list(Config) -> Datadir = ?config(data_dir, Config), - - [Entry0] = - erl_make_certs:pem_to_der(filename:join(Datadir, "dsa.pem")), - - [{'Certificate', DerCert, not_encrypted} = Entry7] = + + [{'Certificate', _, not_encrypted} = Entry0] = erl_make_certs:pem_to_der(filename:join(Datadir, "client_cert.pem")), - Cert = public_key:der_decode('Certificate', DerCert), - Cert = public_key:pem_entry_decode(Entry7), + asn1_encode_decode(Entry0), - CertEntries = [{'Certificate', _, not_encrypted} = CertEntry0, - {'Certificate', _, not_encrypted} = CertEntry1] = + [{'Certificate', _, not_encrypted} = Entry1, + {'Certificate', _, not_encrypted} = Entry2] = erl_make_certs:pem_to_der(filename:join(Datadir, "cacerts.pem")), - - ok = erl_make_certs:der_to_pem(filename:join(Datadir, "wcacerts.pem"), CertEntries), - ok = erl_make_certs:der_to_pem(filename:join(Datadir, "wdsa.pem"), [Entry0]), - NewCertEntries = erl_make_certs:pem_to_der(filename:join(Datadir, "wcacerts.pem")), - true = lists:member(CertEntry0, NewCertEntries), - true = lists:member(CertEntry1, NewCertEntries), - [Entry0] = erl_make_certs:pem_to_der(filename:join(Datadir, "wdsa.pem")). + asn1_encode_decode(Entry1), + asn1_encode_decode(Entry2). %%-------------------------------------------------------------------- ssh_rsa_public_key() -> @@ -720,6 +695,12 @@ pkix_iso_dsa_oid(Config) when is_list(Config) -> %%-------------------------------------------------------------------- %% Internal functions ------------------------------------------------ %%-------------------------------------------------------------------- +asn1_encode_decode({Asn1Type, Der, not_encrypted} = Entry) -> + Decoded = public_key:der_decode(Asn1Type, Der), + Decoded = public_key:pem_entry_decode(Entry), + Entry = public_key:pem_entry_encode(Asn1Type, Decoded), + ok. + check_countryname({rdnSequence,DirName}) -> do_check_countryname(DirName). do_check_countryname([]) -> diff --git a/lib/public_key/test/public_key_SUITE_data/pkcs7_ext.pem b/lib/public_key/test/public_key_SUITE_data/pkcs7_ext.pem new file mode 100644 index 0000000000..d7a1d01fe1 --- /dev/null +++ b/lib/public_key/test/public_key_SUITE_data/pkcs7_ext.pem @@ -0,0 +1,62 @@ +-----BEGIN PKCS7----- +MIILCAYJKoZIhvcNAQcCoIIK+TCCCvUCAQExDjAMBggqhkiG9w0CBQUAMIIFmwYJ +KoZIhvcNAQcBoIIFjASCBYgwggWEBgkqhkiG9w0BBwOgggV1MIIFcQIBADGCAmQw +ggJgAgEAMEgwPDELMAkGA1UEBhMCU0UxETAPBgNVBAoMCEVyaWNzc29uMRowGAYD +VQQDDBFWQ19SQlNfU3ViQ0FfVjNfMQIIcw3ZS5VSTIwwDQYJKoZIhvcNAQEBBQAE +ggIAFW0vd8wY2FJ87KVyUqcdK5uCmnjwC6uPbypDqnL44Fe4iAAiNOvmqt1Crm46 +pg9gOq50NbrRb+PY+UUM7lEUNNKZ61cul2iwGwp6r41l05EbMqgfsNoJkH+bTM8Y +YhME4sT+AzdmPHIg1PGoM+pAMHzpjcdnaHFSlfSmwq5xfZwWelR2TDz7arO+AKCk +DVIEnG9qHBrUWvDoT23VDVQQXP5Uja0Nml7B7Jt2RW2EKAiCAYDujkjIWcGy3F3X +2Q+Nm4K2nJKnkdMI5kS0Eu9uHp24VHn98sEyqn8rDiLFOaj5BskQIVMDN6npssgr +X4ChmBiVcquaxCoHMqQYGa/Jrd66C8WK2lQH3NpDCsULS+m6Z76bvXDFyL0K6rEP +sOcn8J91LfB5jXeSvS3vi7zk07M/IwAL03fVKvqiKU65D4859AOgbjkGyytWG1iv +t7ENh6GYHGJj71L+OlZZH25cJQ/2gGsYs4IYrT6w4Z1X5TscOL/tBiCDdTwcdT0q ++YdkL9ZONouHvgszb9IFvfFErzmmG7jTHwC/TzR0nC8vPog9+y05G4vnD1h7lzH7 +8xDsGrn86gcjYXXRPfc4AxDZfmaM8S0SFmd+O7B24sUKmSyxF3A7OVnb0/rTMuez +Izoy6RW9WQpCJM5R9k7YFDI5lQI+PiKT8GqzQuFIFXRYwOIwggMCBgkqhkiG9w0B +BwEwEQYFKw4DAgcECLsGKZ/iQ1HBgIIC4J1lxb/gn6EosJyMrTV8KnJxvD+Garzp +zmrDNvl9Q7CHmpNLuW3dngU5JcB5dElq7B+j6+RXNkupcrd2dvllAmwfPpFblmNp +Snsn99TTwDYv4LrpxNCcoIKSm93H28wfszhPv75zD9+/aIy4JK4UwYuv+p5JHfLW +EhvWO4pxUc2YpB8jiUVKTJJcRohry/lwvXu5s8VjmpoADSflHtAA4DUhFKX2fafu +Ux7muxbh7xFViNY6laQ/tuZuxxjs2Eb5aWWizO00cyLP2724vFQL+lnvyAvtSmcD +z2hOeOvvch6sJ4krx/gFznqe/lVksPyJQOj+Or8RTbC26kV4GQwiuGqgp6zhNjYe +4niPvGxVAFz8Qdv8Zu47fSHgI2nz5YlWuE2NiQ1qtCbMsf2k/NnZrTgx2oZxnZvL +B2We2D0u6BRZo4XMvGUqOLlGIV5scusv39/sBblJGOwNjtekG/pIRmiHXuI+RQOX +yr4tLR8clylf/HEMmYn2UVxXXuWsEr6zdBB3u3JhXhq+YmDpYYnTkxZq4nTz7oMY +MicrF0+iUrun6lIAXEU6yOSPehje5PfZW5PqKlpugKYIQSsbuJ4t/8n/MczHbRk9 +CcIX05OeWUdxRPKYa7Jt8umXnuIqWu7s7uZpbiB/tmuW4Cp16xUv53SgrTm4tiMq +b7O3ftMmEiFZ+uXds/ODfh7bTe4YlWdyimkCcyI4dcIjLxe+ifx4T+b4LktIc5Pd +5MHwAN+F1yIWnPxi8Nep9Pnw4HiX/ZkL0jHG0msZgZ60jb1U3LV4w3VI1WrsjvJM +6M+l7HM3xeTl9posjVQPxb7kyX5s6gDe4IaatPrNYcsDJ4t43v/se/nvlrQtkJzv +D4S2a9l833kYIC0MvoT8dqJuwySPZxjK0Io69sd6Af1BTGBoSQL75pOntrQUhICl +/kfjBkG5h6tpJFSZQEReK3Kg9rKIax5VwgQUte2yVu3EYARd3YZ7On+gggMTMIID +DzCCAfegAwIBAgITAkxY3LTPyvVkS5SUobGvznBgQDANBgkqhkiG9w0BAQUFADBC +MQswCQYDVQQGEwJTRTERMA8GA1UEChMIRXJpY3Nzb24xIDAeBgNVBAMTF0M4MjYx +MjQ1ODEuZXJpY3Nzb24uY29tMB4XDTEzMDgyMTE1MTcwM1oXDTE0MDgyMTE1MTcw +M1owQjELMAkGA1UEBhMCU0UxETAPBgNVBAoTCEVyaWNzc29uMSAwHgYDVQQDExdD +ODI2MTI0NTgxLmVyaWNzc29uLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC +AQoCggEBAPgg9zlAP6Z8vDMq+Ux0mq1RPLLtG2kByeauGvKdzbRLxtiyyKlknFQ8 +jdn8w3NrQiXTYSEcR0eDWjpLiwvkW2WC+lARIHUWQjRJWQIaSQ1lu9rDHlMYr2xm +6EF6QDgr/9fqkY1IrF/gEAwnNQhT44qCzSr/jqmf5phd5qslzYlpYY97yeEihiCT +wa/BNl1puS3+ayXI9e73Fpeysd0+TFjgbUwhUZn8kcKnDiynb19cyKzk4F1MQHwu +QDFUkxtFcKMW8GikjEYy0Gw8CJUPl4SedtwoU4PGhWqgA/vYOPhdP6LfSBhTmU3s +tUrFxUuMAiRF24JHdTj2bv+huDotWu0CAwEAATANBgkqhkiG9w0BAQUFAAOCAQEA +PtB1eG9FbriUPD79Kb5uyt15JoROPDBc3voR9HffqDsANyEJ3VPlvAFEyrQzbdnA +V5slZRR7M5AJBha1K3BIR7Cs74BlCXiiuWi358HnPGsHqqJjKVxlTKJksrRLvUr4 +K2bG1kBniQU/PkSZjB1DbSwAqw4So9BKLbzQFE8888/yETeCIEWnG2YMiRe1GB0r +P/88QJctNrsT5oLdZ9E4igcAoGna6UR71PJSFCBoJ5WsnofMf44gZr7bgg2szoZr +KDPnrlsi9SM4nWzTaxSTjEp3397QMwEHosJxwXv/Zy5QyGBDYfynaTRUVS2BwIfo +AqRdylyrbv/+3NBQxdERRjGCAigwggIkAgEBMFkwQjELMAkGA1UEBhMCU0UxETAP +BgNVBAoTCEVyaWNzc29uMSAwHgYDVQQDExdDODI2MTI0NTgxLmVyaWNzc29uLmNv +bQITAkxY3LTPyvVkS5SUobGvznBgQDAMBggqhkiG9w0CBQUAoIGiMBIGCmCGSAGG ++EUBCQIxBBMCMTkwGAYJKoZIhvcNAQkDMQsGCSqGSIb3DQEHATAfBgkqhkiG9w0B +CQQxEgQQaEUDvpv6H163UM7zAQiMvDAgBgpghkgBhvhFAQkFMRIEEN4FI8tal3of +ZTXKi1Ny2cswLwYKYIZIAYb4RQEJBzEhEx8yOUFBQjJFNTY5OUY1QjI1QTJEQUI3 +NDlGN0Q0QTFBMA0GCSqGSIb3DQEBAQUABIIBACnR54LqeHZ0u8bSErSnGupEytHK +xbfShraXl3DFPnIZYs0HUuuriw5/BhkFHBsSXO8Oqm759/UgxOjnCUD2AKHenGoK +LB0yqLGe/USBs0IkBv6lXg7HJhSDNqAPES6a5iUVIRv+M40Ldob570MKjZhERVPN +AVSHMJHKmtVTZGt/VqiVk0qqZeV9nqhaSPFyW9pQU0PKep0lFltnwCHUTZiiqHuk +SIpZFCmIgahAUcl/WrxiW4xC9L5+wBgsuaUU5LqLZwg3AFua0aaDs6NZXpSE0A43 +zm5whhmkVePjnSUUr78AoBRalsBdMkDwLoUZZ1Hhq+/WH+WW7TQ96zm+uzE= +-----END PKCS7----- + diff --git a/lib/public_key/vsn.mk b/lib/public_key/vsn.mk index b820f24d2a..72247f14d8 100644 --- a/lib/public_key/vsn.mk +++ b/lib/public_key/vsn.mk @@ -1 +1 @@ -PUBLIC_KEY_VSN = 0.19 +PUBLIC_KEY_VSN = 0.20 diff --git a/lib/reltool/doc/src/notes.xml b/lib/reltool/doc/src/notes.xml index 8aaf4cc5d3..df81418677 100644 --- a/lib/reltool/doc/src/notes.xml +++ b/lib/reltool/doc/src/notes.xml @@ -37,7 +37,24 @@ thus constitutes one section in this document. The title of each section is the version number of Reltool.</p> - <section><title>Reltool 0.6.4</title> + <section><title>Reltool 0.6.4.1</title> + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + The encoding of the <c>notes.xml</c> file has been + changed from latin1 to utf-8 to avoid future merge + problems.</p> + <p> + Own Id: OTP-11310</p> + </item> + </list> + </section> + +</section> + +<section><title>Reltool 0.6.4</title> <section><title>Fixed Bugs and Malfunctions</title> <list> @@ -61,7 +78,7 @@ even if the application was explicitly excluded in the config. This has been changed and will only produce a warning. If the application is not explicitly excluded it - will still cause reltool to fail. Thanks to H�kan + will still cause reltool to fail. Thanks to Håkan Mattsson!</p> <p> Own Id: OTP-10988</p> diff --git a/lib/reltool/vsn.mk b/lib/reltool/vsn.mk index 412e78f49f..16ec570d22 100644 --- a/lib/reltool/vsn.mk +++ b/lib/reltool/vsn.mk @@ -1 +1 @@ -RELTOOL_VSN = 0.6.4 +RELTOOL_VSN = 0.6.4.1 diff --git a/lib/runtime_tools/doc/src/notes.xml b/lib/runtime_tools/doc/src/notes.xml index db35eba436..b334bdcac2 100644 --- a/lib/runtime_tools/doc/src/notes.xml +++ b/lib/runtime_tools/doc/src/notes.xml @@ -31,6 +31,35 @@ <p>This document describes the changes made to the Runtime_Tools application.</p> +<section><title>Runtime_Tools 1.8.12</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + The process trace flag 'silent' is now allowed in call to + dbg:p/2.</p> + <p> + Own Id: OTP-11222</p> + </item> + </list> + </section> + + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Introduced functionality for inspection of system and + build configuration.</p> + <p> + Own Id: OTP-11196</p> + </item> + </list> + </section> + +</section> + <section><title>Runtime_Tools 1.8.11</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/runtime_tools/vsn.mk b/lib/runtime_tools/vsn.mk index 5faae06b53..9ee1aba29c 100644 --- a/lib/runtime_tools/vsn.mk +++ b/lib/runtime_tools/vsn.mk @@ -1 +1 @@ -RUNTIME_TOOLS_VSN = 1.8.11 +RUNTIME_TOOLS_VSN = 1.8.12 diff --git a/lib/sasl/doc/src/notes.xml b/lib/sasl/doc/src/notes.xml index 373d732e53..f42657c45e 100644 --- a/lib/sasl/doc/src/notes.xml +++ b/lib/sasl/doc/src/notes.xml @@ -30,6 +30,21 @@ </header> <p>This document describes the changes made to the SASL application.</p> +<section><title>SASL 2.3.3</title> + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Add Fd usage in rb logging. Thanks to Eric Pailleau.</p> + <p> + Own Id: OTP-11252</p> + </item> + </list> + </section> + +</section> + <section><title>SASL 2.3.2</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/snmp/doc/src/notes.xml b/lib/snmp/doc/src/notes.xml index 9c61bae85a..7514c52dda 100644 --- a/lib/snmp/doc/src/notes.xml +++ b/lib/snmp/doc/src/notes.xml @@ -34,6 +34,73 @@ <section> + <title>SNMP Development Toolkit 4.24.2</title> + <p>Version 4.24.2 supports code replacement in runtime from/to + version 4.24.1, 4.24, 4.23.1 and 4.23. </p> + + <section> + <title>Improvements and new features</title> +<!-- + <p>-</p> +--> + + <list type="bulleted"> + <item> + <p>[agent] Improved documentation for the functions for + loading and unloading mibs, + see <seealso marker="snmpa#load_mibs">load_mibs</seealso> and + <seealso marker="snmpa#unload_mibs">unload_mibs</seealso> for + more info. </p> + <p>Also added new functions for loading and unloading a single mib, + see <seealso marker="snmpa#load_mib">load_mib</seealso> and + <seealso marker="snmpa#unload_mib">unload_mib</seealso> for + more info. </p> + <p>Own Id: OTP-11216</p> + </item> + + </list> + + </section> + + <section> + <title>Fixed Bugs and Malfunctions</title> + <p>-</p> + +<!-- + <list type="bulleted"> + <item> + <p>[agent] + see <seealso marker="snmpa#load_mibs">load_mibs</seealso> and + <seealso marker="snmpa#unload_mibs">unload_mibs</seealso>. </p> + <p>Own Id: OTP-11216</p> + </item> + + </list> +--> + + </section> + + <section> + <title>Incompatibilities</title> + <p>-</p> + +<!-- + <list type="bulleted"> + <item> + <p>[manager] The old Addr-and-Port based API functions, previously + long deprecated and marked for deletion in R16B, has now been + removed. </p> + <p>Own Id: OTP-10027</p> + </item> + + </list> +--> + </section> + + </section> <!-- 4.24.2 --> + + + <section> <title>SNMP Development Toolkit 4.24.1</title> <p>Version 4.24.1 supports code replacement in runtime from/to version 4.24, 4.23.1 and 4.23. </p> @@ -147,7 +214,7 @@ <seealso marker="snmpa_mib_storage">mib storage</seealso>. At present there are three simple modules (<c>snmpa_mib_storage_ets</c>, <c>snmpa_mib_storage_dets</c> and - <c>snmpa_mib_storage_mnesia</c>) implement�ng this behaviour, + <c>snmpa_mib_storage_mnesia</c>) implementing this behaviour, provided with the app. </p> <p>A config option for the (agent) <seealso marker="snmp_config#agent_mib_storage">mib storage</seealso> diff --git a/lib/snmp/doc/src/snmpa.xml b/lib/snmp/doc/src/snmpa.xml index 7133cb08cc..a8b8d06eea 100644 --- a/lib/snmp/doc/src/snmpa.xml +++ b/lib/snmp/doc/src/snmpa.xml @@ -245,29 +245,75 @@ notification_delivery_info() = #snmpa_notification_delivery_info{} This function is used to convert to the old (pre-4.4) info format. </p> + <marker id="load_mib"></marker> + </desc> + </func> + + <func> + <name>load_mib(Mib) -> ok | {error, Reason}</name> + <name>load_mib(Agent, Mib) -> ok | {error, Reason}</name> + <fsummary>Load single MIB into the agent</fsummary> + <type> + <v>Agent = pid() | atom()</v> + <v>MibName = string()</v> + <v>Reason = already_loaded | term()</v> + </type> + <desc> + <p>Load a single <c>Mib</c> into an agent. The <c>MibName</c> + is the name of the Mib, including the path to where the compiled + mib is found. For example: </p> + <code type="none"> + Dir = code:priv_dir(my_app) ++ "/mibs/", + snmpa:load_mib(snmp_master_agent, Dir ++ "MY-MIB"). + </code> + <marker id="load_mibs"></marker> </desc> </func> <func> <name>load_mibs(Mibs) -> ok | {error, Reason}</name> - <name>load_mibs(Agent,Mibs) -> ok | {error, Reason}</name> + <name>load_mibs(Mibs, Force) -> ok | {error, Reason}</name> + <name>load_mibs(Agent, Mibs) -> ok | {error, Reason}</name> + <name>load_mibs(Agent, Mibs, Force) -> ok | {error, Reason}</name> <fsummary>Load MIBs into the agent</fsummary> <type> <v>Agent = pid() | atom()</v> <v>Mibs = [MibName]</v> + <v>Force = boolean()</v> <v>MibName = string()</v> - <v>Reason = term()</v> + <v>Reason = {'load aborted at', MibName, InternalReason}</v> + <v>InternalReason = already_loaded | term()</v> </type> <desc> - <p>Loads <c>Mibs</c> into an agent. If the agent cannot load - all MIBs, it will indicate where loading was aborted. The - <c>MibName</c> is the name of the Mib, including the path to - where the compiled mib is found. For example,</p> - <code type="none"> + <p>Load <c>Mibs</c> into an agent. If the agent cannot load all + MIBs (the default value of the <c>Force</c> argument is <c>false</c>), + it will indicate where loading was aborted. The <c>MibName</c> + is the name of the Mib, including the path to where the compiled + mib is found. For example,</p> + <code type="none"> Dir = code:priv_dir(my_app) ++ "/mibs/", snmpa:load_mibs(snmp_master_agent, [Dir ++ "MY-MIB"]). </code> + <p>If <c>Force = true</c> then the agent will continue attempting + to load each mib even after failing to load a previous mib. Use with + care. </p> + + <marker id="unload_mib"></marker> + </desc> + </func> + + <func> + <name>unload_mib(Mib) -> ok | {error, Reason}</name> + <name>unload_mib(Agent, Mib) -> ok | {error, Reason}</name> + <fsummary>Unload single MIB from the agent</fsummary> + <type> + <v>Agent = pid() | atom()</v> + <v>MibName = string()</v> + <v>Reason = not_loaded | term()</v> + </type> + <desc> + <p>Unload a single <c>Mib</c> from an agent. </p> <marker id="unload_mibs"></marker> </desc> @@ -275,16 +321,25 @@ notification_delivery_info() = #snmpa_notification_delivery_info{} <func> <name>unload_mibs(Mibs) -> ok | {error, Reason}</name> - <name>unload_mibs(Agent,Mibs) -> ok | {error, Reason}</name> + <name>unload_mibs(Mibs, Force) -> ok | {error, Reason}</name> + <name>unload_mibs(Agent, Mibs) -> ok | {error, Reason}</name> + <name>unload_mibs(Agent, Mibs, Force) -> ok | {error, Reason}</name> <fsummary>Unload MIBs from the agent</fsummary> <type> <v>Agent = pid() | atom()</v> <v>Mibs = [MibName]</v> + <v>Force = boolean()</v> <v>MibName = string()</v> + <v>Reason = {'unload aborted at', MibName, InternalReason}</v> + <v>InternalReason = not_loaded | term()</v> </type> <desc> - <p>Unloads MIBs into an agent. If it cannot unload all MIBs, - it will indicate where unloading was aborted. </p> + <p>Unload <c>Mibs</c> from an agent. If it cannot unload all MIBs + (the default value of the <c>Force</c> argument is <c>false</c>), + it will indicate where unloading was aborted. </p> + <p>If <c>Force = true</c> then the agent will continue attempting + to unload each mib even after failing to unload a previous mib. + Use with care. </p> <marker id="which_mibs"></marker> </desc> diff --git a/lib/snmp/doc/src/snmpa_mib_data.xml b/lib/snmp/doc/src/snmpa_mib_data.xml index ff07a03b98..c1ea0a91f9 100644 --- a/lib/snmp/doc/src/snmpa_mib_data.xml +++ b/lib/snmp/doc/src/snmpa_mib_data.xml @@ -380,7 +380,7 @@ <desc> <p>Perform a code-change (upgrade or downgrade). </p> <p>See - <seealso marker="gen_server">gen_server</seealso> + <seealso marker="stdlib:gen_server">gen_server</seealso> for more info regarding the <c>Vsn</c> and <c>Extra</c> arguments. </p> </desc> diff --git a/lib/snmp/src/agent/snmpa.erl b/lib/snmp/src/agent/snmpa.erl index 14b93439df..a95e41ea42 100644 --- a/lib/snmp/src/agent/snmpa.erl +++ b/lib/snmp/src/agent/snmpa.erl @@ -39,8 +39,10 @@ enum_to_int/2, enum_to_int/3, info/0, info/1, old_info_format/1, - load_mibs/1, load_mibs/2, - unload_mibs/1, unload_mibs/2, + load_mib/1, load_mib/2, + load_mibs/1, load_mibs/2, load_mibs/3, + unload_mib/1, unload_mib/2, + unload_mibs/1, unload_mibs/2, unload_mibs/3, which_mibs/0, which_mibs/1, whereis_mib/1, whereis_mib/2, dump_mibs/0, dump_mibs/1, @@ -300,19 +302,75 @@ backup(Agent, BackupDir) -> dump_mibs() -> snmpa_agent:dump_mibs(snmp_master_agent). dump_mibs(File) -> snmpa_agent:dump_mibs(snmp_master_agent, File). + +load_mib(Mib) -> + load_mib(snmp_master_agent, Mib). + +-spec load_mib(Agent :: pid() | atom(), Mib :: string()) -> + ok | {error, Reason :: already_loaded | term()}. + +load_mib(Agent, Mib) -> + case load_mibs(Agent, [Mib]) of + {error, {'load aborted at', Mib, Reason}} -> + {error, Reason}; + Else -> + Else + end. + load_mibs(Mibs) -> - load_mibs(snmp_master_agent, Mibs). + load_mibs(snmp_master_agent, Mibs, false). load_mibs(Agent, Mibs) when is_list(Mibs) -> - snmpa_agent:load_mibs(Agent, Mibs). + snmpa_agent:load_mibs(Agent, Mibs, false); +load_mibs(Mibs, Force) + when is_list(Mibs) andalso ((Force =:= true) orelse (Force =:= false)) -> + load_mibs(snmp_master_agent, Mibs, Force). + +-spec load_mibs(Agent :: pid() | atom(), + Mibs :: [MibName :: string()], + Force :: boolean()) -> + ok | {error, {'load aborted at', MibName :: string(), InternalReason :: already_loaded | term()}}. + +load_mibs(Agent, Mibs, Force) + when is_list(Mibs) andalso ((Force =:= true) orelse (Force =:= false)) -> + snmpa_agent:load_mibs(Agent, Mibs, Force). + + +unload_mib(Mib) -> + unload_mib(snmp_master_agent, Mib). + +-spec unload_mib(Agent :: pid() | atom(), Mib :: string()) -> + ok | {error, Reason :: not_loaded | term()}. + +unload_mib(Agent, Mib) -> + case unload_mibs(Agent, [Mib]) of + {error, {'unload aborted at', Mib, Reason}} -> + {error, Reason}; + Else -> + Else + end. unload_mibs(Mibs) -> - unload_mibs(snmp_master_agent, Mibs). + unload_mibs(snmp_master_agent, Mibs, false). unload_mibs(Agent, Mibs) when is_list(Mibs) -> - snmpa_agent:unload_mibs(Agent, Mibs). + snmpa_agent:unload_mibs(Agent, Mibs); +unload_mibs(Mibs, Force) + when is_list(Mibs) andalso ((Force =:= true) orelse (Force =:= false)) -> + unload_mibs(snmp_master_agent, Mibs, Force). + +-spec unload_mibs(Agent :: pid() | atom(), + Mibs :: [MibName :: string()], + Force :: boolean()) -> + ok | {error, {'unload aborted at', MibName :: string(), InternalReason :: not_loaded | term()}}. + +unload_mibs(Agent, Mibs, Force) + when is_list(Mibs) andalso ((Force =:= true) orelse (Force =:= false)) -> + snmpa_agent:unload_mibs(Agent, Mibs, Force). + which_mibs() -> which_mibs(snmp_master_agent). which_mibs(Agent) -> snmpa_agent:which_mibs(Agent). + whereis_mib(Mib) -> whereis_mib(snmp_master_agent, Mib). whereis_mib(Agent, Mib) when is_atom(Mib) -> diff --git a/lib/snmp/src/agent/snmpa_agent.erl b/lib/snmp/src/agent/snmpa_agent.erl index c267ce5a70..9bed6e554e 100644 --- a/lib/snmp/src/agent/snmpa_agent.erl +++ b/lib/snmp/src/agent/snmpa_agent.erl @@ -28,7 +28,8 @@ %% External exports -export([start_link/4, start_link/5, stop/1]). -export([subagent_set/2, - load_mibs/2, unload_mibs/2, which_mibs/1, whereis_mib/2, info/1, + load_mibs/3, unload_mibs/3, + which_mibs/1, whereis_mib/2, info/1, register_subagent/3, unregister_subagent/2, send_notification/3, register_notification_filter/5, @@ -71,7 +72,8 @@ handle_pdu/8, worker/2, worker_loop/1, do_send_trap/7, do_send_trap/8]). %% <BACKWARD-COMPAT> --export([handle_pdu/7]). +-export([handle_pdu/7, + load_mibs/2, unload_mibs/2]). %% </BACKWARD-COMPAT> -include("snmpa_internal.hrl"). @@ -528,12 +530,22 @@ subagent_set(SubAgent, Arguments) -> %% Called by administrator (not agent; deadlock would occur) +%% <BACKWARD-COMPAT> load_mibs(Agent, Mibs) -> - call(Agent, {load_mibs, Mibs}). + load_mibs(Agent, Mibs, false). +%% </BACKWARD-COMPAT> + +load_mibs(Agent, Mibs, Force) -> + call(Agent, {load_mibs, Mibs, Force}). %% Called by administrator (not agent; deadlock would occur) +%% <BACKWARD-COMPAT> unload_mibs(Agent, Mibs) -> - call(Agent, {unload_mibs, Mibs}). + unload_mibs(Agent, Mibs, false). +%% </BACKWARD-COMPAT> + +unload_mibs(Agent, Mibs, Force) -> + call(Agent, {unload_mibs, Mibs, Force}). which_mibs(Agent) -> call(Agent, which_mibs). @@ -1216,13 +1228,25 @@ handle_call({unregister_subagent, SubTreeOid}, _From, S) -> end, {reply, Reply, S}; +%% <BACKWARD-COMPAT> handle_call({load_mibs, Mibs}, _From, S) -> ?vlog("load mibs ~p", [Mibs]), {reply, snmpa_mib:load_mibs(get(mibserver), Mibs), S}; +%% </BACKWARD-COMPAT> + +handle_call({load_mibs, Mibs, Force}, _From, S) -> + ?vlog("[~w] load mibs ~p", [Force, Mibs]), + {reply, snmpa_mib:load_mibs(get(mibserver), Mibs, Force), S}; +%% <BACKWARD-COMPAT> handle_call({unload_mibs, Mibs}, _From, S) -> ?vlog("unload mibs ~p", [Mibs]), {reply, snmpa_mib:unload_mibs(get(mibserver), Mibs), S}; +%% </BACKWARD-COMPAT> + +handle_call({unload_mibs, Mibs, Force}, _From, S) -> + ?vlog("[~w] unload mibs ~p", [Force, Mibs]), + {reply, snmpa_mib:unload_mibs(get(mibserver), Mibs, Force), S}; handle_call(which_mibs, _From, S) -> ?vlog("which mibs", []), diff --git a/lib/snmp/src/agent/snmpa_mib.erl b/lib/snmp/src/agent/snmpa_mib.erl index 031309b990..5b523447c5 100644 --- a/lib/snmp/src/agent/snmpa_mib.erl +++ b/lib/snmp/src/agent/snmpa_mib.erl @@ -26,7 +26,7 @@ %% External exports -export([start_link/3, stop/1, lookup/2, next/3, which_mib/2, which_mibs/1, whereis_mib/2, - load_mibs/2, unload_mibs/2, + load_mibs/3, unload_mibs/3, register_subagent/3, unregister_subagent/2, info/1, info/2, verbosity/2, dump/1, dump/2, backup/2, @@ -39,6 +39,10 @@ which_cache_size/1 ]). +%% <BACKWARD-COMPAT> +-export([load_mibs/2, unload_mibs/2]). +%% </BACKWARD-COMPAT> + %% Internal exports -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). @@ -182,19 +186,32 @@ next(MibServer, Oid, MibView) -> %%---------------------------------------------------------------------- %% Purpose: Loads mibs into the mib process. %% Args: Mibs is a list of Filenames (compiled mibs). +%% Force is a boolean %% Returns: ok | {error, Reason} %%---------------------------------------------------------------------- + +%% <BACKWARD-COMPAT> load_mibs(MibServer, Mibs) -> - call(MibServer, {load_mibs, Mibs}). + load_mibs(MibServer, Mibs, false). +%% </BACKWARD-COMPAT> + +load_mibs(MibServer, Mibs, Force) -> + call(MibServer, {load_mibs, Mibs, Force}). %%---------------------------------------------------------------------- %% Purpose: Loads mibs into the mib process. %% Args: Mibs is a list of Filenames (compiled mibs). +%% Force is a boolean %% Returns: ok | {error, Reason} %%---------------------------------------------------------------------- +%% <BACKWARD-COMPAT> unload_mibs(MibServer, Mibs) -> - call(MibServer, {unload_mibs, Mibs}). + unload_mibs(MibServer, Mibs, false). +%% </BACKWARD-COMPAT> + +unload_mibs(MibServer, Mibs, Force) -> + call(MibServer, {unload_mibs, Mibs, Force}). %%---------------------------------------------------------------------- @@ -323,10 +340,6 @@ do_init(Prio, Mibs, Opts) -> %% Returns: {ok, NewMibData} | {'aborted at', Mib, NewData, Reason} %% Args: Operation is load_mib | unload_mib. %%---------------------------------------------------------------------- -mib_operations(Mod, Operation, Mibs, Data, MeOverride, TeOverride) -> - mib_operations(Mod, Operation, Mibs, Data, MeOverride, TeOverride, false). - - mib_operations(_Mod, _Operation, [], Data, _MeOverride, _TeOverride, _Force) -> {ok, Data}; mib_operations(Mod, Operation, [Mib|Mibs], Data0, MeOverride, TeOverride, Force) -> @@ -451,18 +464,23 @@ handle_call({next, Oid, MibView}, _From, ?vdebug("next -> Reply: ~p", [Reply]), {reply, Reply, NewState}; -handle_call({load_mibs, Mibs}, _From, +%% <BACKWARD-COMPAT> +handle_call({load_mibs, Mibs}, From, State) -> + handle_call({load_mibs, Mibs, false}, From, State); +%% </BACKWARD-COMPAT> + +handle_call({load_mibs, Mibs, Force}, _From, #state{data = Data, teo = TeOverride, meo = MeOverride, cache = Cache, data_mod = Mod} = State) -> - ?vlog("load mibs ~p",[Mibs]), + ?vlog("[~w] load mibs ~p", [Force, Mibs]), %% Invalidate cache NewCache = maybe_invalidate_cache(Cache), {NData, Reply} = case (catch mib_operations(Mod, load_mib, Mibs, Data, - MeOverride, TeOverride)) of + MeOverride, TeOverride, Force)) of {'aborted at', Mib, NewData, Reason} -> ?vlog("aborted at ~p for reason ~p",[Mib,Reason]), {NewData, {error, {'load aborted at', Mib, Reason}}}; @@ -472,19 +490,24 @@ handle_call({load_mibs, Mibs}, _From, Mod:sync(NData), {reply, Reply, State#state{data = NData, cache = NewCache}}; -handle_call({unload_mibs, Mibs}, _From, +%% <BACKWARD-COMPAT> +handle_call({unload_mibs, Mibs}, From, State) -> + handle_call({unload_mibs, Mibs, false}, From, State); +%% </BACKWARD-COMPAT> + +handle_call({unload_mibs, Mibs, Force}, _From, #state{data = Data, teo = TeOverride, meo = MeOverride, cache = Cache, data_mod = Mod} = State) -> - ?vlog("unload mibs ~p",[Mibs]), + ?vlog("[~w] unload mibs ~p", [Force, Mibs]), %% Invalidate cache NewCache = maybe_invalidate_cache(Cache), %% Unload mib(s) {NData, Reply} = case (catch mib_operations(Mod, unload_mib, Mibs, Data, - MeOverride, TeOverride)) of + MeOverride, TeOverride, Force)) of {'aborted at', Mib, NewData, Reason} -> ?vlog("aborted at ~p for reason ~p", [Mib,Reason]), {NewData, {error, {'unload aborted at', Mib, Reason}}}; diff --git a/lib/snmp/src/app/snmp.appup.src b/lib/snmp/src/app/snmp.appup.src index 16b626111b..6edcf7e833 100644 --- a/lib/snmp/src/app/snmp.appup.src +++ b/lib/snmp/src/app/snmp.appup.src @@ -29,12 +29,22 @@ %% {add_module, snmpm_net_if_mt} [ + {"4.24.1", + [ + {load_module, snmpa, soft_purge, soft_purge, [snmpa_agent]}, + {update, snmpa_agent, soft, soft_purge, soft_purge, [snmpa_agent]}, + {update, snmpa_mib, soft, soft_purge, soft_purge, []} + ] + }, {"4.24", [ {load_module, snmp_conf, soft_purge, soft_purge, []}, {load_module, snmp_view_based_acm_mib, soft_purge, soft_purge, [snmp_conf]}, - {update, snmpa_local_db, soft, soft_purge, soft_purge, []} + {load_module, snmpa, soft_purge, soft_purge, [snmpa_agent]}, + {update, snmpa_local_db, soft, soft_purge, soft_purge, []}, + {update, snmpa_agent, soft, soft_purge, soft_purge, [snmpa_agent]}, + {update, snmpa_mib, soft, soft_purge, soft_purge, []} ] }, {"4.23.1", [{restart_application, snmp}]}, @@ -47,12 +57,22 @@ %% {remove, {snmpm_net_if_mt, soft_purge, soft_purge}} [ + {"4.24.1", + [ + {load_module, snmpa, soft_purge, soft_purge, [snmpa_agent]}, + {update, snmpa_agent, soft, soft_purge, soft_purge, [snmpa_agent]}, + {update, snmpa_mib, soft, soft_purge, soft_purge, []} + ] + }, {"4.24", [ {load_module, snmp_conf, soft_purge, soft_purge, []}, {load_module, snmp_view_based_acm_mib, soft_purge, soft_purge, [snmp_conf]}, - {update, snmpa_local_db, soft, soft_purge, soft_purge, []} + {load_module, snmpa, soft_purge, soft_purge, [snmpa_agent]}, + {update, snmpa_local_db, soft, soft_purge, soft_purge, []}, + {update, snmpa_agent, soft, soft_purge, soft_purge, [snmpa_agent]}, + {update, snmpa_mib, soft, soft_purge, soft_purge, []} ] }, {"4.23.1", [{restart_application, snmp}]}, diff --git a/lib/snmp/test/snmp_agent_mibs_test.erl b/lib/snmp/test/snmp_agent_mibs_test.erl index 248fe7d83e..f7dae64e3f 100644 --- a/lib/snmp/test/snmp_agent_mibs_test.erl +++ b/lib/snmp/test/snmp_agent_mibs_test.erl @@ -238,6 +238,8 @@ start_and_stop(Config) when is_list(Config) -> load_unload(suite) -> []; load_unload(Config) when is_list(Config) -> + ?DBG("load_unload -> start", []), + Prio = normal, Verbosity = log, MibDir = ?config(data_dir, Config), @@ -253,8 +255,10 @@ load_unload(Config) when is_list(Config) -> ?line ok = load_mibs(MibsPid, MibDir, ["Test2"]), ?line ok = verify_loaded_mibs(MibsPid, MibDir, ["Test2"]), - ?DBG("load_unload -> load one already loaded mib", []), - ?line {error, _} = load_mibs(MibsPid, MibDir, ["Test2"]), + ?DBG("load_unload -> try load one *already loaded* mib", []), + EMib = join(MibDir, "Test2"), + ?line {error, {'load aborted at', EMib, already_loaded}} = + load_mibs(MibsPid, MibDir, ["Test2"]), ?DBG("load_unload -> load 2 not already loaded mibs", []), ?line ok = load_mibs(MibsPid, MibDir, ["TestTrap", "TestTrapv2"]), @@ -266,7 +270,8 @@ load_unload(Config) when is_list(Config) -> ?line ok = verify_loaded_mibs(MibsPid, MibDir, ["TestTrap", "TestTrapv2"]), ?DBG("load_unload -> try unload two loaded mibs and one not loaded", []), - ?line {error, _} = unload_mibs(MibsPid, ["TestTrap","Test2","TestTrapv2"]), + ?line {error, {'unload aborted at', "Test2", not_loaded}} = + unload_mibs(MibsPid, ["TestTrap","Test2","TestTrapv2"]), ?line ok = verify_loaded_mibs(MibsPid, MibDir, ["TestTrapv2"]), ?DBG("load_unload -> unload the remaining loaded mib", []), @@ -279,6 +284,7 @@ load_unload(Config) when is_list(Config) -> ?DBG("load_unload -> stop symbolic store", []), ?line sym_stop(), + ?DBG("load_unload -> done", []), ok. @@ -691,10 +697,16 @@ mibs_info(Pid) -> load_mibs(Pid, Dir, Mibs0) -> Mibs = [join(Dir, Mib) || Mib <- Mibs0], - snmpa_mib:load_mibs(Pid, Mibs). + Res = snmpa_mib:load_mibs(Pid, Mibs), + %% ?DBG("load_mibs -> " + %% "~n Res: ~p", [Res]), + Res. unload_mibs(Pid, Mibs) -> - snmpa_mib:unload_mibs(Pid, Mibs). + Res = snmpa_mib:unload_mibs(Pid, Mibs), + %% ?DBG("unload_mibs -> " + %% "~n Res: ~p", [Res]), + Res. verify_loaded_mibs(Pid, Dir, ExpectedMibs0) -> ExpectedMibs = [join(Dir, Mib) || Mib <- ExpectedMibs0], diff --git a/lib/snmp/test/snmp_agent_test.erl b/lib/snmp/test/snmp_agent_test.erl index 0bd180513e..8a2abdcdad 100644 --- a/lib/snmp/test/snmp_agent_test.erl +++ b/lib/snmp/test/snmp_agent_test.erl @@ -553,7 +553,7 @@ init_per_suite(Config0) when is_list(Config0) -> %% Mib-dirs MibDir = snmp_test_lib:lookup(data_dir, Config2), - StdMibDir = filename:join([code:priv_dir(snmp), "mibs"]), + StdMibDir = join([code:priv_dir(snmp), "mibs"]), Config3 = [{mib_dir, MibDir}, {std_mib_dir, StdMibDir} | Config2], @@ -747,21 +747,21 @@ init_per_testcase2(Case, Config) -> CaseTopDir = snmp_test_lib:init_testcase_top_dir(Case, Config), %% Create agent top-dir(s) - AgentTopDir = filename:join([CaseTopDir, agent]), + AgentTopDir = join([CaseTopDir, agent]), ok = file:make_dir(AgentTopDir), - AgentConfDir = filename:join([AgentTopDir, config]), + AgentConfDir = join([AgentTopDir, config]), ok = file:make_dir(AgentConfDir), - AgentDbDir = filename:join([AgentTopDir, db]), + AgentDbDir = join([AgentTopDir, db]), ok = file:make_dir(AgentDbDir), - AgentLogDir = filename:join([AgentTopDir, log]), + AgentLogDir = join([AgentTopDir, log]), ok = file:make_dir(AgentLogDir), %% Create sub-agent top-dir(s) - SubAgentTopDir = filename:join([CaseTopDir, sub_agent]), + SubAgentTopDir = join([CaseTopDir, sub_agent]), ok = file:make_dir(SubAgentTopDir), %% Create manager top-dir(s) - ManagerTopDir = filename:join([CaseTopDir, manager]), + ManagerTopDir = join([CaseTopDir, manager]), ok = file:make_dir(ManagerTopDir), [{case_top_dir, CaseTopDir}, @@ -1737,19 +1737,19 @@ init_case(Config) -> load_master(Mib) -> ?DBG("load_master -> entry with" "~n Mib: ~p", [Mib]), - snmpa:unload_mibs(snmp_master_agent, [Mib]), % Unload for safety - ok = snmpa:load_mibs(snmp_master_agent, [get(mib_dir) ++ Mib]). + snmpa:unload_mib(snmp_master_agent, Mib), % Unload for safety + ok = snmpa:load_mib(snmp_master_agent, join(get(mib_dir), Mib)). load_master_std(Mib) -> ?DBG("load_master_std -> entry with" "~n Mib: ~p", [Mib]), - snmpa:unload_mibs(snmp_master_agent, [Mib]), % Unload for safety - ok = snmpa:load_mibs(snmp_master_agent, [get(std_mib_dir) ++ Mib]). + snmpa:unload_mib(snmp_master_agent, Mib), % Unload for safety + ok = snmpa:load_mib(snmp_master_agent, join(get(std_mib_dir), Mib)). unload_master(Mib) -> ?DBG("unload_master -> entry with" "~n Mib: ~p", [Mib]), - ok = snmpa:unload_mibs(snmp_master_agent, [Mib]). + ok = snmpa:unload_mib(snmp_master_agent, Mib). loaded_mibs() -> ?DBG("loaded_mibs -> entry",[]), @@ -2154,11 +2154,11 @@ subagent(Config) when is_list(Config) -> try_test(unreg_test), ?P1("Loading previous subagent mib in master and testing..."), - ?line ok = snmpa:load_mibs(MA, [MibDir ++ "Klas1"]), + ?line ok = snmpa:load_mib(MA, join(MibDir, "Klas1")), try_test(load_test), ?P1("Unloading previous subagent mib in master and testing..."), - ?line ok = snmpa:unload_mibs(MA, [MibDir ++ "Klas1"]), + ?line ok = snmpa:unload_mib(MA, join(MibDir, "Klas1")), try_test(unreg_test), ?P1("Testing register subagent..."), rpc:call(SaNode, snmp, register_subagent, @@ -2354,11 +2354,11 @@ sa_register(Config) when is_list(Config) -> ?P1("Unloading Klas1..."), ?DBG("sa_register -> unload mibs", []), - snmpa:unload_mibs(SA, [MibDir ++ "Klas1"]), + snmpa:unload_mib(SA, join(MibDir, "Klas1")), ?P1("Loading SA-MIB..."), ?DBG("sa_register -> unload mibs", []), - snmpa:load_mibs(SA, [MibDir ++ "SA-MIB"]), + snmpa:load_mib(SA, join(MibDir, "SA-MIB")), ?P1("register subagent..."), ?DBG("sa_register -> register subagent", []), @@ -2577,7 +2577,7 @@ next_across_sa(Config) when is_list(Config) -> ?line {ok, SA} = start_subagent(SaNode, ?sa, "SA-MIB"), ?P1("Loading another subagent mib (Klas1)..."), - ?line ok = snmpa:load_mibs(SA, [MibDir ++ "Klas1"]), + ?line ok = snmpa:load_mib(SA, MibDir ++ "Klas1"), ?P1("register subagent..."), rpc:call(SaNode, snmp, register_subagent, [MA, ?klas1, SA]), @@ -2589,7 +2589,7 @@ next_across_sa(Config) when is_list(Config) -> try_test(next_across_sa_test), ?P1("Unloading mib (Klas1)"), - snmpa:unload_mibs(SA, [MibDir ++ "Klas1"]), + snmpa:unload_mib(SA, join(MibDir, "Klas1")), rpc:call(SaNode, snmp, unregister_subagent, [MA, ?klas1]), try_test(unreg_test), @@ -2630,25 +2630,25 @@ undo(Config) when is_list(Config) -> ?line {ok, SA} = start_subagent(SaNode, ?sa, "SA-MIB"), ?P1("Load Klas3 & Klas4..."), - ?line ok = snmpa:load_mibs(MA, [MibDir ++ "Klas3"]), - ?line ok = snmpa:load_mibs(MA, [MibDir ++ "Klas4"]), + ?line ok = snmpa:load_mib(MA, join(MibDir, "Klas3")), + ?line ok = snmpa:load_mib(MA, join(MibDir, "Klas4")), ?P1("Testing undo phase at master agent..."), try_test(undo_test), try_test(api_test2), ?P1("Unload Klas3..."), - ?line ok = snmpa:unload_mibs(MA, [MibDir ++ "Klas3"]), + ?line ok = snmpa:unload_mib(MA, join(MibDir, "Klas3")), ?P1("Testing bad return values from instrum. funcs..."), try_test(bad_return), ?P1("Unload Klas4..."), - ?line ok = snmpa:unload_mibs(MA, [MibDir ++ "Klas4"]), + ?line ok = snmpa:unload_mib(MA, join(MibDir, "Klas4")), ?P1("Testing undo phase at subagent..."), - ?line ok = snmpa:load_mibs(SA, [MibDir ++ "Klas3"]), - ?line ok = snmpa:load_mibs(SA, [MibDir ++ "Klas4"]), + ?line ok = snmpa:load_mib(SA, join(MibDir, "Klas3")), + ?line ok = snmpa:load_mib(SA, join(MibDir, "Klas4")), ?line ok = snmpa:register_subagent(MA, ?klas3, SA), ?line ok = snmpa:register_subagent(MA, ?klas4, SA), try_test(undo_test), @@ -6246,8 +6246,8 @@ otp_4394_config(AgentConfDir, MgrDir, Ip0) -> "OTP-4394 test"), ?line case update_usm(Vsn, AgentConfDir) of true -> - ?line copy_file(filename:join(AgentConfDir, "usm.conf"), - filename:join(MgrDir, "usm.conf")), + ?line copy_file(join(AgentConfDir, "usm.conf"), + join(MgrDir, "usm.conf")), ?line update_usm_mgr(Vsn, MgrDir); false -> ?line ok @@ -6406,11 +6406,11 @@ otp8395({init, Config}) when is_list(Config) -> %% AgentDbDir = ?config(agent_db_dir, Config), - AgentMnesiaDir = filename:join([AgentDbDir, "mnesia"]), + AgentMnesiaDir = join([AgentDbDir, "mnesia"]), mnesia_init(AgentNode, AgentMnesiaDir), %% SubAgentDir = ?config(sub_agent_dir, Config), - %% SubAgentMnesiaDir = filename:join([SubAgentDir, "mnesia"]), + %% SubAgentMnesiaDir = join([SubAgentDir, "mnesia"]), %% mnesia_init(SubAgentNode, SubAgentMnesiaDir), %% ok = mnesia_create_schema(AgentNode, [AgentNode, SubAgentNode]), @@ -6540,7 +6540,7 @@ otp8395(Config) when is_list(Config) -> ?SLEEP(1000), AgentNode = ?config(agent_node, Config), AgentLogDir = ?config(agent_log_dir, Config), - OutFile = filename:join([AgentLogDir, "otp8395.txt"]), + OutFile = join([AgentLogDir, "otp8395.txt"]), {ok, LogInfo} = rpc:call(AgentNode, snmpa, log_info, []), ?DBG("otp8395 -> LogInfo: ~p", [LogInfo]), @@ -6578,7 +6578,7 @@ otp9884({init, Config}) when is_list(Config) -> %% AgentDbDir = ?config(agent_db_dir, Config), - AgentMnesiaDir = filename:join([AgentDbDir, "mnesia"]), + AgentMnesiaDir = join([AgentDbDir, "mnesia"]), mnesia_init(AgentNode, AgentMnesiaDir), mnesia_create_schema(AgentNode, [AgentNode]), @@ -6608,8 +6608,8 @@ otp9884({init, Config}) when is_list(Config) -> ManagerConfDir = ?config(manager_top_dir, Config), AgentConfDir = ?config(agent_conf_dir, Config), AgentTopDir = ?config(agent_top_dir, Config), - AgentBkpDir1 = filename:join([AgentTopDir, backup1]), - AgentBkpDir2 = filename:join([AgentTopDir, backup2]), + AgentBkpDir1 = join([AgentTopDir, backup1]), + AgentBkpDir2 = join([AgentTopDir, backup2]), ok = file:make_dir(AgentBkpDir1), ok = file:make_dir(AgentBkpDir2), AgentBkpDirs = [AgentBkpDir1, AgentBkpDir2], @@ -7104,7 +7104,7 @@ display_log(Config) -> {value, {_, Node}} -> LogDir = Dir, Mibs = [], - OutFile = filename:join(LogDir, "snmpa_log.txt"), + OutFile = join(LogDir, "snmpa_log.txt"), p("~n" "=========================" " < Audit Trail Log > " @@ -7251,6 +7251,14 @@ lists_key1search(Key, List) when is_atom(Key) -> %% regs() -> %% lists:sort(registered()). +%% ------ + +join(Parts) -> + filename:join(Parts). + +join(Dir, File) -> + filename:join(Dir, File). + %% ------ diff --git a/lib/snmp/test/snmp_agent_test_lib.erl b/lib/snmp/test/snmp_agent_test_lib.erl index 7e4b713e56..122289c28e 100644 --- a/lib/snmp/test/snmp_agent_test_lib.erl +++ b/lib/snmp/test/snmp_agent_test_lib.erl @@ -139,31 +139,31 @@ init_all(Config) when is_list(Config) -> SuiteTopDir = ?config(snmp_suite_top_dir, Config), ?DBG("init_all -> SuiteTopDir ~p", [SuiteTopDir]), - AgentDir = filename:join(SuiteTopDir, "agent/"), + AgentDir = join(SuiteTopDir, "agent/"), ?line ok = file:make_dir(AgentDir), ?DBG("init_all -> AgentDir ~p", [AgentDir]), - AgentDbDir = filename:join(AgentDir, "db/"), + AgentDbDir = join(AgentDir, "db/"), ?line ok = file:make_dir(AgentDbDir), ?DBG("init_all -> AgentDbDir ~p", [AgentDbDir]), - AgentLogDir = filename:join(AgentDir, "log/"), + AgentLogDir = join(AgentDir, "log/"), ?line ok = file:make_dir(AgentLogDir), ?DBG("init_all -> AgentLogDir ~p", [AgentLogDir]), - AgentConfDir = filename:join(AgentDir, "conf/"), + AgentConfDir = join(AgentDir, "conf/"), ?line ok = file:make_dir(AgentConfDir), ?DBG("init_all -> AgentConfDir ~p", [AgentConfDir]), - MgrDir = filename:join(SuiteTopDir, "mgr/"), + MgrDir = join(SuiteTopDir, "mgr/"), ?line ok = file:make_dir(MgrDir), ?DBG("init_all -> MgrDir ~p", [MgrDir]), - SaDir = filename:join(SuiteTopDir, "sa/"), + SaDir = join(SuiteTopDir, "sa/"), ?line ok = file:make_dir(SaDir), ?DBG("init_all -> SaDir ~p", [SaDir]), - SaDbDir = filename:join(SaDir, "db/"), + SaDbDir = join(SaDir, "db/"), ?line ok = file:make_dir(SaDbDir), ?DBG("init_all -> SaDbDir ~p", [SaDbDir]), @@ -183,11 +183,11 @@ init_all(Config) when is_list(Config) -> ?DBG("init_all -> application mnesia: set_env dir",[]), ?line application_controller:set_env(mnesia, dir, - filename:join(AgentDbDir, "Mnesia1")), + join(AgentDbDir, "Mnesia1")), ?DBG("init_all -> application mnesia: set_env dir on node ~p",[SaNode]), ?line rpc:call(SaNode, application_controller, set_env, - [mnesia, dir, filename:join(SaDir, "Mnesia2")]), + [mnesia, dir, join(SaDir, "Mnesia2")]), ?DBG("init_all -> create mnesia schema",[]), ?line ok = mnesia:create_schema([SaNode, node()]), @@ -253,7 +253,7 @@ init_case(Config) when is_list(Config) -> MibDir = ?config(mib_dir, Config), put(mib_dir, MibDir), - StdM = filename:join(code:priv_dir(snmp), "mibs") ++ "/", + StdM = join(code:priv_dir(snmp), "mibs") ++ "/", put(std_mib_dir, StdM), MgrDir = ?config(mgr_dir, Config), @@ -341,7 +341,7 @@ run(Mod, Func, Args, Opts) -> Crypto = ?CRYPTO_START(), ?DBG("run -> Crypto: ~p", [Crypto]), catch snmp_test_mgr:stop(), % If we had a running mgr from a failed case - StdM = filename:join(code:priv_dir(snmp), "mibs") ++ "/", + StdM = join(code:priv_dir(snmp), "mibs") ++ "/", Vsn = get(vsn), ?DBG("run -> config:" "~n M: ~p" @@ -763,7 +763,7 @@ start_subagent(SaNode, RegTree, Mib) -> MA = whereis(snmp_master_agent), ?DBG("start_subagent -> MA: ~p", [MA]), MibDir = get(mib_dir), - Mib1 = join(MibDir,Mib), + Mib1 = join(MibDir, Mib), Mod = snmpa_supervisor, Func = start_sub_agent, Args = [MA, RegTree, [Mib1]], @@ -800,28 +800,25 @@ mibs(StdMibDir,MibDir) -> join(MibDir, "Test2.bin"), join(MibDir, "TestTrapv2.bin")]. -join(D,F) -> - filename:join(D,F). - %% --- various mib load/unload functions --- load_master(Mib) -> ?DBG("load_master -> entry with" "~n Mib: ~p", [Mib]), - snmpa:unload_mibs(snmp_master_agent, [Mib]), % Unload for safety - ok = snmpa:load_mibs(snmp_master_agent, [get(mib_dir) ++ Mib]). + snmpa:unload_mib(snmp_master_agent, Mib), % Unload for safety + ok = snmpa:load_mib(snmp_master_agent, join(get(mib_dir), Mib)). load_master_std(Mib) -> ?DBG("load_master_std -> entry with" "~n Mib: ~p", [Mib]), - snmpa:unload_mibs(snmp_master_agent, [Mib]), % Unload for safety - ok = snmpa:load_mibs(snmp_master_agent, [get(std_mib_dir) ++ Mib]). + snmpa:unload_mib(snmp_master_agent, Mib), % Unload for safety + ok = snmpa:load_mibs(snmp_master_agent, join(get(std_mib_dir), Mib)). unload_master(Mib) -> ?DBG("unload_master -> entry with" "~n Mib: ~p", [Mib]), - ok = snmpa:unload_mibs(snmp_master_agent, [Mib]). + ok = snmpa:unload_mib(snmp_master_agent, Mib). loaded_mibs() -> ?DBG("loaded_mibs -> entry",[]), @@ -1383,8 +1380,8 @@ config(Vsns, MgrDir, AgentConfDir, MIp, AIp) -> "test"), ?line case update_usm(Vsns, AgentConfDir) of true -> - ?line copy_file(filename:join(AgentConfDir, "usm.conf"), - filename:join(MgrDir, "usm.conf")), + ?line copy_file(join(AgentConfDir, "usm.conf"), + join(MgrDir, "usm.conf")), ?line update_usm_mgr(Vsns, MgrDir); false -> ?line ok @@ -1403,9 +1400,9 @@ delete_files(Config) -> delete_files(_AgentFiles, []) -> ok; delete_files(AgentDir, [DirName|DirNames]) -> - Dir = filename:join(AgentDir, DirName), + Dir = join(AgentDir, DirName), {ok, Files} = file:list_dir(Dir), - lists:foreach(fun(FName) -> file:delete(filename:join(Dir, FName)) end, + lists:foreach(fun(FName) -> file:delete(join(Dir, FName)) end, Files), delete_files(AgentDir, DirNames). @@ -1481,8 +1478,8 @@ update_usm_mgr(Vsns, Dir) -> end. rewrite_usm_mgr(Dir, ShaKey, DesKey) -> - ?line ok = file:rename(filename:join(Dir,"usm.conf"), - filename:join(Dir,"usm.old")), + ?line ok = file:rename(join(Dir,"usm.conf"), + join(Dir,"usm.old")), Conf = [{"agentEngine", "newUser", "newUser", zeroDotZero, usmHMACSHAAuthProtocol, "", "", usmDESPrivProtocol, "", "", "", ShaKey, DesKey}, @@ -1492,8 +1489,8 @@ rewrite_usm_mgr(Dir, ShaKey, DesKey) -> ok = snmp_config:write_agent_usm_config(Dir, "", Conf). reset_usm_mgr(Dir) -> - ?line ok = file:rename(filename:join(Dir,"usm.old"), - filename:join(Dir,"usm.conf")). + ?line ok = file:rename(join(Dir,"usm.old"), + join(Dir,"usm.conf")). update_community([v3], _Dir) -> @@ -1526,7 +1523,7 @@ write_target_addr_conf(Dir, ManagerIp, UDP, Vsns) -> rewrite_target_addr_conf(Dir, NewPort) -> ?DBG("rewrite_target_addr_conf -> entry with" "~n NewPort: ~p", [NewPort]), - TAFile = filename:join(Dir, "target_addr.conf"), + TAFile = join(Dir, "target_addr.conf"), case file:read_file_info(TAFile) of {ok, _} -> ok; @@ -1546,8 +1543,8 @@ rewrite_target_addr_conf(Dir, NewPort) -> ?DBG("rewrite_target_addr_conf -> NewAddrs: ~p",[NewAddrs]), - ?line ok = file:rename(filename:join(Dir,"target_addr.conf"), - filename:join(Dir,"target_addr.old")), + ?line ok = file:rename(join(Dir,"target_addr.conf"), + join(Dir,"target_addr.old")), ?line ok = snmp_config:write_agent_target_addr_config(Dir, "", NewAddrs). @@ -1565,8 +1562,8 @@ rewrite_target_addr_conf2(_NewPort,O) -> O. reset_target_addr_conf(Dir) -> - ?line ok = file:rename(filename:join(Dir, "target_addr.old"), - filename:join(Dir, "target_addr.conf")). + ?line ok = file:rename(join(Dir, "target_addr.old"), + join(Dir, "target_addr.conf")). write_target_params_conf(Dir, Vsns) -> F = fun(v1) -> {"target_v1", v1, v1, "all-rights", noAuthNoPriv}; @@ -1578,14 +1575,14 @@ write_target_params_conf(Dir, Vsns) -> rewrite_target_params_conf(Dir, SecName, SecLevel) when is_list(SecName) andalso is_atom(SecLevel) -> - ?line ok = file:rename(filename:join(Dir,"target_params.conf"), - filename:join(Dir,"target_params.old")), + ?line ok = file:rename(join(Dir,"target_params.conf"), + join(Dir,"target_params.old")), Conf = [{"target_v3", v3, usm, SecName, SecLevel}], snmp_config:write_agent_target_params_config(Dir, "", Conf). reset_target_params_conf(Dir) -> - ?line ok = file:rename(filename:join(Dir,"target_params.old"), - filename:join(Dir,"target_params.conf")). + ?line ok = file:rename(join(Dir,"target_params.old"), + join(Dir,"target_params.conf")). write_notify_conf(Dir) -> Conf = [{"standard trap", "std_trap", trap}, @@ -1648,6 +1645,9 @@ rpc(Node, F, A) -> rpc:call(Node, snmpa, F, A). +join(Dir, File) -> + filename:join(Dir, File). + %% await_pdu(To) -> %% await_response(To, pdu). %% diff --git a/lib/snmp/vsn.mk b/lib/snmp/vsn.mk index e987649e11..2164121e86 100644 --- a/lib/snmp/vsn.mk +++ b/lib/snmp/vsn.mk @@ -18,6 +18,6 @@ # %CopyrightEnd% APPLICATION = snmp -SNMP_VSN = 4.24.1 +SNMP_VSN = 4.24.2 PRE_VSN = APP_VSN = "$(APPLICATION)-$(SNMP_VSN)$(PRE_VSN)" diff --git a/lib/ssh/doc/src/notes.xml b/lib/ssh/doc/src/notes.xml index 6b7ff7b238..041f5e54af 100644 --- a/lib/ssh/doc/src/notes.xml +++ b/lib/ssh/doc/src/notes.xml @@ -29,6 +29,41 @@ <file>notes.xml</file> </header> +<section><title>Ssh 2.1.8</title> + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Do not chmod ~/.ssh unnecessarily.</p> + <p> + Own Id: OTP-11189</p> + </item> + <item> + <p> + Make ssh_cli.erl handle CTRL+C. Thanks to Stefan + Zegenhagen.</p> + <p> + Own Id: OTP-11199</p> + </item> + <item> + <p> + Clarified timeout options in documentation.</p> + <p> + Own Id: OTP-11249</p> + </item> + <item> + <p> + Add openssh_zlib compression type to ssh_transport. + Thanks to Louis-Philippe Gauthier.</p> + <p> + Own Id: OTP-11256</p> + </item> + </list> + </section> + +</section> + <section><title>Ssh 2.1.7</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/ssh/vsn.mk b/lib/ssh/vsn.mk index 231779b75a..90f09471c9 100644 --- a/lib/ssh/vsn.mk +++ b/lib/ssh/vsn.mk @@ -1,5 +1,5 @@ #-*-makefile-*- ; force emacs to enter makefile-mode -SSH_VSN = 2.1.7 +SSH_VSN = 2.1.8 APP_VSN = "ssh-$(SSH_VSN)" diff --git a/lib/ssl/doc/src/notes.xml b/lib/ssl/doc/src/notes.xml index fb6b45c904..692d7fd0e1 100644 --- a/lib/ssl/doc/src/notes.xml +++ b/lib/ssl/doc/src/notes.xml @@ -25,7 +25,69 @@ <file>notes.xml</file> </header> <p>This document describes the changes made to the SSL application.</p> - <section><title>SSL 5.3</title> + <section><title>SSL 5.3.1</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Setopts during renegotiation caused the renegotiation to + be unsuccessful.</p> + <p> + If calling setopts during a renegotiation the FSM state + might change during the handling of the setopts messages, + this is now handled correctly.</p> + <p> + Own Id: OTP-11228</p> + </item> + <item> + <p> + Now handles signature_algorithm field in digitally_signed + properly with proper defaults. Prior to this change some + elliptic curve cipher suites could fail reporting the + error "bad certificate".</p> + <p> + Own Id: OTP-11229</p> + </item> + <item> + <p> + The code emulating the inet header option was changed in + the belief that it made it inet compatible. However the + testing is a bit hairy as the inet option is actually + broken, now the tests are corrected and the header option + should work in the same broken way as inet again, + preferably use the bitsyntax instead.</p> + <p> + Own Id: OTP-11230</p> + </item> + </list> + </section> + + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Make the ssl manager name for erlang distribution over + SSL/TLS relative to the module name of the ssl_manager.</p> + <p> + This can be beneficial when making tools that rename + modules for internal processing in the tool.</p> + <p> + Own Id: OTP-11255</p> + </item> + <item> + <p> + Add documentation regarding log_alert option.</p> + <p> + Own Id: OTP-11271</p> + </item> + </list> + </section> + +</section> + +<section><title>SSL 5.3</title> <section><title>Fixed Bugs and Malfunctions</title> <list> diff --git a/lib/ssl/src/Makefile b/lib/ssl/src/Makefile index cf9f7d5001..6744e2f256 100644 --- a/lib/ssl/src/Makefile +++ b/lib/ssl/src/Makefile @@ -58,15 +58,18 @@ MODULES= \ ssl_connection_sup \ tls_handshake \ dtls_handshake\ + ssl_handshake\ ssl_manager \ ssl_session \ ssl_session_cache \ ssl_socket \ tls_record \ dtls_record \ - ssl_ssl2 \ - ssl_ssl3 \ - ssl_tls1 \ + ssl_record \ + ssl_v2 \ + ssl_v3 \ + tls_v1 \ + dtls_v1 \ ssl_tls_dist_proxy INTERNAL_HRL_FILES = \ diff --git a/lib/ssl/src/dtls_connection.erl b/lib/ssl/src/dtls_connection.erl index ac2ee0d09f..fda488501c 100644 --- a/lib/ssl/src/dtls_connection.erl +++ b/lib/ssl/src/dtls_connection.erl @@ -17,3 +17,325 @@ %% %CopyrightEnd% %% -module(dtls_connection). + +%%-behaviour(gen_fsm). + +%% -include("dtls_handshake.hrl"). +%% -include("ssl_alert.hrl"). +%% -include("dtls_record.hrl"). +%% -include("ssl_cipher.hrl"). +%% -include("ssl_internal.hrl"). +%% -include("ssl_srp.hrl"). +%% -include_lib("public_key/include/public_key.hrl"). + + +%% %% Called by dtls_connection_sup +%% %%-export([start_link/7]). + +%% %% gen_fsm callbacks +%% -export([init/1, hello/2, certify/2, cipher/2, +%% abbreviated/2, connection/2, handle_event/3, +%% handle_sync_event/4, handle_info/3, terminate/3, code_change/4]). + +%% -record(message_sequences, { +%% read = 0, +%% write = 0 +%% }). + +%% -record(state, { +%% role, % client | server +%% user_application, % {MonitorRef, pid()} +%% transport_cb, % atom() - callback module +%% data_tag, % atom() - ex tcp. +%% close_tag, % atom() - ex tcp_closed +%% error_tag, % atom() - ex tcp_error +%% host, % string() | ipadress() +%% port, % integer() +%% socket, % socket() +%% ssl_options, % #ssl_options{} +%% socket_options, % #socket_options{} +%% connection_states, % #connection_states{} from ssl_record.hrl +%% message_sequences = #message_sequences{}, +%% dtls_packets = [], % Not yet handled decode ssl/tls packets. +%% dtls_record_buffer, % binary() buffer of incomplete records +%% dtls_handshake_buffer, % binary() buffer of incomplete handshakes +%% dtls_handshake_history, % tls_handshake_history() +%% dtls_cipher_texts, % list() received but not deciphered yet +%% cert_db, % +%% session, % #session{} from tls_handshake.hrl +%% session_cache, % +%% session_cache_cb, % +%% negotiated_version, % tls_version() +%% client_certificate_requested = false, +%% key_algorithm, % atom as defined by cipher_suite +%% hashsign_algorithm, % atom as defined by cipher_suite +%% public_key_info, % PKIX: {Algorithm, PublicKey, PublicKeyParams} +%% private_key, % PKIX: #'RSAPrivateKey'{} +%% diffie_hellman_params, % PKIX: #'DHParameter'{} relevant for server side +%% diffie_hellman_keys, % {PublicKey, PrivateKey} +%% psk_identity, % binary() - server psk identity hint +%% srp_params, % #srp_user{} +%% srp_keys, % {PublicKey, PrivateKey} +%% premaster_secret, % +%% file_ref_db, % ets() +%% cert_db_ref, % ref() +%% bytes_to_read, % integer(), # bytes to read in passive mode +%% user_data_buffer, % binary() +%% log_alert, % boolean() +%% renegotiation, % {boolean(), From | internal | peer} +%% start_or_recv_from, % "gen_fsm From" +%% timer, % start_or_recv_timer +%% send_queue, % queue() +%% terminated = false, % +%% allow_renegotiate = true, +%% expecting_next_protocol_negotiation = false :: boolean(), +%% next_protocol = undefined :: undefined | binary(), +%% client_ecc, % {Curves, PointFmt} +%% client_cookie = <<>> +%% }). + + + +%% %%==================================================================== +%% %% Internal application API +%% %%==================================================================== + + +%% %%==================================================================== +%% %% State functions +%% %%==================================================================== + +%% -spec hello(start | #hello_request{} | #client_hello{} | #server_hello{} | term(), +%% #state{}) -> gen_fsm_state_return(). +%% %%-------------------------------------------------------------------- +%% hello(start, #state{host = Host, port = Port, role = client, +%% ssl_options = SslOpts, +%% session = #session{own_certificate = Cert} = Session0, +%% session_cache = Cache, session_cache_cb = CacheCb, +%% connection_states = ConnectionStates0, +%% renegotiation = {Renegotiation, _}, +%% client_cookie = Cookie} = State0) -> +%% Hello = dtls_handshake:client_hello(Host, Port, Cookie, ConnectionStates0, SslOpts, +%% Cache, CacheCb, Renegotiation, Cert), + +%% Version = Hello#client_hello.client_version, +%% State1 = State0#state{negotiated_version = Version, %% Requested version +%% session = +%% Session0#session{session_id = Hello#client_hello.session_id}, +%% dtls_handshake_history = ssl_handshake:init_handshake_history()}, + +%% State2 = send_flight(Hello, waiting, State1), + +%% {Record, State} = next_record(State2), +%% next_state(hello, hello, Record, State); + +%% hello(start, #state{role = server} = State0) -> +%% {Record, State} = next_record(State0), +%% next_state(hello, hello, Record, State); + +%% hello(#hello_request{}, #state{role = client} = State0) -> +%% {Record, State} = next_record(State0), +%% next_state(hello, hello, Record, State); + +%% hello(#server_hello{cipher_suite = CipherSuite, +%% compression_method = Compression} = Hello, +%% #state{session = #session{session_id = OldId}, +%% connection_states = ConnectionStates0, +%% role = client, +%% negotiated_version = ReqVersion, +%% renegotiation = {Renegotiation, _}, +%% ssl_options = SslOptions} = State1) -> +%% State0 = flight_done(State1), +%% case ssl_handshake:hello(Hello, SslOptions, ConnectionStates0, Renegotiation) of +%% #alert{} = Alert -> +%% handle_own_alert(Alert, ReqVersion, hello, State0); +%% {Version, NewId, ConnectionStates, NextProtocol} -> +%% {KeyAlgorithm, _, _, _} = +%% ssl_cipher:suite_definition(CipherSuite), + +%% PremasterSecret = make_premaster_secret(ReqVersion, KeyAlgorithm), + +%% NewNextProtocol = case NextProtocol of +%% undefined -> +%% State0#state.next_protocol; +%% _ -> +%% NextProtocol +%% end, + +%% State = State0#state{key_algorithm = KeyAlgorithm, +%% hashsign_algorithm = default_hashsign(Version, KeyAlgorithm), +%% negotiated_version = Version, +%% connection_states = ConnectionStates, +%% premaster_secret = PremasterSecret, +%% expecting_next_protocol_negotiation = NextProtocol =/= undefined, +%% next_protocol = NewNextProtocol}, + +%% case ssl_session:is_new(OldId, NewId) of +%% true -> +%% handle_new_session(NewId, CipherSuite, Compression, +%% State#state{connection_states = ConnectionStates}); +%% false -> +%% handle_resumed_session(NewId, State#state{connection_states = ConnectionStates}) +%% end +%% end; + +%% hello(#hello_verify_request{cookie = Cookie}, +%% #state{host = Host, port = Port, +%% session = #session{own_certificate = Cert}, +%% session_cache = Cache, session_cache_cb = CacheCb, +%% ssl_options = SslOpts, +%% connection_states = ConnectionStates0, +%% renegotiation = {Renegotiation, _}} = State0) -> +%% Hello = ssl_handshake:client_hello(Host, Port, Cookie, ConnectionStates0, SslOpts, +%% Cache, CacheCb, Renegotiation, Cert), +%% State1 = State0#state{ +%% tls_handshake_history = ssl_handshake:init_handshake_history(), +%% client_cookie = Cookie}, +%% State2 = send_flight(Hello, waiting, State1), + +%% {Record, State} = next_record(State2), +%% next_state(hello, hello, Record, State); + +%% hello(Hello = #client_hello{client_version = ClientVersion}, +%% State = #state{connection_states = ConnectionStates0, +%% port = Port, session = #session{own_certificate = Cert} = Session0, +%% renegotiation = {Renegotiation, _}, +%% session_cache = Cache, +%% session_cache_cb = CacheCb, +%% ssl_options = SslOpts}) -> +%% case ssl_handshake:hello(Hello, SslOpts, {Port, Session0, Cache, CacheCb, +%% ConnectionStates0, Cert}, Renegotiation) of +%% {Version, {Type, Session}, ConnectionStates, ProtocolsToAdvertise, +%% EcPointFormats, EllipticCurves} -> +%% do_server_hello(Type, ProtocolsToAdvertise, +%% EcPointFormats, EllipticCurves, +%% State#state{connection_states = ConnectionStates, +%% negotiated_version = Version, +%% session = Session, +%% client_ecc = {EllipticCurves, EcPointFormats}}); +%% #alert{} = Alert -> +%% handle_own_alert(Alert, ClientVersion, hello, State) +%% end; + +%% hello(timeout, State) -> +%% { next_state, hello, State, hibernate }; + +%% hello(Msg, State) -> +%% handle_unexpected_message(Msg, hello, State). +%% %%-------------------------------------------------------------------- +%% -spec abbreviated(#hello_request{} | #finished{} | term(), +%% #state{}) -> gen_fsm_state_return(). +%% %%-------------------------------------------------------------------- + +%% abbreviated(timeout, State) -> +%% { next_state, abbreviated, State, hibernate }; + +%% abbreviated(Msg, State) -> +%% handle_unexpected_message(Msg, abbreviated, State). + +%% %%-------------------------------------------------------------------- +%% -spec certify(#hello_request{} | #certificate{} | #server_key_exchange{} | +%% #certificate_request{} | #server_hello_done{} | #client_key_exchange{} | term(), +%% #state{}) -> gen_fsm_state_return(). +%% %%-------------------------------------------------------------------- + + +%% certify(timeout, State) -> +%% { next_state, certify, State, hibernate }; + +%% certify(Msg, State) -> +%% handle_unexpected_message(Msg, certify, State). + + +%% %%-------------------------------------------------------------------- +%% -spec cipher(#hello_request{} | #certificate_verify{} | #finished{} | term(), +%% #state{}) -> gen_fsm_state_return(). +%% %%-------------------------------------------------------------------- + +%% cipher(timeout, State) -> +%% { next_state, cipher, State, hibernate }; + +%% cipher(Msg, State) -> +%% handle_unexpected_message(Msg, cipher, State). + +%% %%-------------------------------------------------------------------- +%% -spec connection(#hello_request{} | #client_hello{} | term(), +%% #state{}) -> gen_fsm_state_return(). +%% %%-------------------------------------------------------------------- + +%% connection(timeout, State) -> +%% {next_state, connection, State, hibernate}; + +%% connection(Msg, State) -> +%% handle_unexpected_message(Msg, connection, State). + +%% %%-------------------------------------------------------------------- +%% %%% Internal functions +%% %%-------------------------------------------------------------------- +%% handle_unexpected_message(Msg, Info, #state{negotiated_version = Version} = State) -> +%% Alert = ?ALERT_REC(?FATAL,?UNEXPECTED_MESSAGE), +%% handle_own_alert(Alert, Version, {Info, Msg}, State). + +%% send_flight(HandshakeRec, FlightState, State) -> +%% send_flight(FlightState, buffer_flight(HandshakeRec, State)). + +%% send_flight(FlightState, State = #state{negotiated_version = Version, +%% flight_buffer = Buffer}) -> + +%% State1 = do_send_flight(queue:to_list(Buffer), [], State), +%% finish_send_flight(Version, FlightState, State1). + +%% resend_flight(State = #state{negotiated_version = Version, +%% flight_state = FlightState, +%% flight_buffer = Buffer}) +%% when FlightState == finished; FlightState == waiting -> +%% State1 = do_send_flight(queue:to_list(Buffer), [], State), +%% finish_send_flight(Version, FlightState, State1); + +%% resend_flight(State) -> +%% State. + +%% flight_done(State) -> +%% cancel_dtls_retransmit_timer(State#state{flight_state = done, +%% flight_buffer = undefined}). + +%% do_send_flight([], BinMsgs, State = #state{transport_cb = Transport, socket = Socket}) -> +%% Transport:send(Socket, lists:reverse(BinMsgs)), +%% State; +%% do_send_flight([{Epoch, MsgSeq, HandshakeRec}|T], BinMsgs0, +%% State = #state{negotiated_version = Version, +%% connection_states = ConnectionStates0}) -> +%% CS0 = ssl_record:connection_state_by_epoch(ConnectionStates0, Epoch, write), +%% {BinMsgs, CS1} = encode_handshake_rec(HandshakeRec, Version, MsgSeq, BinMsgs0, CS0), +%% ConnectionStates1 = ssl_record:set_connection_state_by_epoch(ConnectionStates0, CS1, write), +%% do_send_flight(T, BinMsgs, State#state{connection_states = ConnectionStates1}). + +%% cancel_dtls_retransmit_timer(State = #state{dtls_retransmit_timer = TimerRef}) -> +%% cancel_timer(TimerRef), +%% State#state{dtls_retransmit_timer = undefined}. + +%% rearm_dtls_retransmit_timer(State = #state{dtls_retransmit_timer = undefined}) -> +%% TimerRef = erlang:start_timer(1000, self(), dtls_retransmit), +%% State#state{dtls_retransmit_timer = TimerRef}; +%% rearm_dtls_retransmit_timer(State) -> +%% State. + +%% finish_send_flight({254, _}, waiting, State) -> +%% TimerRef = erlang:start_timer(1000, self(), dtls_retransmit), +%% State#state{ +%% dtls_retransmit_timer = TimerRef, +%% last_retransmit = timestamp(), +%% flight_state = waiting}; + +%% finish_send_flight(_, FlightState, State) -> +%% State#state{flight_state = FlightState}. + +%% timestamp() -> +%% {Mega, Sec, Micro} = erlang:now(), +%% Mega * 1000000 * 1000 + Sec * 1000 + (Micro div 1000). + +%% encode_handshake_rec(HandshakeRec, Version, MsgSeq, BinMsgs0, CS0) -> +%% {_, Fragments} = ssl_handshake:encode_handshake(HandshakeRec, Version, MsgSeq, 1400), +%% lists:foldl(fun(F, {Bin, C0}) -> +%% {B, C1} = ssl_record:encode_handshake(F, Version, C0), +%% {[B|Bin], C1} end, {BinMsgs0, CS0}, Fragments). diff --git a/lib/ssl/src/dtls_handshake.erl b/lib/ssl/src/dtls_handshake.erl index b25daa59d9..26e8ce7503 100644 --- a/lib/ssl/src/dtls_handshake.erl +++ b/lib/ssl/src/dtls_handshake.erl @@ -16,3 +16,413 @@ %% %% %CopyrightEnd% -module(dtls_handshake). + +-include("dtls_handshake.hrl"). +-include("dtls_record.hrl"). +-include("ssl_internal.hrl"). + +-export([client_hello/9, hello/3, get_dtls_handshake/2, + dtls_handshake_new_flight/1, dtls_handshake_new_epoch/1, + encode_handshake/4]). + +%%==================================================================== +%% Internal application API +%%==================================================================== + +%%-------------------------------------------------------------------- +-spec client_hello(host(), inet:port_number(), term(), #connection_states{}, + #ssl_options{}, integer(), atom(), boolean(), der_cert()) -> + #client_hello{}. +%% +%% Description: Creates a client hello message. +%%-------------------------------------------------------------------- +client_hello(Host, Port, Cookie, ConnectionStates, + #ssl_options{versions = Versions, + ciphers = UserSuites + } = SslOpts, + Cache, CacheCb, Renegotiation, OwnCert) -> + Version = dtls_record:highest_protocol_version(Versions), + Pending = ssl_record:pending_connection_state(ConnectionStates, read), + SecParams = Pending#connection_state.security_parameters, + CipherSuites = ssl_handshake:available_suites(UserSuites, Version), + + Extensions = ssl_handshake:client_hello_extensions(Version, CipherSuites, + SslOpts, ConnectionStates, Renegotiation), + + Id = ssl_session:client_id({Host, Port, SslOpts}, Cache, CacheCb, OwnCert), + + #client_hello{session_id = Id, + client_version = Version, + cipher_suites = ssl_handshake:cipher_suites(CipherSuites, Renegotiation), + compression_methods = ssl_record:compressions(), + random = SecParams#security_parameters.client_random, + cookie = Cookie, + extensions = Extensions + }. + +hello(Address, Port, + #ssl_tls{epoch = _Epoch, record_seq = _Seq, + version = Version} = Record) -> + {[{Hello, _}], _, _} = + get_dtls_handshake(Record, + dtls_handshake_new_flight(undefined)), + #client_hello{client_version = {Major, Minor}, + random = Random, + session_id = SessionId, + cipher_suites = CipherSuites, + compression_methods = CompressionMethods} = Hello, + CookieData = [address_to_bin(Address, Port), + <<?BYTE(Major), ?BYTE(Minor)>>, + Random, SessionId, CipherSuites, CompressionMethods], + Cookie = crypto:hmac(sha, <<"secret">>, CookieData), + + case Hello of + #client_hello{cookie = Cookie} -> + accept; + _ -> + %% generate HelloVerifyRequest + HelloVerifyRequest = encode_handshake(#hello_verify_request{protocol_version = Version, + cookie = Cookie}, + Version, 0, 1400), + {reply, HelloVerifyRequest} + end. + +address_to_bin({A,B,C,D}, Port) -> + <<0:80,16#ffff:16,A,B,C,D,Port:16>>; +address_to_bin({A,B,C,D,E,F,G,H}, Port) -> + <<A:16,B:16,C:16,D:16,E:16,F:16,G:16,H:16,Port:16>>. + +%%-------------------------------------------------------------------- +encode_handshake(Package, Version, MsgSeq, Mss) -> + {MsgType, Bin} = enc_hs(Package, Version), + Len = byte_size(Bin), + HsHistory = [MsgType, ?uint24(Len), ?uint16(MsgSeq), ?uint24(0), ?uint24(Len), Bin], + BinMsg = dtls_split_handshake(Mss, MsgType, Len, MsgSeq, Bin, 0, []), + {HsHistory, BinMsg}. + +%-------------------------------------------------------------------- +-spec get_dtls_handshake(#ssl_tls{}, #dtls_hs_state{} | binary()) -> + {[dtls_handshake()], #ssl_tls{}}. +% +% Description: Given a DTLS state and new data from ssl_record, collects +% and returns it as a list of handshake messages, also returns a new +% DTLS state +%-------------------------------------------------------------------- +% get_dtls_handshake(Record, <<>>) -> +% get_dtls_handshake_aux(Record, dtls_hs_state_init()); +get_dtls_handshake(Record, HsState) -> + get_dtls_handshake_aux(Record, HsState). + +%-------------------------------------------------------------------- +-spec dtls_handshake_new_epoch(#dtls_hs_state{}) -> #dtls_hs_state{}. +% +% Description: Reset the DTLS decoder state for a new Epoch +%-------------------------------------------------------------------- +% dtls_handshake_new_epoch(<<>>) -> +% dtls_hs_state_init(); +dtls_handshake_new_epoch(HsState) -> + HsState#dtls_hs_state{highest_record_seq = 0, + starting_read_seq = HsState#dtls_hs_state.current_read_seq, + fragments = gb_trees:empty(), completed = []}. + +%-------------------------------------------------------------------- +-spec dtls_handshake_new_flight(integer() | undefined) -> #dtls_hs_state{}. +% +% Description: Init the DTLS decoder state for a new Flight +dtls_handshake_new_flight(ExpectedReadReq) -> + #dtls_hs_state{current_read_seq = ExpectedReadReq, + highest_record_seq = 0, + starting_read_seq = 0, + fragments = gb_trees:empty(), completed = []}. + +%%-------------------------------------------------------------------- +%%% Internal functions +%%-------------------------------------------------------------------- + +dtls_split_handshake(Mss, MsgType, Len, MsgSeq, Bin, Offset, Acc) + when byte_size(Bin) + 12 < Mss -> + FragmentLen = byte_size(Bin), + BinMsg = [MsgType, ?uint24(Len), ?uint16(MsgSeq), ?uint24(Offset), ?uint24(FragmentLen), Bin], + lists:reverse([BinMsg|Acc]); +dtls_split_handshake(Mss, MsgType, Len, MsgSeq, Bin, Offset, Acc) -> + FragmentLen = Mss - 12, + <<Fragment:FragmentLen/bytes, Rest/binary>> = Bin, + BinMsg = [MsgType, ?uint24(Len), ?uint16(MsgSeq), ?uint24(Offset), ?uint24(FragmentLen), Fragment], + dtls_split_handshake(Mss, MsgType, Len, MsgSeq, Rest, Offset + FragmentLen, [BinMsg|Acc]). + +get_dtls_handshake_aux(#ssl_tls{version = Version, + record_seq = SeqNo, + fragment = Data}, HsState) -> + get_dtls_handshake_aux(Version, SeqNo, Data, HsState). + +get_dtls_handshake_aux(Version, SeqNo, + <<?BYTE(Type), ?UINT24(Length), + ?UINT16(MessageSeq), + ?UINT24(FragmentOffset), ?UINT24(FragmentLength), + Body:FragmentLength/binary, Rest/binary>>, + HsState0) -> + case reassemble_dtls_fragment(SeqNo, Type, Length, MessageSeq, + FragmentOffset, FragmentLength, + Body, HsState0) of + {retransmit, HsState1} -> + case Rest of + <<>> -> + {retransmit, HsState1}; + _ -> + get_dtls_handshake_aux(Version, SeqNo, Rest, HsState1) + end; + {HsState1, HighestSeqNo, MsgBody} -> + HsState2 = dec_dtls_fragment(Version, HighestSeqNo, Type, Length, MessageSeq, MsgBody, HsState1), + HsState3 = process_dtls_fragments(Version, HsState2), + get_dtls_handshake_aux(Version, SeqNo, Rest, HsState3); + HsState2 -> + HsState3 = process_dtls_fragments(Version, HsState2), + get_dtls_handshake_aux(Version, SeqNo, Rest, HsState3) + end; + +get_dtls_handshake_aux(_Version, _SeqNo, <<>>, HsState) -> + {lists:reverse(HsState#dtls_hs_state.completed), + HsState#dtls_hs_state.highest_record_seq, + HsState#dtls_hs_state{completed = []}}. + +dec_dtls_fragment(Version, SeqNo, Type, Length, MessageSeq, MsgBody, + HsState = #dtls_hs_state{highest_record_seq = HighestSeqNo, completed = Acc}) -> + Raw = <<?BYTE(Type), ?UINT24(Length), ?UINT16(MessageSeq), ?UINT24(0), ?UINT24(Length), MsgBody/binary>>, + H = decode_handshake(Version, Type, MsgBody), + HsState#dtls_hs_state{completed = [{H,Raw}|Acc], highest_record_seq = erlang:max(HighestSeqNo, SeqNo)}. + +process_dtls_fragments(Version, + HsState0 = #dtls_hs_state{current_read_seq = CurrentReadSeq, + fragments = Fragments0}) -> + case gb_trees:is_empty(Fragments0) of + true -> + HsState0; + _ -> + case gb_trees:smallest(Fragments0) of + {CurrentReadSeq, {SeqNo, Type, Length, CurrentReadSeq, {Length, [{0, Length}], MsgBody}}} -> + HsState1 = dtls_hs_state_process_seq(HsState0), + HsState2 = dec_dtls_fragment(Version, SeqNo, Type, Length, CurrentReadSeq, MsgBody, HsState1), + process_dtls_fragments(Version, HsState2); + _ -> + HsState0 + end + end. + +dtls_hs_state_process_seq(HsState0 = #dtls_hs_state{current_read_seq = CurrentReadSeq, + fragments = Fragments0}) -> + Fragments1 = gb_trees:delete_any(CurrentReadSeq, Fragments0), + HsState0#dtls_hs_state{current_read_seq = CurrentReadSeq + 1, + fragments = Fragments1}. + +dtls_hs_state_add_fragment(MessageSeq, Fragment, HsState0 = #dtls_hs_state{fragments = Fragments0}) -> + Fragments1 = gb_trees:enter(MessageSeq, Fragment, Fragments0), + HsState0#dtls_hs_state{fragments = Fragments1}. + +reassemble_dtls_fragment(SeqNo, Type, Length, MessageSeq, 0, Length, + Body, HsState0 = #dtls_hs_state{current_read_seq = undefined}) + when Type == ?CLIENT_HELLO; + Type == ?SERVER_HELLO; + Type == ?HELLO_VERIFY_REQUEST -> + %% First message, should be client hello + %% return the current message and set the next expected Sequence + %% + %% Note: this could (should?) be restricted further, ClientHello and + %% HelloVerifyRequest have to have message_seq = 0, ServerHello + %% can have a message_seq of 0 or 1 + %% + {HsState0#dtls_hs_state{current_read_seq = MessageSeq + 1}, SeqNo, Body}; + +reassemble_dtls_fragment(_SeqNo, _Type, Length, _MessageSeq, _, Length, + _Body, HsState = #dtls_hs_state{current_read_seq = undefined}) -> + %% not what we expected, drop it + HsState; + +reassemble_dtls_fragment(SeqNo, _Type, Length, MessageSeq, 0, Length, + Body, HsState0 = + #dtls_hs_state{starting_read_seq = StartingReadSeq}) + when MessageSeq < StartingReadSeq -> + %% this has to be the start of a new flight, let it through + %% + %% Note: this could (should?) be restricted further, the first message of a + %% new flight has to have message_seq = 0 + %% + HsState = dtls_hs_state_process_seq(HsState0), + {HsState, SeqNo, Body}; + +reassemble_dtls_fragment(_SeqNo, _Type, Length, MessageSeq, 0, Length, + _Body, HsState = + #dtls_hs_state{current_read_seq = CurrentReadSeq}) + when MessageSeq < CurrentReadSeq -> + {retransmit, HsState}; + +reassemble_dtls_fragment(_SeqNo, _Type, Length, MessageSeq, 0, Length, + _Body, HsState = #dtls_hs_state{current_read_seq = CurrentReadSeq}) + when MessageSeq < CurrentReadSeq -> + HsState; + +reassemble_dtls_fragment(SeqNo, _Type, Length, MessageSeq, 0, Length, + Body, HsState0 = #dtls_hs_state{current_read_seq = MessageSeq}) -> + %% Message fully contained and it's the current seq + HsState1 = dtls_hs_state_process_seq(HsState0), + {HsState1, SeqNo, Body}; + +reassemble_dtls_fragment(SeqNo, Type, Length, MessageSeq, 0, Length, + Body, HsState) -> + %% Message fully contained and it's the NOT the current seq -> buffer + Fragment = {SeqNo, Type, Length, MessageSeq, + dtls_fragment_init(Length, 0, Length, Body)}, + dtls_hs_state_add_fragment(MessageSeq, Fragment, HsState); + +reassemble_dtls_fragment(_SeqNo, _Type, Length, MessageSeq, FragmentOffset, FragmentLength, + _Body, + HsState = #dtls_hs_state{current_read_seq = CurrentReadSeq}) + when FragmentOffset + FragmentLength == Length andalso MessageSeq == (CurrentReadSeq - 1) -> + {retransmit, HsState}; + +reassemble_dtls_fragment(_SeqNo, _Type, _Length, MessageSeq, _FragmentOffset, _FragmentLength, + _Body, + HsState = #dtls_hs_state{current_read_seq = CurrentReadSeq}) + when MessageSeq < CurrentReadSeq -> + HsState; + +reassemble_dtls_fragment(SeqNo, Type, Length, MessageSeq, + FragmentOffset, FragmentLength, + Body, + HsState = #dtls_hs_state{fragments = Fragments0}) -> + case gb_trees:lookup(MessageSeq, Fragments0) of + {value, Fragment} -> + dtls_fragment_reassemble(SeqNo, Type, Length, MessageSeq, + FragmentOffset, FragmentLength, + Body, Fragment, HsState); + none -> + dtls_fragment_start(SeqNo, Type, Length, MessageSeq, + FragmentOffset, FragmentLength, + Body, HsState) + end. + +dtls_fragment_start(SeqNo, Type, Length, MessageSeq, + FragmentOffset, FragmentLength, + Body, HsState = #dtls_hs_state{fragments = Fragments0}) -> + Fragment = {SeqNo, Type, Length, MessageSeq, + dtls_fragment_init(Length, FragmentOffset, FragmentLength, Body)}, + Fragments1 = gb_trees:insert(MessageSeq, Fragment, Fragments0), + HsState#dtls_hs_state{fragments = Fragments1}. + +dtls_fragment_reassemble(SeqNo, Type, Length, MessageSeq, + FragmentOffset, FragmentLength, + Body, + {LastSeqNo, Type, Length, MessageSeq, FragBuffer0}, + HsState = #dtls_hs_state{fragments = Fragments0}) -> + FragBuffer1 = dtls_fragment_add(FragBuffer0, FragmentOffset, FragmentLength, Body), + Fragment = {erlang:max(SeqNo, LastSeqNo), Type, Length, MessageSeq, FragBuffer1}, + Fragments1 = gb_trees:enter(MessageSeq, Fragment, Fragments0), + HsState#dtls_hs_state{fragments = Fragments1}; + +%% Type, Length or Seq mismatch, drop everything... +%% Note: the RFC is not clear on how to handle this... +dtls_fragment_reassemble(_SeqNo, _Type, _Length, MessageSeq, + _FragmentOffset, _FragmentLength, _Body, _Fragment, + HsState = #dtls_hs_state{fragments = Fragments0}) -> + Fragments1 = gb_trees:delete_any(MessageSeq, Fragments0), + HsState#dtls_hs_state{fragments = Fragments1}. + +dtls_fragment_add({Length, FragmentList0, Bin0}, FragmentOffset, FragmentLength, Body) -> + Bin1 = dtls_fragment_bin_add(FragmentOffset, FragmentLength, Body, Bin0), + FragmentList1 = add_fragment(FragmentList0, {FragmentOffset, FragmentLength}), + {Length, FragmentList1, Bin1}. + +dtls_fragment_init(Length, 0, Length, Body) -> + {Length, [{0, Length}], Body}; +dtls_fragment_init(Length, FragmentOffset, FragmentLength, Body) -> + Bin = dtls_fragment_bin_add(FragmentOffset, FragmentLength, Body, <<0:(Length*8)>>), + {Length, [{FragmentOffset, FragmentLength}], Bin}. + +dtls_fragment_bin_add(FragmentOffset, FragmentLength, Add, Buffer) -> + <<First:FragmentOffset/bytes, _:FragmentLength/bytes, Rest/binary>> = Buffer, + <<First/binary, Add/binary, Rest/binary>>. + +merge_fragment_list([], Fragment, Acc) -> + lists:reverse([Fragment|Acc]); + +merge_fragment_list([H = {_, HEnd}|Rest], Frag = {FStart, _}, Acc) + when FStart > HEnd -> + merge_fragment_list(Rest, Frag, [H|Acc]); + +merge_fragment_list(Rest = [{HStart, _HEnd}|_], Frag = {_FStart, FEnd}, Acc) + when FEnd < HStart -> + lists:reverse(Acc) ++ [Frag|Rest]; + +merge_fragment_list([{HStart, HEnd}|Rest], _Frag = {FStart, FEnd}, Acc) + when + FStart =< HEnd orelse FEnd >= HStart -> + Start = erlang:min(HStart, FStart), + End = erlang:max(HEnd, FEnd), + NewFrag = {Start, End}, + merge_fragment_list(Rest, NewFrag, Acc). + +add_fragment(List, {FragmentOffset, FragmentLength}) -> + merge_fragment_list(List, {FragmentOffset, FragmentOffset + FragmentLength}, []). + +enc_hs(#hello_verify_request{protocol_version = {Major, Minor}, + cookie = Cookie}, _Version) -> + CookieLength = byte_size(Cookie), + {?HELLO_VERIFY_REQUEST, <<?BYTE(Major), ?BYTE(Minor), + ?BYTE(CookieLength), + Cookie/binary>>}; + +enc_hs(#client_hello{client_version = {Major, Minor}, + random = Random, + session_id = SessionID, + cookie = Cookie, + cipher_suites = CipherSuites, + compression_methods = CompMethods, + extensions = HelloExtensions}, Version) -> + SIDLength = byte_size(SessionID), + BinCookie = enc_client_hello_cookie(Version, Cookie), + BinCompMethods = list_to_binary(CompMethods), + CmLength = byte_size(BinCompMethods), + BinCipherSuites = list_to_binary(CipherSuites), + CsLength = byte_size(BinCipherSuites), + ExtensionsBin = ssl_handshake:encode_hello_extensions(HelloExtensions), + + {?CLIENT_HELLO, <<?BYTE(Major), ?BYTE(Minor), Random:32/binary, + ?BYTE(SIDLength), SessionID/binary, + BinCookie/binary, + ?UINT16(CsLength), BinCipherSuites/binary, + ?BYTE(CmLength), BinCompMethods/binary, ExtensionsBin/binary>>}; +enc_hs(HandshakeMsg, Version) -> + ssl_handshake:encode_handshake(HandshakeMsg, Version). + +enc_client_hello_cookie(_, <<>>) -> + <<>>; +enc_client_hello_cookie(_, Cookie) -> + CookieLength = byte_size(Cookie), + <<?BYTE(CookieLength), Cookie/binary>>. + +decode_handshake(_Version, ?CLIENT_HELLO, <<?BYTE(Major), ?BYTE(Minor), Random:32/binary, + ?BYTE(SID_length), Session_ID:SID_length/binary, + ?BYTE(Cookie_length), Cookie:Cookie_length/binary, + ?UINT16(Cs_length), CipherSuites:Cs_length/binary, + ?BYTE(Cm_length), Comp_methods:Cm_length/binary, + Extensions/binary>>) -> + + DecodedExtensions = ssl_handshake:decode_hello_extensions(Extensions), + + #client_hello{ + client_version = {Major,Minor}, + random = Random, + session_id = Session_ID, + cookie = Cookie, + cipher_suites = ssl_handshake:decode_suites('2_bytes', CipherSuites), + compression_methods = Comp_methods, + extensions = DecodedExtensions + }; + +decode_handshake(_Version, ?HELLO_VERIFY_REQUEST, <<?BYTE(Major), ?BYTE(Minor), + ?BYTE(CookieLength), Cookie:CookieLength/binary>>) -> + + #hello_verify_request{ + protocol_version = {Major,Minor}, + cookie = Cookie}; +decode_handshake(Version, Tag, Msg) -> + ssl_handshake:decode_handshake(Version, Tag, Msg). diff --git a/lib/ssl/src/dtls_handshake.hrl b/lib/ssl/src/dtls_handshake.hrl index db7b8596ae..5bdf45f627 100644 --- a/lib/ssl/src/dtls_handshake.hrl +++ b/lib/ssl/src/dtls_handshake.hrl @@ -27,6 +27,8 @@ -include("ssl_handshake.hrl"). %% Common TLS and DTLS records and Constantes +-define(HELLO_VERIFY_REQUEST, 3). + -record(client_hello, { client_version, random, @@ -35,16 +37,22 @@ cipher_suites, % cipher_suites<2..2^16-1> compression_methods, % compression_methods<1..2^8-1>, %% Extensions - renegotiation_info, - hash_signs, % supported combinations of hashes/signature algos - next_protocol_negotiation = undefined % [binary()] + extensions }). --record(hello_verify_request { +-record(hello_verify_request, { protocol_version, cookie }). --define(HELLO_VERIFY_REQUEST, 3). +-record(dtls_hs_state, + {current_read_seq, + starting_read_seq, + highest_record_seq, + fragments, + completed + }). + +-type dtls_handshake() :: #client_hello{} | #hello_verify_request{} | ssl_handshake(). -endif. % -ifdef(dtls_handshake). diff --git a/lib/ssl/src/dtls_record.erl b/lib/ssl/src/dtls_record.erl index 2469a7d26c..f667458a10 100644 --- a/lib/ssl/src/dtls_record.erl +++ b/lib/ssl/src/dtls_record.erl @@ -15,4 +15,370 @@ %% under the License. %% %% %CopyrightEnd% + +%% +%%---------------------------------------------------------------------- +%% Purpose: Handle DTLS record protocol. (Parts that are not shared with SSL/TLS) +%%---------------------------------------------------------------------- -module(dtls_record). + +-include("dtls_record.hrl"). +-include("ssl_internal.hrl"). +-include("ssl_alert.hrl"). +-include("dtls_handshake.hrl"). +-include("ssl_cipher.hrl"). + +%% Handling of incoming data +-export([get_dtls_records/2]). + +%% Decoding +-export([decode_cipher_text/2]). + +%% Encoding +-export([encode_plain_text/4]). + +%% Protocol version handling +-export([protocol_version/1, lowest_protocol_version/2, + highest_protocol_version/1, supported_protocol_versions/0, + is_acceptable_version/2, cipher/4, decipher/2]). + +-export([init_connection_state_seq/2, current_connection_state_epoch/2, + set_connection_state_by_epoch/3, connection_state_by_epoch/3]). + +-compile(inline). + +%%==================================================================== +%% Internal application API +%%==================================================================== + +%%-------------------------------------------------------------------- +-spec get_dtls_records(binary(), binary()) -> {[binary()], binary()} | #alert{}. +%% +%% Description: Given old buffer and new data from UDP/SCTP, packs up a records +%% and returns it as a list of tls_compressed binaries also returns leftover +%% data +%%-------------------------------------------------------------------- +get_dtls_records(Data, <<>>) -> + get_dtls_records_aux(Data, []); +get_dtls_records(Data, Buffer) -> + get_dtls_records_aux(list_to_binary([Buffer, Data]), []). + +get_dtls_records_aux(<<?BYTE(?APPLICATION_DATA),?BYTE(MajVer),?BYTE(MinVer), + ?UINT16(Epoch), ?UINT48(SequenceNumber), + ?UINT16(Length), Data:Length/binary, Rest/binary>>, + Acc) -> + get_dtls_records_aux(Rest, [#ssl_tls{type = ?APPLICATION_DATA, + version = {MajVer, MinVer}, + epoch = Epoch, record_seq = SequenceNumber, + fragment = Data} | Acc]); +get_dtls_records_aux(<<?BYTE(?HANDSHAKE),?BYTE(MajVer),?BYTE(MinVer), + ?UINT16(Epoch), ?UINT48(SequenceNumber), + ?UINT16(Length), + Data:Length/binary, Rest/binary>>, Acc) when MajVer >= 128 -> + get_dtls_records_aux(Rest, [#ssl_tls{type = ?HANDSHAKE, + version = {MajVer, MinVer}, + epoch = Epoch, record_seq = SequenceNumber, + fragment = Data} | Acc]); +get_dtls_records_aux(<<?BYTE(?ALERT),?BYTE(MajVer),?BYTE(MinVer), + ?UINT16(Epoch), ?UINT48(SequenceNumber), + ?UINT16(Length), Data:Length/binary, + Rest/binary>>, Acc) -> + get_dtls_records_aux(Rest, [#ssl_tls{type = ?ALERT, + version = {MajVer, MinVer}, + epoch = Epoch, record_seq = SequenceNumber, + fragment = Data} | Acc]); +get_dtls_records_aux(<<?BYTE(?CHANGE_CIPHER_SPEC),?BYTE(MajVer),?BYTE(MinVer), + ?UINT16(Epoch), ?UINT48(SequenceNumber), + ?UINT16(Length), Data:Length/binary, Rest/binary>>, + Acc) -> + get_dtls_records_aux(Rest, [#ssl_tls{type = ?CHANGE_CIPHER_SPEC, + version = {MajVer, MinVer}, + epoch = Epoch, record_seq = SequenceNumber, + fragment = Data} | Acc]); + +get_dtls_records_aux(<<0:1, _CT:7, ?BYTE(_MajVer), ?BYTE(_MinVer), + ?UINT16(Length), _/binary>>, + _Acc) when Length > ?MAX_CIPHER_TEXT_LENGTH -> + ?ALERT_REC(?FATAL, ?RECORD_OVERFLOW); + +get_dtls_records_aux(<<1:1, Length0:15, _/binary>>,_Acc) + when Length0 > ?MAX_CIPHER_TEXT_LENGTH -> + ?ALERT_REC(?FATAL, ?RECORD_OVERFLOW); + +get_dtls_records_aux(Data, Acc) -> + case size(Data) =< ?MAX_CIPHER_TEXT_LENGTH + ?INITIAL_BYTES of + true -> + {lists:reverse(Acc), Data}; + false -> + ?ALERT_REC(?FATAL, ?UNEXPECTED_MESSAGE) + end. + +encode_plain_text(Type, Version, Data, + #connection_state{ + compression_state = CompS0, + epoch = Epoch, + sequence_number = Seq, + security_parameters= + #security_parameters{compression_algorithm = CompAlg} + }= CS0) -> + {Comp, CompS1} = ssl_record:compress(CompAlg, Data, CompS0), + CS1 = CS0#connection_state{compression_state = CompS1}, + {CipherText, CS2} = cipher(Type, Version, Comp, CS1), + CTBin = encode_tls_cipher_text(Type, Version, Epoch, Seq, CipherText), + {CTBin, CS2}. + +decode_cipher_text(CipherText, ConnnectionStates0) -> + ReadState0 = ConnnectionStates0#connection_states.current_read, + #connection_state{compression_state = CompressionS0, + security_parameters = SecParams} = ReadState0, + CompressAlg = SecParams#security_parameters.compression_algorithm, + case decipher(CipherText, ReadState0) of + {Compressed, ReadState1} -> + {Plain, CompressionS1} = ssl_record:uncompress(CompressAlg, + Compressed, CompressionS0), + ConnnectionStates = ConnnectionStates0#connection_states{ + current_read = ReadState1#connection_state{ + compression_state = CompressionS1}}, + {Plain, ConnnectionStates}; + #alert{} = Alert -> + Alert + end. + +%%-------------------------------------------------------------------- +-spec protocol_version(tls_atom_version() | tls_version()) -> + tls_version() | tls_atom_version(). +%% +%% Description: Creates a protocol version record from a version atom +%% or vice versa. +%%-------------------------------------------------------------------- +protocol_version('dtlsv1.2') -> + {254, 253}; +protocol_version(dtlsv1) -> + {254, 255}; +protocol_version({254, 253}) -> + 'dtlsv1.2'; +protocol_version({254, 255}) -> + dtlsv1. +%%-------------------------------------------------------------------- +-spec lowest_protocol_version(tls_version(), tls_version()) -> tls_version(). +%% +%% Description: Lowes protocol version of two given versions +%%-------------------------------------------------------------------- +lowest_protocol_version(Version = {M, N}, {M, O}) when N > O -> + Version; +lowest_protocol_version({M, _}, Version = {M, _}) -> + Version; +lowest_protocol_version(Version = {M,_}, {N, _}) when M > N -> + Version; +lowest_protocol_version(_,Version) -> + Version. +%%-------------------------------------------------------------------- +-spec highest_protocol_version([tls_version()]) -> tls_version(). +%% +%% Description: Highest protocol version present in a list +%%-------------------------------------------------------------------- +highest_protocol_version([Ver | Vers]) -> + highest_protocol_version(Ver, Vers). + +highest_protocol_version(Version, []) -> + Version; +highest_protocol_version(Version = {N, M}, [{N, O} | Rest]) when M < O -> + highest_protocol_version(Version, Rest); +highest_protocol_version({M, _}, [Version = {M, _} | Rest]) -> + highest_protocol_version(Version, Rest); +highest_protocol_version(Version = {M,_}, [{N,_} | Rest]) when M < N -> + highest_protocol_version(Version, Rest); +highest_protocol_version(_, [Version | Rest]) -> + highest_protocol_version(Version, Rest). + + +%%-------------------------------------------------------------------- +-spec supported_protocol_versions() -> [tls_version()]. +%% +%% Description: Protocol versions supported +%%-------------------------------------------------------------------- +supported_protocol_versions() -> + Fun = fun(Version) -> + protocol_version(Version) + end, + case application:get_env(ssl, dtls_protocol_version) of + undefined -> + lists:map(Fun, supported_protocol_versions([])); + {ok, []} -> + lists:map(Fun, supported_protocol_versions([])); + {ok, Vsns} when is_list(Vsns) -> + supported_protocol_versions(Vsns); + {ok, Vsn} -> + supported_protocol_versions([Vsn]) + end. + +supported_protocol_versions([]) -> + Vsns = supported_connection_protocol_versions([]), + application:set_env(ssl, dtls_protocol_version, Vsns), + Vsns; + +supported_protocol_versions([_|_] = Vsns) -> + Vsns. + +supported_connection_protocol_versions([]) -> + ?ALL_DATAGRAM_SUPPORTED_VERSIONS. + +%%-------------------------------------------------------------------- +-spec is_acceptable_version(tls_version(), Supported :: [tls_version()]) -> boolean(). +%% +%% Description: ssl version 2 is not acceptable security risks are too big. +%% +%%-------------------------------------------------------------------- +is_acceptable_version(Version, Versions) -> + lists:member(Version, Versions). + + +%%-------------------------------------------------------------------- +-spec init_connection_state_seq(tls_version(), #connection_states{}) -> + #connection_state{}. +%% +%% Description: Copy the read sequence number to the write sequence number +%% This is only valid for DTLS in the first client_hello +%%-------------------------------------------------------------------- +init_connection_state_seq({254, _}, + #connection_states{ + current_read = Read = #connection_state{epoch = 0}, + current_write = Write = #connection_state{epoch = 0}} = CS0) -> + CS0#connection_states{current_write = + Write#connection_state{ + sequence_number = Read#connection_state.sequence_number}}; +init_connection_state_seq(_, CS) -> + CS. + +%%-------------------------------------------------------- +-spec current_connection_state_epoch(#connection_states{}, read | write) -> + integer(). +%% +%% Description: Returns the epoch the connection_state record +%% that is currently defined as the current conection state. +%%-------------------------------------------------------------------- +current_connection_state_epoch(#connection_states{current_read = Current}, + read) -> + Current#connection_state.epoch; +current_connection_state_epoch(#connection_states{current_write = Current}, + write) -> + Current#connection_state.epoch. + +%%-------------------------------------------------------------------- + +-spec connection_state_by_epoch(#connection_states{}, integer(), read | write) -> + #connection_state{}. +%% +%% Description: Returns the instance of the connection_state record +%% that is defined by the Epoch. +%%-------------------------------------------------------------------- +connection_state_by_epoch(#connection_states{current_read = CS}, Epoch, read) + when CS#connection_state.epoch == Epoch -> + CS; +connection_state_by_epoch(#connection_states{pending_read = CS}, Epoch, read) + when CS#connection_state.epoch == Epoch -> + CS; +connection_state_by_epoch(#connection_states{current_write = CS}, Epoch, write) + when CS#connection_state.epoch == Epoch -> + CS; +connection_state_by_epoch(#connection_states{pending_write = CS}, Epoch, write) + when CS#connection_state.epoch == Epoch -> + CS. +%%-------------------------------------------------------------------- +-spec set_connection_state_by_epoch(#connection_states{}, + #connection_state{}, read | write) -> ok. +%% +%% Description: Returns the instance of the connection_state record +%% that is defined by the Epoch. +%%-------------------------------------------------------------------- +set_connection_state_by_epoch(ConnectionStates0 = + #connection_states{current_read = CS}, + NewCS = #connection_state{epoch = Epoch}, read) + when CS#connection_state.epoch == Epoch -> + ConnectionStates0#connection_states{current_read = NewCS}; + +set_connection_state_by_epoch(ConnectionStates0 = + #connection_states{pending_read = CS}, + NewCS = #connection_state{epoch = Epoch}, read) + when CS#connection_state.epoch == Epoch -> + ConnectionStates0#connection_states{pending_read = NewCS}; + +set_connection_state_by_epoch(ConnectionStates0 = + #connection_states{current_write = CS}, + NewCS = #connection_state{epoch = Epoch}, write) + when CS#connection_state.epoch == Epoch -> + ConnectionStates0#connection_states{current_write = NewCS}; + +set_connection_state_by_epoch(ConnectionStates0 = + #connection_states{pending_write = CS}, + NewCS = #connection_state{epoch = Epoch}, write) + when CS#connection_state.epoch == Epoch -> + ConnectionStates0#connection_states{pending_write = NewCS}. + +%%-------------------------------------------------------------------- +%%% Internal functions +%%-------------------------------------------------------------------- +encode_tls_cipher_text(Type, {MajVer, MinVer}, Epoch, Seq, Fragment) -> + Length = erlang:iolist_size(Fragment), + [<<?BYTE(Type), ?BYTE(MajVer), ?BYTE(MinVer), ?UINT16(Epoch), + ?UINT48(Seq), ?UINT16(Length)>>, Fragment]. + +cipher(Type, Version, Fragment, CS0) -> + Length = erlang:iolist_size(Fragment), + {MacHash, CS1=#connection_state{cipher_state = CipherS0, + security_parameters= + #security_parameters{bulk_cipher_algorithm = + BCA} + }} = + hash_and_bump_seqno(CS0, Type, Version, Length, Fragment), + {Ciphered, CipherS1} = ssl_cipher:cipher(BCA, CipherS0, MacHash, Fragment, Version), + CS2 = CS1#connection_state{cipher_state=CipherS1}, + {Ciphered, CS2}. + +decipher(TLS=#ssl_tls{type=Type, version=Version={254, _}, + epoch = Epoch, record_seq = SeqNo, + fragment=Fragment}, CS0) -> + SP = CS0#connection_state.security_parameters, + BCA = SP#security_parameters.bulk_cipher_algorithm, + HashSz = SP#security_parameters.hash_size, + CipherS0 = CS0#connection_state.cipher_state, + case ssl_cipher:decipher(BCA, HashSz, CipherS0, Fragment, Version) of + {T, Mac, CipherS1} -> + CS1 = CS0#connection_state{cipher_state = CipherS1}, + TLength = size(T), + MacHash = hash_with_seqno(CS1, Type, Version, Epoch, SeqNo, TLength, T), + case ssl_record:is_correct_mac(Mac, MacHash) of + true -> + {TLS#ssl_tls{fragment = T}, CS1}; + false -> + ?ALERT_REC(?FATAL, ?BAD_RECORD_MAC) + end; + #alert{} = Alert -> + Alert + end. + +hash_with_seqno(#connection_state{mac_secret = MacSecret, + security_parameters = + SecPars}, + Type, Version = {254, _}, + Epoch, SeqNo, Length, Fragment) -> + mac_hash(Version, + SecPars#security_parameters.mac_algorithm, + MacSecret, (Epoch bsl 48) + SeqNo, Type, + Length, Fragment). + +hash_and_bump_seqno(#connection_state{epoch = Epoch, + sequence_number = SeqNo, + mac_secret = MacSecret, + security_parameters = + SecPars} = CS0, + Type, Version = {254, _}, Length, Fragment) -> + Hash = mac_hash(Version, + SecPars#security_parameters.mac_algorithm, + MacSecret, (Epoch bsl 48) + SeqNo, Type, + Length, Fragment), + {Hash, CS0#connection_state{sequence_number = SeqNo+1}}. + +mac_hash(Version, MacAlg, MacSecret, SeqNo, Type, Length, Fragment) -> + dtls_v1:mac_hash(MacAlg, MacSecret, SeqNo, Type, Version, + Length, Fragment). diff --git a/lib/ssl/src/dtls_v1.erl b/lib/ssl/src/dtls_v1.erl new file mode 100644 index 0000000000..c12e12e424 --- /dev/null +++ b/lib/ssl/src/dtls_v1.erl @@ -0,0 +1,43 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2013-2013. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +-module(dtls_v1). + +-include("ssl_cipher.hrl"). + +-export([suites/1, mac_hash/7, ecc_curves/1, corresponding_tls_version/1]). + +-spec suites(Minor:: 253|255) -> [cipher_suite()]. + +suites(Minor) -> + tls_v1:suites(corresponding_minor_tls_version(Minor)). + +mac_hash(Version, MacAlg, MacSecret, SeqNo, Type, Length, Fragment) -> + tls_v1:mac_hash(MacAlg, MacSecret, SeqNo, Type, Version, + Length, Fragment). + +ecc_curves({_Major, Minor}) -> + tls_v1:ecc_curves(corresponding_minor_tls_version(Minor)). + +corresponding_tls_version({254, Minor}) -> + {3, corresponding_minor_tls_version(Minor)}. + +corresponding_minor_tls_version(255) -> + 2; +corresponding_minor_tls_version(253) -> + 3. diff --git a/lib/ssl/src/ssl.app.src b/lib/ssl/src/ssl.app.src index 582a60635f..44798f8c12 100644 --- a/lib/ssl/src/ssl.app.src +++ b/lib/ssl/src/ssl.app.src @@ -3,40 +3,44 @@ {vsn, "%VSN%"}, {modules, [ %% TLS/SSL - tls, tls_connection, tls_handshake, tls_record, + tls_v1, + ssl_v3, + ssl_v2, %% DTLS - dtls_record, - dtls_handshake, dtls_connection, - dtls, - %% Backwards compatibility + dtls_handshake, + dtls_record, + dtls_v1, + %% API + tls, %% Future API module + dtls, %% Future API module ssl, + ssl_session_cache_api, %% Both TLS/SSL and DTLS - ssl_app, - ssl_sup, + ssl_handshake, + ssl_record, + ssl_cipher, + ssl_srp_primes, + ssl_alert, + ssl_socket, + %%ssl_connection, + %% Erlang Distribution over SSL/TLS inet_tls_dist, ssl_tls_dist_proxy, ssl_dist_sup, - ssl_tls1, - ssl_ssl3, - ssl_ssl2, + %% SSL/TLS session handling ssl_session, - ssl_session_cache_api, ssl_session_cache, - ssl_socket, - %%ssl_record, ssl_manager, - %%ssl_handshake, - ssl_connection_sup, - %%ssl_connection, - ssl_cipher, - ssl_srp_primes, ssl_pkix_db, ssl_certificate, - ssl_alert + %% App structure + ssl_app, + ssl_sup, + ssl_connection_sup ]}, {registered, [ssl_sup, ssl_manager]}, {applications, [crypto, public_key, kernel, stdlib]}, diff --git a/lib/ssl/src/ssl.appup.src b/lib/ssl/src/ssl.appup.src index 9e5bec26f1..c090b6ebfb 100644 --- a/lib/ssl/src/ssl.appup.src +++ b/lib/ssl/src/ssl.appup.src @@ -1,6 +1,7 @@ %% -*- erlang -*- {"%VSN%", [ + {<<"5.3\\*">>, [{restart_application, ssl}]}, {<<"5.2\\*">>, [{restart_application, ssl}]}, {<<"5.1\\*">>, [{restart_application, ssl}]}, {<<"5.0\\*">>, [{restart_application, ssl}]}, @@ -8,6 +9,7 @@ {<<"3\\.*">>, [{restart_application, ssl}]} ], [ + {<<"5.3\\*">>, [{restart_application, ssl}]}, {<<"5.2\\*">>, [{restart_application, ssl}]}, {<<"5.1\\*">>, [{restart_application, ssl}]}, {<<"5.0\\*">>, [{restart_application, ssl}]}, diff --git a/lib/ssl/src/ssl_cipher.erl b/lib/ssl/src/ssl_cipher.erl index ec5d793d65..e6ed0d8626 100644 --- a/lib/ssl/src/ssl_cipher.erl +++ b/lib/ssl/src/ssl_cipher.erl @@ -32,16 +32,26 @@ -include("ssl_alert.hrl"). -include_lib("public_key/include/public_key.hrl"). --export([security_parameters/3, suite_definition/1, +-export([security_parameters/2, security_parameters/3, suite_definition/1, decipher/5, cipher/5, - suite/1, suites/1, anonymous_suites/0, psk_suites/1, srp_suites/0, + suite/1, suites/1, ec_keyed_suites/0, anonymous_suites/0, psk_suites/1, srp_suites/0, openssl_suite/1, openssl_suite_name/1, filter/2, filter_suites/1, - hash_algorithm/1, sign_algorithm/1]). + hash_algorithm/1, sign_algorithm/1, is_acceptable_hash/2]). -compile(inline). %%-------------------------------------------------------------------- --spec security_parameters(tls_version(), cipher_suite(), #security_parameters{}) -> +-spec security_parameters(cipher_suite(), #security_parameters{}) -> + #security_parameters{}. +%% Only security_parameters/2 should call security_parameters/3 with undefined as +%% first argument. +%%-------------------------------------------------------------------- + +security_parameters(?TLS_NULL_WITH_NULL_NULL = CipherSuite, SecParams) -> + security_parameters(undefined, CipherSuite, SecParams). + +%%-------------------------------------------------------------------- +-spec security_parameters(tls_version() | undefined, cipher_suite(), #security_parameters{}) -> #security_parameters{}. %% %% Description: Returns a security parameters record where the @@ -195,9 +205,9 @@ block_decipher(Fun, #cipher_state{key=Key, iv=IV} = CipherState0, %% Description: Returns a list of supported cipher suites. %%-------------------------------------------------------------------- suites({3, 0}) -> - ssl_ssl3:suites(); + ssl_v3:suites(); suites({3, N}) -> - ssl_tls1:suites(N). + tls_v1:suites(N). %%-------------------------------------------------------------------- -spec anonymous_suites() -> [cipher_suite()]. @@ -1009,6 +1019,7 @@ filter(DerCert, Ciphers) -> filter_keyuse(OtpCert, (Ciphers -- rsa_keyed_suites()) -- dsa_signed_suites(), [], ecdhe_ecdsa_suites()) end, + case public_key:pkix_sign_types(SigAlg#'SignatureAlgorithm'.algorithm) of {_, rsa} -> Ciphers1 -- ecdsa_signed_suites(); @@ -1191,15 +1202,15 @@ hash_size(md5) -> hash_size(sha) -> 20; %% Uncomment when adding cipher suite that needs it -%% hash_size(sha224) -> -%% 28; +%hash_size(sha224) -> +% 28; hash_size(sha256) -> 32; hash_size(sha384) -> 48. %% Uncomment when adding cipher suite that needs it -%% hash_size(sha512) -> -%% 64. +%hash_size(sha512) -> +% 64. %% RFC 5246: 6.2.3.2. CBC Block Cipher %% @@ -1259,15 +1270,15 @@ generic_stream_cipher_from_bin(T, HashSz) -> %% SSL 3.0 and TLS 1.0 as it is not strictly required and breaks %% interopability with for instance Google. is_correct_padding(#generic_block_cipher{padding_length = Len, - padding = Padding}, {3, N}) + padding = Padding}, {3, N}) when N == 0; N == 1 -> Len == byte_size(Padding); %% Padding must be check in TLS 1.1 and after is_correct_padding(#generic_block_cipher{padding_length = Len, - padding = Padding}, _) -> + padding = Padding}, _) -> Len == byte_size(Padding) andalso list_to_binary(lists:duplicate(Len, Len)) == Padding. - + get_padding(Length, BlockSize) -> get_padding_aux(BlockSize, Length rem BlockSize). @@ -1291,7 +1302,7 @@ next_iv(Bin, IV) -> rsa_signed_suites() -> dhe_rsa_suites() ++ rsa_suites() ++ psk_rsa_suites() ++ srp_rsa_suites() ++ - ecdh_rsa_suites(). + ecdh_rsa_suites() ++ ecdhe_rsa_suites(). rsa_keyed_suites() -> dhe_rsa_suites() ++ rsa_suites() ++ diff --git a/lib/ssl/src/ssl_cipher.hrl b/lib/ssl/src/ssl_cipher.hrl index c7c71ee1a7..62a5269def 100644 --- a/lib/ssl/src/ssl_cipher.hrl +++ b/lib/ssl/src/ssl_cipher.hrl @@ -28,7 +28,8 @@ -type cipher() :: null |rc4_128 | idea_cbc | des40_cbc | des_cbc | '3des_ede_cbc' | aes_128_cbc | aes_256_cbc. --type hash() :: null | sha | md5 | ssh224 | sha256 | sha384 | sha512. +-type hash() :: null | sha | md5 | sha224 | sha256 | sha384 | sha512. +-type key_algo() :: null | rsa | dhe_rsa | dhe_dss | ecdhe_ecdsa| ecdh_ecdsa | ecdh_rsa| srp_rsa| srp_dss | psk | dhe_psk | rsa_psk | dh_anon | ecdh_anon | srp_anon. -type erl_cipher_suite() :: {key_algo(), cipher(), hash()}. -type int_cipher_suite() :: {key_algo(), cipher(), hash(), hash() | default_prf}. -type cipher_suite() :: binary(). diff --git a/lib/ssl/src/ssl_handshake.erl b/lib/ssl/src/ssl_handshake.erl new file mode 100644 index 0000000000..b18452a8f2 --- /dev/null +++ b/lib/ssl/src/ssl_handshake.erl @@ -0,0 +1,1672 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2013-2013. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% + +%---------------------------------------------------------------------- +%% Purpose: Help funtions for handling the SSL-handshake protocol (common +%% to SSL/TLS and DTLS +%%---------------------------------------------------------------------- + +-module(ssl_handshake). + +-include("ssl_handshake.hrl"). +-include("ssl_record.hrl"). +-include("ssl_cipher.hrl"). +-include("ssl_alert.hrl"). +-include("ssl_internal.hrl"). +-include("ssl_srp.hrl"). +-include_lib("public_key/include/public_key.hrl"). + +%% Handshake messages +-export([hello_request/0, server_hello_done/0, + certificate/4, certificate_request/4, key_exchange/3, + finished/5, next_protocol/1]). + +%% Handle handshake messages +-export([certify/7, client_certificate_verify/6, certificate_verify/6, verify_signature/5, + master_secret/5, server_key_exchange_hash/2, verify_connection/6]). + +%% Encode/Decode +-export([encode_handshake/2, encode_hello_extensions/1, + encode_client_protocol_negotiation/2, encode_protocols_advertised_on_server/1, + decode_handshake/3, decode_hello_extensions/1, + decode_server_key/3, decode_client_key/3, + decode_suites/2 + ]). + +%% Cipher suites handling +-export([available_suites/2, cipher_suites/2, + select_session/10, supported_ecc/1]). + +%% Extensions handling +-export([client_hello_extensions/5, + handle_client_hello_extensions/8, %% Returns server hello extensions + handle_server_hello_extensions/9, select_curve/2 + ]). + +%% MISC +-export([select_version/3, prf/5, select_hashsign/2, select_cert_hashsign/3, + decrypt_premaster_secret/2]). + +%%==================================================================== +%% Internal application API +%%==================================================================== + +%% ---------- Create handshake messages ---------- + +%%-------------------------------------------------------------------- +-spec hello_request() -> #hello_request{}. +%% +%% Description: Creates a hello request message sent by server to +%% trigger renegotiation. +%%-------------------------------------------------------------------- +hello_request() -> + #hello_request{}. + +%%-------------------------------------------------------------------- +-spec server_hello_done() -> #server_hello_done{}. +%% +%% Description: Creates a server hello done message. +%%-------------------------------------------------------------------- +server_hello_done() -> + #server_hello_done{}. + +client_hello_extensions(Version, CipherSuites, SslOpts, ConnectionStates, Renegotiation) -> + {EcPointFormats, EllipticCurves} = + case advertises_ec_ciphers(lists:map(fun ssl_cipher:suite_definition/1, CipherSuites)) of + true -> + client_ecc_extensions(tls_v1, Version); + false -> + {undefined, undefined} + end, + SRP = srp_user(SslOpts), + + #hello_extensions{ + renegotiation_info = renegotiation_info(tls_record, client, + ConnectionStates, Renegotiation), + srp = SRP, + hash_signs = advertised_hash_signs(Version), + ec_point_formats = EcPointFormats, + elliptic_curves = EllipticCurves, + next_protocol_negotiation = + encode_client_protocol_negotiation(SslOpts#ssl_options.next_protocol_selector, + Renegotiation)}. + +%%-------------------------------------------------------------------- +-spec certificate(der_cert(), db_handle(), certdb_ref(), client | server) -> #certificate{} | #alert{}. +%% +%% Description: Creates a certificate message. +%%-------------------------------------------------------------------- +certificate(OwnCert, CertDbHandle, CertDbRef, client) -> + Chain = + case ssl_certificate:certificate_chain(OwnCert, CertDbHandle, CertDbRef) of + {ok, CertChain} -> + CertChain; + {error, _} -> + %% If no suitable certificate is available, the client + %% SHOULD send a certificate message containing no + %% certificates. (chapter 7.4.6. RFC 4346) + [] + end, + #certificate{asn1_certificates = Chain}; + +certificate(OwnCert, CertDbHandle, CertDbRef, server) -> + case ssl_certificate:certificate_chain(OwnCert, CertDbHandle, CertDbRef) of + {ok, Chain} -> + #certificate{asn1_certificates = Chain}; + {error, _} -> + ?ALERT_REC(?FATAL, ?INTERNAL_ERROR) + end. + +%%-------------------------------------------------------------------- +-spec next_protocol(binary()) -> #next_protocol{}. +%% +%% Description: Creates a next protocol message +%%------------------------------------------------------------------- +next_protocol(SelectedProtocol) -> + #next_protocol{selected_protocol = SelectedProtocol}. + +%%-------------------------------------------------------------------- +-spec client_certificate_verify(undefined | der_cert(), binary(), + tls_version(), term(), private_key(), + tls_handshake_history()) -> + #certificate_verify{} | ignore | #alert{}. +%% +%% Description: Creates a certificate_verify message, called by the client. +%%-------------------------------------------------------------------- +client_certificate_verify(undefined, _, _, _, _, _) -> + ignore; +client_certificate_verify(_, _, _, _, undefined, _) -> + ignore; +client_certificate_verify(OwnCert, MasterSecret, Version, + {HashAlgo, SignAlgo}, + PrivateKey, {Handshake, _}) -> + case public_key:pkix_is_fixed_dh_cert(OwnCert) of + true -> + ?ALERT_REC(?FATAL, ?UNSUPPORTED_CERTIFICATE); + false -> + Hashes = + calc_certificate_verify(Version, HashAlgo, MasterSecret, Handshake), + Signed = digitally_signed(Version, Hashes, HashAlgo, PrivateKey), + #certificate_verify{signature = Signed, hashsign_algorithm = {HashAlgo, SignAlgo}} + end. + +%%-------------------------------------------------------------------- +-spec certificate_request(erl_cipher_suite(), db_handle(), certdb_ref(), tls_version()) -> + #certificate_request{}. +%% +%% Description: Creates a certificate_request message, called by the server. +%%-------------------------------------------------------------------- +certificate_request(CipherSuite, CertDbHandle, CertDbRef, Version) -> + Types = certificate_types(CipherSuite), + HashSigns = advertised_hash_signs(Version), + Authorities = certificate_authorities(CertDbHandle, CertDbRef), + #certificate_request{ + certificate_types = Types, + hashsign_algorithms = HashSigns, + certificate_authorities = Authorities + }. +%%-------------------------------------------------------------------- +-spec key_exchange(client | server, tls_version(), + {premaster_secret, binary(), public_key_info()} | + {dh, binary()} | + {dh, {binary(), binary()}, #'DHParameter'{}, {HashAlgo::atom(), SignAlgo::atom()}, + binary(), binary(), private_key()} | + {ecdh, #'ECPrivateKey'{}} | + {psk, binary()} | + {dhe_psk, binary(), binary()} | + {srp, {binary(), binary()}, #srp_user{}, {HashAlgo::atom(), SignAlgo::atom()}, + binary(), binary(), private_key()}) -> + #client_key_exchange{} | #server_key_exchange{}. + +%% +%% Description: Creates a keyexchange message. +%%-------------------------------------------------------------------- +key_exchange(client, _Version, {premaster_secret, Secret, {_, PublicKey, _}}) -> + EncPremasterSecret = + encrypted_premaster_secret(Secret, PublicKey), + #client_key_exchange{exchange_keys = EncPremasterSecret}; + +key_exchange(client, _Version, {dh, PublicKey}) -> + #client_key_exchange{ + exchange_keys = #client_diffie_hellman_public{ + dh_public = PublicKey} + }; + +key_exchange(client, _Version, {ecdh, #'ECPrivateKey'{publicKey = {0, ECPublicKey}}}) -> + #client_key_exchange{ + exchange_keys = #client_ec_diffie_hellman_public{ + dh_public = ECPublicKey} + }; + +key_exchange(client, _Version, {psk, Identity}) -> + #client_key_exchange{ + exchange_keys = #client_psk_identity{ + identity = Identity} + }; + +key_exchange(client, _Version, {dhe_psk, Identity, PublicKey}) -> + #client_key_exchange{ + exchange_keys = #client_dhe_psk_identity{ + identity = Identity, + dh_public = PublicKey} + }; + +key_exchange(client, _Version, {psk_premaster_secret, PskIdentity, Secret, {_, PublicKey, _}}) -> + EncPremasterSecret = + encrypted_premaster_secret(Secret, PublicKey), + #client_key_exchange{ + exchange_keys = #client_rsa_psk_identity{ + identity = PskIdentity, + exchange_keys = EncPremasterSecret}}; + +key_exchange(client, _Version, {srp, PublicKey}) -> + #client_key_exchange{ + exchange_keys = #client_srp_public{ + srp_a = PublicKey} + }; + +key_exchange(server, Version, {dh, {PublicKey, _}, + #'DHParameter'{prime = P, base = G}, + HashSign, ClientRandom, ServerRandom, PrivateKey}) -> + ServerDHParams = #server_dh_params{dh_p = int_to_bin(P), + dh_g = int_to_bin(G), dh_y = PublicKey}, + enc_server_key_exchange(Version, ServerDHParams, HashSign, + ClientRandom, ServerRandom, PrivateKey); + +key_exchange(server, Version, {ecdh, #'ECPrivateKey'{publicKey = {0, ECPublicKey}, + parameters = ECCurve}, HashSign, + ClientRandom, ServerRandom, PrivateKey}) -> + ServerECParams = #server_ecdh_params{curve = ECCurve, public = ECPublicKey}, + enc_server_key_exchange(Version, ServerECParams, HashSign, + ClientRandom, ServerRandom, PrivateKey); + +key_exchange(server, Version, {psk, PskIdentityHint, + HashSign, ClientRandom, ServerRandom, PrivateKey}) -> + ServerPSKParams = #server_psk_params{hint = PskIdentityHint}, + enc_server_key_exchange(Version, ServerPSKParams, HashSign, + ClientRandom, ServerRandom, PrivateKey); + +key_exchange(server, Version, {dhe_psk, PskIdentityHint, {PublicKey, _}, + #'DHParameter'{prime = P, base = G}, + HashSign, ClientRandom, ServerRandom, PrivateKey}) -> + ServerEDHPSKParams = #server_dhe_psk_params{ + hint = PskIdentityHint, + dh_params = #server_dh_params{dh_p = int_to_bin(P), + dh_g = int_to_bin(G), dh_y = PublicKey} + }, + enc_server_key_exchange(Version, ServerEDHPSKParams, + HashSign, ClientRandom, ServerRandom, PrivateKey); + +key_exchange(server, Version, {srp, {PublicKey, _}, + #srp_user{generator = Generator, prime = Prime, + salt = Salt}, + HashSign, ClientRandom, ServerRandom, PrivateKey}) -> + ServerSRPParams = #server_srp_params{srp_n = Prime, srp_g = Generator, + srp_s = Salt, srp_b = PublicKey}, + enc_server_key_exchange(Version, ServerSRPParams, HashSign, + ClientRandom, ServerRandom, PrivateKey). + +%%-------------------------------------------------------------------- +-spec finished(tls_version(), client | server, integer(), binary(), tls_handshake_history()) -> + #finished{}. +%% +%% Description: Creates a handshake finished message +%%------------------------------------------------------------------- +finished(Version, Role, PrfAlgo, MasterSecret, {Handshake, _}) -> % use the current handshake + #finished{verify_data = + calc_finished(Version, Role, PrfAlgo, MasterSecret, Handshake)}. + +%% ---------- Handle handshake messages ---------- + +%%-------------------------------------------------------------------- +-spec certificate_verify(binary(), public_key_info(), tls_version(), term(), + binary(), tls_handshake_history()) -> valid | #alert{}. +%% +%% Description: Checks that the certificate_verify message is valid. +%%-------------------------------------------------------------------- +certificate_verify(Signature, PublicKeyInfo, Version, + HashSign = {HashAlgo, _}, MasterSecret, {_, Handshake}) -> + Hash = calc_certificate_verify(Version, HashAlgo, MasterSecret, Handshake), + case verify_signature(Version, Hash, HashSign, Signature, PublicKeyInfo) of + true -> + valid; + _ -> + ?ALERT_REC(?FATAL, ?BAD_CERTIFICATE) + end. +%%-------------------------------------------------------------------- +-spec verify_signature(tls_version(), binary(), {term(), term()}, binary(), + public_key_info()) -> true | false. +%% +%% Description: Checks that a public_key signature is valid. +%%-------------------------------------------------------------------- +verify_signature(_Version, _Hash, {_HashAlgo, anon}, _Signature, _) -> + true; +verify_signature({3, Minor}, Hash, {HashAlgo, rsa}, Signature, {?rsaEncryption, PubKey, _PubKeyParams}) + when Minor >= 3 -> + public_key:verify({digest, Hash}, HashAlgo, Signature, PubKey); +verify_signature(_Version, Hash, _HashAlgo, Signature, {?rsaEncryption, PubKey, _PubKeyParams}) -> + case public_key:decrypt_public(Signature, PubKey, + [{rsa_pad, rsa_pkcs1_padding}]) of + Hash -> true; + _ -> false + end; +verify_signature(_Version, Hash, {HashAlgo, dsa}, Signature, {?'id-dsa', PublicKey, PublicKeyParams}) -> + public_key:verify({digest, Hash}, HashAlgo, Signature, {PublicKey, PublicKeyParams}); +verify_signature(_Version, Hash, {HashAlgo, ecdsa}, Signature, + {?'id-ecPublicKey', PublicKey, PublicKeyParams}) -> + public_key:verify({digest, Hash}, HashAlgo, Signature, {PublicKey, PublicKeyParams}). + +%%-------------------------------------------------------------------- +-spec certify(#certificate{}, db_handle(), certdb_ref(), integer() | nolimit, + verify_peer | verify_none, {fun(), term}, + client | server) -> {der_cert(), public_key_info()} | #alert{}. +%% +%% Description: Handles a certificate handshake message +%%-------------------------------------------------------------------- +certify(#certificate{asn1_certificates = ASN1Certs}, CertDbHandle, CertDbRef, + MaxPathLen, _Verify, VerifyFunAndState, Role) -> + [PeerCert | _] = ASN1Certs, + + ValidationFunAndState = + case VerifyFunAndState of + undefined -> + {fun(OtpCert, ExtensionOrVerifyResult, SslState) -> + ssl_certificate:validate_extension(OtpCert, + ExtensionOrVerifyResult, SslState) + end, Role}; + {Fun, UserState0} -> + {fun(OtpCert, {extension, _} = Extension, {SslState, UserState}) -> + case ssl_certificate:validate_extension(OtpCert, + Extension, + SslState) of + {valid, NewSslState} -> + {valid, {NewSslState, UserState}}; + {fail, Reason} -> + apply_user_fun(Fun, OtpCert, Reason, UserState, + SslState); + {unknown, _} -> + apply_user_fun(Fun, OtpCert, + Extension, UserState, SslState) + end; + (OtpCert, VerifyResult, {SslState, UserState}) -> + apply_user_fun(Fun, OtpCert, VerifyResult, UserState, + SslState) + end, {Role, UserState0}} + end, + + try + {TrustedErlCert, CertPath} = + ssl_certificate:trusted_cert_and_path(ASN1Certs, CertDbHandle, CertDbRef), + case public_key:pkix_path_validation(TrustedErlCert, + CertPath, + [{max_path_length, + MaxPathLen}, + {verify_fun, ValidationFunAndState}]) of + {ok, {PublicKeyInfo,_}} -> + {PeerCert, PublicKeyInfo}; + {error, Reason} -> + path_validation_alert(Reason) + end + catch + error:_ -> + %% ASN-1 decode of certificate somehow failed + ?ALERT_REC(?FATAL, ?CERTIFICATE_UNKNOWN) + end. + +%%-------------------------------------------------------------------- +-spec verify_connection(tls_version(), #finished{}, client | server, integer(), binary(), + tls_handshake_history()) -> verified | #alert{}. +%% +%% Description: Checks the ssl handshake finished message to verify +%% the connection. +%%------------------------------------------------------------------- +verify_connection(Version, #finished{verify_data = Data}, + Role, PrfAlgo, MasterSecret, {_, Handshake}) -> + %% use the previous hashes + case calc_finished(Version, Role, PrfAlgo, MasterSecret, Handshake) of + Data -> + verified; + _ -> + ?ALERT_REC(?FATAL, ?DECRYPT_ERROR) + end. +%%-------------------------------------------------------------------- +-spec decrypt_premaster_secret(binary(), #'RSAPrivateKey'{}) -> binary(). + +%% +%% Description: Public key decryption using the private key. +%%-------------------------------------------------------------------- +decrypt_premaster_secret(Secret, RSAPrivateKey) -> + try public_key:decrypt_private(Secret, RSAPrivateKey, + [{rsa_pad, rsa_pkcs1_padding}]) + catch + _:_ -> + throw(?ALERT_REC(?FATAL, ?DECRYPT_ERROR)) + end. +%%-------------------------------------------------------------------- +-spec server_key_exchange_hash(md5sha | md5 | sha | sha224 |sha256 | sha384 | sha512, binary()) -> binary(). +%% +%% Description: Calculate server key exchange hash +%%-------------------------------------------------------------------- +server_key_exchange_hash(md5sha, Value) -> + MD5 = crypto:hash(md5, Value), + SHA = crypto:hash(sha, Value), + <<MD5/binary, SHA/binary>>; + +server_key_exchange_hash(Hash, Value) -> + crypto:hash(Hash, Value). +%%-------------------------------------------------------------------- +-spec prf(tls_version(), binary(), binary(), [binary()], non_neg_integer()) -> + {ok, binary()} | {error, undefined}. +%% +%% Description: use the TLS PRF to generate key material +%%-------------------------------------------------------------------- +prf({3,0}, _, _, _, _) -> + {error, undefined}; +prf({3,1}, Secret, Label, Seed, WantedLength) -> + {ok, tls_v1:prf(?MD5SHA, Secret, Label, Seed, WantedLength)}; +prf({3,_N}, Secret, Label, Seed, WantedLength) -> + {ok, tls_v1:prf(?SHA256, Secret, Label, Seed, WantedLength)}. +%%-------------------------------------------------------------------- +-spec select_hashsign(#hash_sign_algos{}| undefined, undefined | binary()) -> + [{atom(), atom()}] | undefined. + +%% +%% Description: +%%-------------------------------------------------------------------- +select_hashsign(_, undefined) -> + {null, anon}; +select_hashsign(undefined, Cert) -> + #'OTPCertificate'{tbsCertificate = TBSCert} = public_key:pkix_decode_cert(Cert, otp), + #'OTPSubjectPublicKeyInfo'{algorithm = {_,Algo, _}} = TBSCert#'OTPTBSCertificate'.subjectPublicKeyInfo, + select_cert_hashsign(undefined, Algo, {undefined, undefined}); +select_hashsign(#hash_sign_algos{hash_sign_algos = HashSigns}, Cert) -> + #'OTPCertificate'{tbsCertificate = TBSCert} =public_key:pkix_decode_cert(Cert, otp), + #'OTPSubjectPublicKeyInfo'{algorithm = {_,Algo, _}} = TBSCert#'OTPTBSCertificate'.subjectPublicKeyInfo, + DefaultHashSign = {_, Sign} = select_cert_hashsign(undefined, Algo, {undefined, undefined}), + case lists:filter(fun({sha, dsa}) -> + true; + ({_, dsa}) -> + false; + ({Hash, S}) when S == Sign -> + ssl_cipher:is_acceptable_hash(Hash, proplists:get_value(hashs, crypto:supports())); + (_) -> + false + end, HashSigns) of + [] -> + DefaultHashSign; + [HashSign| _] -> + HashSign + end. +%%-------------------------------------------------------------------- +-spec select_cert_hashsign(#hash_sign_algos{}| undefined, oid(), tls_version() | {undefined, undefined}) -> + {atom(), atom()}. + +%% +%% Description: For TLS 1.2 selected cert_hash_sign will be recived +%% in the handshake message, for previous versions use appropriate defaults. +%% This function is also used by select_hashsign to extract +%% the alogrithm of the server cert key. +%%-------------------------------------------------------------------- +select_cert_hashsign(HashSign, _, {Major, Minor}) when HashSign =/= undefined andalso Major >= 3 andalso Minor >= 3 -> + HashSign; +select_cert_hashsign(undefined,?'id-ecPublicKey', _) -> + {sha, ecdsa}; +select_cert_hashsign(undefined, ?rsaEncryption, _) -> + {md5sha, rsa}; +select_cert_hashsign(undefined, ?'id-dsa', _) -> + {sha, dsa}. + +%%-------------------------------------------------------------------- +-spec master_secret(atom(), tls_version(), #session{} | binary(), #connection_states{}, + client | server) -> {binary(), #connection_states{}} | #alert{}. +%% +%% Description: Sets or calculates the master secret and calculate keys, +%% updating the pending connection states. The Mastersecret and the update +%% connection states are returned or an alert if the calculation fails. +%%------------------------------------------------------------------- +master_secret(RecordCB, Version, #session{master_secret = Mastersecret}, + ConnectionStates, Role) -> + ConnectionState = + ssl_record:pending_connection_state(ConnectionStates, read), + SecParams = ConnectionState#connection_state.security_parameters, + try master_secret(RecordCB, Version, Mastersecret, SecParams, + ConnectionStates, Role) + catch + exit:Reason -> + Report = io_lib:format("Key calculation failed due to ~p", + [Reason]), + error_logger:error_report(Report), + ?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE) + end; + +master_secret(RecordCB, Version, PremasterSecret, ConnectionStates, Role) -> + ConnectionState = + ssl_record:pending_connection_state(ConnectionStates, read), + SecParams = ConnectionState#connection_state.security_parameters, + #security_parameters{prf_algorithm = PrfAlgo, + client_random = ClientRandom, + server_random = ServerRandom} = SecParams, + try master_secret(RecordCB, Version, + calc_master_secret(Version,PrfAlgo,PremasterSecret, + ClientRandom, ServerRandom), + SecParams, ConnectionStates, Role) + catch + exit:Reason -> + Report = io_lib:format("Master secret calculation failed" + " due to ~p", [Reason]), + error_logger:error_report(Report), + ?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE) + end. + +%%-------------Encode/Decode -------------------------------- +encode_handshake(#next_protocol{selected_protocol = SelectedProtocol}, _Version) -> + PaddingLength = 32 - ((byte_size(SelectedProtocol) + 2) rem 32), + {?NEXT_PROTOCOL, <<?BYTE((byte_size(SelectedProtocol))), SelectedProtocol/binary, + ?BYTE(PaddingLength), 0:(PaddingLength * 8)>>}; + +encode_handshake(#server_hello{server_version = {Major, Minor}, + random = Random, + session_id = Session_ID, + cipher_suite = CipherSuite, + compression_method = Comp_method, + extensions = #hello_extensions{} = Extensions}, _Version) -> + SID_length = byte_size(Session_ID), + ExtensionsBin = encode_hello_extensions(Extensions), + {?SERVER_HELLO, <<?BYTE(Major), ?BYTE(Minor), Random:32/binary, + ?BYTE(SID_length), Session_ID/binary, + CipherSuite/binary, ?BYTE(Comp_method), ExtensionsBin/binary>>}; +encode_handshake(#certificate{asn1_certificates = ASN1CertList}, _Version) -> + ASN1Certs = certs_from_list(ASN1CertList), + ACLen = erlang:iolist_size(ASN1Certs), + {?CERTIFICATE, <<?UINT24(ACLen), ASN1Certs:ACLen/binary>>}; +encode_handshake(#server_key_exchange{exchange_keys = Keys}, _Version) -> + {?SERVER_KEY_EXCHANGE, Keys}; +encode_handshake(#server_key_params{params_bin = Keys, hashsign = HashSign, + signature = Signature}, Version) -> + EncSign = enc_sign(HashSign, Signature, Version), + {?SERVER_KEY_EXCHANGE, <<Keys/binary, EncSign/binary>>}; +encode_handshake(#certificate_request{certificate_types = CertTypes, + hashsign_algorithms = #hash_sign_algos{hash_sign_algos = HashSignAlgos}, + certificate_authorities = CertAuths}, + {Major, Minor}) + when Major == 3, Minor >= 3 -> + HashSigns= << <<(ssl_cipher:hash_algorithm(Hash)):8, (ssl_cipher:sign_algorithm(Sign)):8>> || + {Hash, Sign} <- HashSignAlgos >>, + CertTypesLen = byte_size(CertTypes), + HashSignsLen = byte_size(HashSigns), + CertAuthsLen = byte_size(CertAuths), + {?CERTIFICATE_REQUEST, + <<?BYTE(CertTypesLen), CertTypes/binary, + ?UINT16(HashSignsLen), HashSigns/binary, + ?UINT16(CertAuthsLen), CertAuths/binary>> + }; +encode_handshake(#certificate_request{certificate_types = CertTypes, + certificate_authorities = CertAuths}, + _Version) -> + CertTypesLen = byte_size(CertTypes), + CertAuthsLen = byte_size(CertAuths), + {?CERTIFICATE_REQUEST, + <<?BYTE(CertTypesLen), CertTypes/binary, + ?UINT16(CertAuthsLen), CertAuths/binary>> + }; +encode_handshake(#server_hello_done{}, _Version) -> + {?SERVER_HELLO_DONE, <<>>}; +encode_handshake(#client_key_exchange{exchange_keys = ExchangeKeys}, Version) -> + {?CLIENT_KEY_EXCHANGE, encode_client_key(ExchangeKeys, Version)}; +encode_handshake(#certificate_verify{signature = BinSig, hashsign_algorithm = HashSign}, Version) -> + EncSig = enc_sign(HashSign, BinSig, Version), + {?CERTIFICATE_VERIFY, EncSig}; +encode_handshake(#finished{verify_data = VerifyData}, _Version) -> + {?FINISHED, VerifyData}. + +encode_hello_extensions(#hello_extensions{} = Extensions) -> + encode_hello_extensions(hello_extensions_list(Extensions), <<>>). +encode_hello_extensions([], <<>>) -> + <<>>; +encode_hello_extensions([], Acc) -> + Size = byte_size(Acc), + <<?UINT16(Size), Acc/binary>>; + +encode_hello_extensions([#next_protocol_negotiation{extension_data = ExtensionData} | Rest], Acc) -> + Len = byte_size(ExtensionData), + encode_hello_extensions(Rest, <<?UINT16(?NEXTPROTONEG_EXT), ?UINT16(Len), + ExtensionData/binary, Acc/binary>>); +encode_hello_extensions([#renegotiation_info{renegotiated_connection = undefined} | Rest], Acc) -> + encode_hello_extensions(Rest, Acc); +encode_hello_extensions([#renegotiation_info{renegotiated_connection = ?byte(0) = Info} | Rest], Acc) -> + Len = byte_size(Info), + encode_hello_extensions(Rest, <<?UINT16(?RENEGOTIATION_EXT), ?UINT16(Len), Info/binary, Acc/binary>>); + +encode_hello_extensions([#renegotiation_info{renegotiated_connection = Info} | Rest], Acc) -> + InfoLen = byte_size(Info), + Len = InfoLen +1, + encode_hello_extensions(Rest, <<?UINT16(?RENEGOTIATION_EXT), ?UINT16(Len), ?BYTE(InfoLen), + Info/binary, Acc/binary>>); +encode_hello_extensions([#elliptic_curves{elliptic_curve_list = EllipticCurves} | Rest], Acc) -> + + EllipticCurveList = << <<(tls_v1:oid_to_enum(X)):16>> || X <- EllipticCurves>>, + ListLen = byte_size(EllipticCurveList), + Len = ListLen + 2, + encode_hello_extensions(Rest, <<?UINT16(?ELLIPTIC_CURVES_EXT), + ?UINT16(Len), ?UINT16(ListLen), EllipticCurveList/binary, Acc/binary>>); +encode_hello_extensions([#ec_point_formats{ec_point_format_list = ECPointFormats} | Rest], Acc) -> + ECPointFormatList = list_to_binary(ECPointFormats), + ListLen = byte_size(ECPointFormatList), + Len = ListLen + 1, + encode_hello_extensions(Rest, <<?UINT16(?EC_POINT_FORMATS_EXT), + ?UINT16(Len), ?BYTE(ListLen), ECPointFormatList/binary, Acc/binary>>); +encode_hello_extensions([#srp{username = UserName} | Rest], Acc) -> + SRPLen = byte_size(UserName), + Len = SRPLen + 2, + encode_hello_extensions(Rest, <<?UINT16(?SRP_EXT), ?UINT16(Len), ?BYTE(SRPLen), + UserName/binary, Acc/binary>>); +encode_hello_extensions([#hash_sign_algos{hash_sign_algos = HashSignAlgos} | Rest], Acc) -> + SignAlgoList = << <<(ssl_cipher:hash_algorithm(Hash)):8, (ssl_cipher:sign_algorithm(Sign)):8>> || + {Hash, Sign} <- HashSignAlgos >>, + ListLen = byte_size(SignAlgoList), + Len = ListLen + 2, + encode_hello_extensions(Rest, <<?UINT16(?SIGNATURE_ALGORITHMS_EXT), + ?UINT16(Len), ?UINT16(ListLen), SignAlgoList/binary, Acc/binary>>). + +enc_server_key_exchange(Version, Params, {HashAlgo, SignAlgo}, + ClientRandom, ServerRandom, PrivateKey) -> + EncParams = encode_server_key(Params), + case HashAlgo of + null -> + #server_key_params{params = Params, + params_bin = EncParams, + hashsign = {null, anon}, + signature = <<>>}; + _ -> + Hash = + server_key_exchange_hash(HashAlgo, <<ClientRandom/binary, + ServerRandom/binary, + EncParams/binary>>), + Signature = digitally_signed(Version, Hash, HashAlgo, PrivateKey), + #server_key_params{params = Params, + params_bin = EncParams, + hashsign = {HashAlgo, SignAlgo}, + signature = Signature} + end. + +%%-------------------------------------------------------------------- +-spec decode_client_key(binary(), key_algo(), tls_version()) -> + #encrypted_premaster_secret{} + | #client_diffie_hellman_public{} + | #client_ec_diffie_hellman_public{} + | #client_psk_identity{} + | #client_dhe_psk_identity{} + | #client_rsa_psk_identity{} + | #client_srp_public{}. +%% +%% Description: Decode client_key data and return appropriate type +%%-------------------------------------------------------------------- +decode_client_key(ClientKey, Type, Version) -> + dec_client_key(ClientKey, key_exchange_alg(Type), Version). + +%%-------------------------------------------------------------------- +-spec decode_server_key(binary(), key_algo(), tls_version()) -> + #server_key_params{}. +%% +%% Description: Decode server_key data and return appropriate type +%%-------------------------------------------------------------------- +decode_server_key(ServerKey, Type, Version) -> + dec_server_key(ServerKey, key_exchange_alg(Type), Version). + +encode_client_protocol_negotiation(undefined, _) -> + undefined; +encode_client_protocol_negotiation(_, false) -> + #next_protocol_negotiation{extension_data = <<>>}; +encode_client_protocol_negotiation(_, _) -> + undefined. + +encode_protocols_advertised_on_server(undefined) -> + undefined; + +encode_protocols_advertised_on_server(Protocols) -> + #next_protocol_negotiation{extension_data = lists:foldl(fun encode_protocol/2, <<>>, Protocols)}. + +decode_handshake(_, ?HELLO_REQUEST, <<>>) -> + #hello_request{}; +decode_handshake(_, ?NEXT_PROTOCOL, <<?BYTE(SelectedProtocolLength), + SelectedProtocol:SelectedProtocolLength/binary, + ?BYTE(PaddingLength), _Padding:PaddingLength/binary>>) -> + #next_protocol{selected_protocol = SelectedProtocol}; + +decode_handshake(_Version, ?SERVER_HELLO, <<?BYTE(Major), ?BYTE(Minor), Random:32/binary, + ?BYTE(SID_length), Session_ID:SID_length/binary, + Cipher_suite:2/binary, ?BYTE(Comp_method)>>) -> + #server_hello{ + server_version = {Major,Minor}, + random = Random, + session_id = Session_ID, + cipher_suite = Cipher_suite, + compression_method = Comp_method, + extensions = #hello_extensions{}}; + +decode_handshake(_Version, ?SERVER_HELLO, <<?BYTE(Major), ?BYTE(Minor), Random:32/binary, + ?BYTE(SID_length), Session_ID:SID_length/binary, + Cipher_suite:2/binary, ?BYTE(Comp_method), + ?UINT16(ExtLen), Extensions:ExtLen/binary>>) -> + + HelloExtensions = decode_hello_extensions(Extensions), + + #server_hello{ + server_version = {Major,Minor}, + random = Random, + session_id = Session_ID, + cipher_suite = Cipher_suite, + compression_method = Comp_method, + extensions = HelloExtensions}; + +decode_handshake(_Version, ?CERTIFICATE, <<?UINT24(ACLen), ASN1Certs:ACLen/binary>>) -> + #certificate{asn1_certificates = certs_to_list(ASN1Certs)}; +decode_handshake(_Version, ?SERVER_KEY_EXCHANGE, Keys) -> + #server_key_exchange{exchange_keys = Keys}; +decode_handshake({Major, Minor}, ?CERTIFICATE_REQUEST, + <<?BYTE(CertTypesLen), CertTypes:CertTypesLen/binary, + ?UINT16(HashSignsLen), HashSigns:HashSignsLen/binary, + ?UINT16(CertAuthsLen), CertAuths:CertAuthsLen/binary>>) + when Major >= 3, Minor >= 3 -> + HashSignAlgos = [{ssl_cipher:hash_algorithm(Hash), ssl_cipher:sign_algorithm(Sign)} || + <<?BYTE(Hash), ?BYTE(Sign)>> <= HashSigns], + #certificate_request{certificate_types = CertTypes, + hashsign_algorithms = #hash_sign_algos{hash_sign_algos = HashSignAlgos}, + certificate_authorities = CertAuths}; +decode_handshake(_Version, ?CERTIFICATE_REQUEST, + <<?BYTE(CertTypesLen), CertTypes:CertTypesLen/binary, + ?UINT16(CertAuthsLen), CertAuths:CertAuthsLen/binary>>) -> + #certificate_request{certificate_types = CertTypes, + certificate_authorities = CertAuths}; +decode_handshake(_Version, ?SERVER_HELLO_DONE, <<>>) -> + #server_hello_done{}; +decode_handshake({Major, Minor}, ?CERTIFICATE_VERIFY,<<HashSign:2/binary, ?UINT16(SignLen), + Signature:SignLen/binary>>) + when Major == 3, Minor >= 3 -> + #certificate_verify{hashsign_algorithm = dec_hashsign(HashSign), signature = Signature}; +decode_handshake(_Version, ?CERTIFICATE_VERIFY,<<?UINT16(SignLen), Signature:SignLen/binary>>)-> + #certificate_verify{signature = Signature}; +decode_handshake(_Version, ?CLIENT_KEY_EXCHANGE, PKEPMS) -> + #client_key_exchange{exchange_keys = PKEPMS}; +decode_handshake(_Version, ?FINISHED, VerifyData) -> + #finished{verify_data = VerifyData}; +decode_handshake(_, _, _) -> + throw(?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE)). + +%%-------------------------------------------------------------------- +-spec decode_hello_extensions({client, binary()} | binary()) -> #hello_extensions{}. +%% +%% Description: Decodes TLS hello extensions +%%-------------------------------------------------------------------- +decode_hello_extensions({client, <<>>}) -> + #hello_extensions{}; +decode_hello_extensions({client, <<?UINT16(ExtLen), Extensions:ExtLen/binary>>}) -> + decode_hello_extensions(Extensions); +decode_hello_extensions(Extensions) -> + dec_hello_extensions(Extensions, #hello_extensions{}). + +dec_server_key(<<?UINT16(PLen), P:PLen/binary, + ?UINT16(GLen), G:GLen/binary, + ?UINT16(YLen), Y:YLen/binary, _/binary>> = KeyStruct, + ?KEY_EXCHANGE_DIFFIE_HELLMAN, Version) -> + Params = #server_dh_params{dh_p = P, dh_g = G, dh_y = Y}, + {BinMsg, HashSign, Signature} = dec_server_key_params(PLen + GLen + YLen + 6, KeyStruct, Version), + #server_key_params{params = Params, + params_bin = BinMsg, + hashsign = HashSign, + signature = Signature}; +%% ECParameters with named_curve +%% TODO: explicit curve +dec_server_key(<<?BYTE(?NAMED_CURVE), ?UINT16(CurveID), + ?BYTE(PointLen), ECPoint:PointLen/binary, + _/binary>> = KeyStruct, + ?KEY_EXCHANGE_EC_DIFFIE_HELLMAN, Version) -> + Params = #server_ecdh_params{curve = {namedCurve, tls_v1:enum_to_oid(CurveID)}, + public = ECPoint}, + {BinMsg, HashSign, Signature} = dec_server_key_params(PointLen + 4, KeyStruct, Version), + #server_key_params{params = Params, + params_bin = BinMsg, + hashsign = HashSign, + signature = Signature}; +dec_server_key(<<?UINT16(Len), PskIdentityHint:Len/binary, _/binary>> = KeyStruct, + KeyExchange, Version) + when KeyExchange == ?KEY_EXCHANGE_PSK; KeyExchange == ?KEY_EXCHANGE_RSA_PSK -> + Params = #server_psk_params{ + hint = PskIdentityHint}, + {BinMsg, HashSign, Signature} = dec_server_key_params(Len + 2, KeyStruct, Version), + #server_key_params{params = Params, + params_bin = BinMsg, + hashsign = HashSign, + signature = Signature}; +dec_server_key(<<?UINT16(Len), IdentityHint:Len/binary, + ?UINT16(PLen), P:PLen/binary, + ?UINT16(GLen), G:GLen/binary, + ?UINT16(YLen), Y:YLen/binary, _/binary>> = KeyStruct, + ?KEY_EXCHANGE_DHE_PSK, Version) -> + DHParams = #server_dh_params{dh_p = P, dh_g = G, dh_y = Y}, + Params = #server_dhe_psk_params{ + hint = IdentityHint, + dh_params = DHParams}, + {BinMsg, HashSign, Signature} = dec_server_key_params(Len + PLen + GLen + YLen + 8, KeyStruct, Version), + #server_key_params{params = Params, + params_bin = BinMsg, + hashsign = HashSign, + signature = Signature}; +dec_server_key(<<?UINT16(NLen), N:NLen/binary, + ?UINT16(GLen), G:GLen/binary, + ?BYTE(SLen), S:SLen/binary, + ?UINT16(BLen), B:BLen/binary, _/binary>> = KeyStruct, + ?KEY_EXCHANGE_SRP, Version) -> + Params = #server_srp_params{srp_n = N, srp_g = G, srp_s = S, srp_b = B}, + {BinMsg, HashSign, Signature} = dec_server_key_params(NLen + GLen + SLen + BLen + 7, KeyStruct, Version), + #server_key_params{params = Params, + params_bin = BinMsg, + hashsign = HashSign, + signature = Signature}; +dec_server_key(_, _, _) -> + throw(?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE)). + +%%-------------------------------------------------------------------- +-spec decode_suites('2_bytes'|'3_bytes', binary()) -> list(). +%% +%% Description: +%%-------------------------------------------------------------------- +decode_suites('2_bytes', Dec) -> + from_2bytes(Dec); +decode_suites('3_bytes', Dec) -> + from_3bytes(Dec). + +%%-------------Cipeher suite handling -------------------------------- + +available_suites(UserSuites, Version) -> + case UserSuites of + [] -> + ssl_cipher:suites(Version); + _ -> + UserSuites + end. + +available_suites(ServerCert, UserSuites, Version, Curve) -> + ssl_cipher:filter(ServerCert, available_suites(UserSuites, Version)) + -- unavailable_ecc_suites(Curve). + +unavailable_ecc_suites(no_curve) -> + ssl_cipher:ec_keyed_suites(); +unavailable_ecc_suites(_) -> + []. + +cipher_suites(Suites, false) -> + [?TLS_EMPTY_RENEGOTIATION_INFO_SCSV | Suites]; +cipher_suites(Suites, true) -> + Suites. + +select_session(SuggestedSessionId, CipherSuites, Compressions, Port, #session{ecc = ECCCurve} = + Session, Version, + #ssl_options{ciphers = UserSuites} = SslOpts, Cache, CacheCb, Cert) -> + {SessionId, Resumed} = ssl_session:server_id(Port, SuggestedSessionId, + SslOpts, Cert, + Cache, CacheCb), + case Resumed of + undefined -> + Suites = available_suites(Cert, UserSuites, Version, ECCCurve), + CipherSuite = select_cipher_suite(CipherSuites, Suites), + Compression = select_compression(Compressions), + {new, Session#session{session_id = SessionId, + cipher_suite = CipherSuite, + compression_method = Compression}}; + _ -> + {resumed, Resumed} + end. + +supported_ecc(Version) -> + case tls_v1:ecc_curves(Version) of + [] -> + undefined; + Curves -> + #elliptic_curves{elliptic_curve_list = Curves} + end. +%%-------------certificate handling -------------------------------- + +certificate_types({KeyExchange, _, _, _}) + when KeyExchange == rsa; + KeyExchange == dhe_dss; + KeyExchange == dhe_rsa; + KeyExchange == ecdhe_rsa -> + <<?BYTE(?RSA_SIGN), ?BYTE(?DSS_SIGN)>>; + +certificate_types({KeyExchange, _, _, _}) + when KeyExchange == dh_ecdsa; + KeyExchange == dhe_ecdsa -> + <<?BYTE(?ECDSA_SIGN)>>; + +certificate_types(_) -> + <<?BYTE(?RSA_SIGN)>>. + +certificate_authorities(CertDbHandle, CertDbRef) -> + Authorities = certificate_authorities_from_db(CertDbHandle, CertDbRef), + Enc = fun(#'OTPCertificate'{tbsCertificate=TBSCert}) -> + OTPSubj = TBSCert#'OTPTBSCertificate'.subject, + DNEncodedBin = public_key:pkix_encode('Name', OTPSubj, otp), + DNEncodedLen = byte_size(DNEncodedBin), + <<?UINT16(DNEncodedLen), DNEncodedBin/binary>> + end, + list_to_binary([Enc(Cert) || {_, Cert} <- Authorities]). + +certificate_authorities_from_db(CertDbHandle, CertDbRef) -> + ConnectionCerts = fun({{Ref, _, _}, Cert}, Acc) when Ref == CertDbRef -> + [Cert | Acc]; + (_, Acc) -> + Acc + end, + ssl_pkix_db:foldl(ConnectionCerts, [], CertDbHandle). + +%%-------------Extension handling -------------------------------- + +handle_client_hello_extensions(RecordCB, Random, + #hello_extensions{renegotiation_info = Info, + srp = SRP, + ec_point_formats = ECCFormat, + next_protocol_negotiation = NextProtocolNegotiation}, Version, + #ssl_options{secure_renegotiate = SecureRenegotation} = Opts, + #session{cipher_suite = CipherSuite, compression_method = Compression} = Session0, + ConnectionStates0, Renegotiation) -> + Session = handle_srp_extension(SRP, Session0), + ConnectionStates = handle_renegotiation_extension(server, RecordCB, Version, Info, + Random, CipherSuite, Compression, + ConnectionStates0, Renegotiation, SecureRenegotation), + ProtocolsToAdvertise = handle_next_protocol_extension(NextProtocolNegotiation, Renegotiation, Opts), + + ServerHelloExtensions = #hello_extensions{ + renegotiation_info = renegotiation_info(RecordCB, server, + ConnectionStates, Renegotiation), + ec_point_formats = server_ecc_extension(Version, ECCFormat), + next_protocol_negotiation = + encode_protocols_advertised_on_server(ProtocolsToAdvertise) + }, + {Session, ConnectionStates, ServerHelloExtensions}. + +handle_server_hello_extensions(RecordCB, Random, CipherSuite, Compression, + #hello_extensions{renegotiation_info = Info, + next_protocol_negotiation = NextProtocolNegotiation}, Version, + #ssl_options{secure_renegotiate = SecureRenegotation, + next_protocol_selector = NextProtoSelector}, + ConnectionStates0, Renegotiation) -> + ConnectionStates = handle_renegotiation_extension(client, RecordCB, Version, Info, Random, CipherSuite, + Compression, ConnectionStates0, + Renegotiation, SecureRenegotation), + case handle_next_protocol(NextProtocolNegotiation, NextProtoSelector, Renegotiation) of + #alert{} = Alert -> + Alert; + Protocol -> + {ConnectionStates, Protocol} + end. + +select_version(RecordCB, ClientVersion, Versions) -> + ServerVersion = RecordCB:highest_protocol_version(Versions), + RecordCB:lowest_protocol_version(ClientVersion, ServerVersion). + +renegotiation_info(_, client, _, false) -> + #renegotiation_info{renegotiated_connection = undefined}; +renegotiation_info(_RecordCB, server, ConnectionStates, false) -> + CS = ssl_record:current_connection_state(ConnectionStates, read), + case CS#connection_state.secure_renegotiation of + true -> + #renegotiation_info{renegotiated_connection = ?byte(0)}; + false -> + #renegotiation_info{renegotiated_connection = undefined} + end; +renegotiation_info(_RecordCB, client, ConnectionStates, true) -> + CS = ssl_record:current_connection_state(ConnectionStates, read), + case CS#connection_state.secure_renegotiation of + true -> + Data = CS#connection_state.client_verify_data, + #renegotiation_info{renegotiated_connection = Data}; + false -> + #renegotiation_info{renegotiated_connection = undefined} + end; + +renegotiation_info(_RecordCB, server, ConnectionStates, true) -> + CS = ssl_record:current_connection_state(ConnectionStates, read), + case CS#connection_state.secure_renegotiation of + true -> + CData = CS#connection_state.client_verify_data, + SData =CS#connection_state.server_verify_data, + #renegotiation_info{renegotiated_connection = <<CData/binary, SData/binary>>}; + false -> + #renegotiation_info{renegotiated_connection = undefined} + end. + +handle_renegotiation_info(_RecordCB, _, #renegotiation_info{renegotiated_connection = ?byte(0)}, + ConnectionStates, false, _, _) -> + {ok, ssl_record:set_renegotiation_flag(true, ConnectionStates)}; + +handle_renegotiation_info(_RecordCB, server, undefined, ConnectionStates, _, _, CipherSuites) -> + case is_member(?TLS_EMPTY_RENEGOTIATION_INFO_SCSV, CipherSuites) of + true -> + {ok, ssl_record:set_renegotiation_flag(true, ConnectionStates)}; + false -> + {ok, ssl_record:set_renegotiation_flag(false, ConnectionStates)} + end; + +handle_renegotiation_info(_RecordCB, _, undefined, ConnectionStates, false, _, _) -> + {ok, ssl_record:set_renegotiation_flag(false, ConnectionStates)}; + +handle_renegotiation_info(_RecordCB, client, #renegotiation_info{renegotiated_connection = ClientServerVerify}, + ConnectionStates, true, _, _) -> + CS = ssl_record:current_connection_state(ConnectionStates, read), + CData = CS#connection_state.client_verify_data, + SData = CS#connection_state.server_verify_data, + case <<CData/binary, SData/binary>> == ClientServerVerify of + true -> + {ok, ConnectionStates}; + false -> + ?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE) + end; +handle_renegotiation_info(_RecordCB, server, #renegotiation_info{renegotiated_connection = ClientVerify}, + ConnectionStates, true, _, CipherSuites) -> + + case is_member(?TLS_EMPTY_RENEGOTIATION_INFO_SCSV, CipherSuites) of + true -> + ?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE); + false -> + CS = ssl_record:current_connection_state(ConnectionStates, read), + Data = CS#connection_state.client_verify_data, + case Data == ClientVerify of + true -> + {ok, ConnectionStates}; + false -> + ?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE) + end + end; + +handle_renegotiation_info(RecordCB, client, undefined, ConnectionStates, true, SecureRenegotation, _) -> + handle_renegotiation_info(RecordCB, ConnectionStates, SecureRenegotation); + +handle_renegotiation_info(RecordCB, server, undefined, ConnectionStates, true, SecureRenegotation, CipherSuites) -> + case is_member(?TLS_EMPTY_RENEGOTIATION_INFO_SCSV, CipherSuites) of + true -> + ?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE); + false -> + handle_renegotiation_info(RecordCB, ConnectionStates, SecureRenegotation) + end. + +handle_renegotiation_info(_RecordCB, ConnectionStates, SecureRenegotation) -> + CS = ssl_record:current_connection_state(ConnectionStates, read), + case {SecureRenegotation, CS#connection_state.secure_renegotiation} of + {_, true} -> + ?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE); + {true, false} -> + ?ALERT_REC(?FATAL, ?NO_RENEGOTIATION); + {false, false} -> + {ok, ConnectionStates} + end. + +hello_extensions_list(#hello_extensions{renegotiation_info = RenegotiationInfo, + srp = SRP, + hash_signs = HashSigns, + ec_point_formats = EcPointFormats, + elliptic_curves = EllipticCurves, + next_protocol_negotiation = NextProtocolNegotiation}) -> + [Ext || Ext <- [RenegotiationInfo, SRP, HashSigns, + EcPointFormats,EllipticCurves, NextProtocolNegotiation], Ext =/= undefined]. + +srp_user(#ssl_options{srp_identity = {UserName, _}}) -> + #srp{username = UserName}; +srp_user(_) -> + undefined. + +client_ecc_extensions(Module, Version) -> + CryptoSupport = proplists:get_value(public_keys, crypto:supports()), + case proplists:get_bool(ecdh, CryptoSupport) of + true -> + EcPointFormats = #ec_point_formats{ec_point_format_list = [?ECPOINT_UNCOMPRESSED]}, + EllipticCurves = #elliptic_curves{elliptic_curve_list = Module:ecc_curves(Version)}, + {EcPointFormats, EllipticCurves}; + _ -> + {undefined, undefined} + end. + +server_ecc_extension(_Version, EcPointFormats) -> + CryptoSupport = proplists:get_value(public_keys, crypto:supports()), + case proplists:get_bool(ecdh, CryptoSupport) of + true -> + handle_ecc_point_fmt_extension(EcPointFormats); + false -> + undefined + end. + +handle_ecc_point_fmt_extension(undefined) -> + undefined; +handle_ecc_point_fmt_extension(_) -> + #ec_point_formats{ec_point_format_list = [?ECPOINT_UNCOMPRESSED]}. + +advertises_ec_ciphers([]) -> + false; +advertises_ec_ciphers([{ecdh_ecdsa, _,_,_} | _]) -> + true; +advertises_ec_ciphers([{ecdhe_ecdsa, _,_,_} | _]) -> + true; +advertises_ec_ciphers([{ecdh_rsa, _,_,_} | _]) -> + true; +advertises_ec_ciphers([{ecdhe_rsa, _,_,_} | _]) -> + true; +advertises_ec_ciphers([{ecdh_anon, _,_,_} | _]) -> + true; +advertises_ec_ciphers([_| Rest]) -> + advertises_ec_ciphers(Rest). +select_curve(#elliptic_curves{elliptic_curve_list = ClientCurves}, + #elliptic_curves{elliptic_curve_list = ServerCurves}) -> + select_curve(ClientCurves, ServerCurves); +select_curve(undefined, _) -> + %% Client did not send ECC extension use default curve if + %% ECC cipher is negotiated + {namedCurve, ?secp256k1}; +select_curve(_, []) -> + no_curve; +select_curve(Curves, [Curve| Rest]) -> + case lists:member(Curve, Curves) of + true -> + {namedCurve, Curve}; + false -> + select_curve(Curves, Rest) + end. + +%%-------------------------------------------------------------------- +%%% Internal functions +%%-------------------------------------------------------------------- +apply_user_fun(Fun, OtpCert, ExtensionOrError, UserState0, SslState) -> + case Fun(OtpCert, ExtensionOrError, UserState0) of + {valid, UserState} -> + {valid, {SslState, UserState}}; + {fail, _} = Fail -> + Fail; + {unknown, UserState} -> + {unknown, {SslState, UserState}} + end. +path_validation_alert({bad_cert, cert_expired}) -> + ?ALERT_REC(?FATAL, ?CERTIFICATE_EXPIRED); +path_validation_alert({bad_cert, invalid_issuer}) -> + ?ALERT_REC(?FATAL, ?BAD_CERTIFICATE); +path_validation_alert({bad_cert, invalid_signature}) -> + ?ALERT_REC(?FATAL, ?BAD_CERTIFICATE); +path_validation_alert({bad_cert, name_not_permitted}) -> + ?ALERT_REC(?FATAL, ?BAD_CERTIFICATE); +path_validation_alert({bad_cert, unknown_critical_extension}) -> + ?ALERT_REC(?FATAL, ?UNSUPPORTED_CERTIFICATE); +path_validation_alert({bad_cert, cert_revoked}) -> + ?ALERT_REC(?FATAL, ?CERTIFICATE_REVOKED); +path_validation_alert({bad_cert, selfsigned_peer}) -> + ?ALERT_REC(?FATAL, ?BAD_CERTIFICATE); +path_validation_alert({bad_cert, unknown_ca}) -> + ?ALERT_REC(?FATAL, ?UNKNOWN_CA); +path_validation_alert(_) -> + ?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE). + +encrypted_premaster_secret(Secret, RSAPublicKey) -> + try + PreMasterSecret = public_key:encrypt_public(Secret, RSAPublicKey, + [{rsa_pad, + rsa_pkcs1_padding}]), + #encrypted_premaster_secret{premaster_secret = PreMasterSecret} + catch + _:_-> + throw(?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE)) + end. + +digitally_signed({3, Minor}, Hash, HashAlgo, Key) when Minor >= 3 -> + public_key:sign({digest, Hash}, HashAlgo, Key); +digitally_signed(_Version, Hash, HashAlgo, #'DSAPrivateKey'{} = Key) -> + public_key:sign({digest, Hash}, HashAlgo, Key); +digitally_signed(_Version, Hash, _HashAlgo, #'RSAPrivateKey'{} = Key) -> + public_key:encrypt_private(Hash, Key, + [{rsa_pad, rsa_pkcs1_padding}]); +digitally_signed(_Version, Hash, HashAlgo, Key) -> + public_key:sign({digest, Hash}, HashAlgo, Key). + +calc_certificate_verify({3, 0}, HashAlgo, MasterSecret, Handshake) -> + ssl_v3:certificate_verify(HashAlgo, MasterSecret, lists:reverse(Handshake)); +calc_certificate_verify({3, N}, HashAlgo, _MasterSecret, Handshake) -> + tls_v1:certificate_verify(HashAlgo, N, lists:reverse(Handshake)). + +calc_finished({3, 0}, Role, _PrfAlgo, MasterSecret, Handshake) -> + ssl_v3:finished(Role, MasterSecret, lists:reverse(Handshake)); +calc_finished({3, N}, Role, PrfAlgo, MasterSecret, Handshake) -> + tls_v1:finished(Role, N, PrfAlgo, MasterSecret, lists:reverse(Handshake)). + +master_secret(_RecordCB, Version, MasterSecret, + #security_parameters{ + client_random = ClientRandom, + server_random = ServerRandom, + hash_size = HashSize, + prf_algorithm = PrfAlgo, + key_material_length = KML, + expanded_key_material_length = EKML, + iv_size = IVS}, + ConnectionStates, Role) -> + {ClientWriteMacSecret, ServerWriteMacSecret, ClientWriteKey, + ServerWriteKey, ClientIV, ServerIV} = + setup_keys(Version, PrfAlgo, MasterSecret, ServerRandom, + ClientRandom, HashSize, KML, EKML, IVS), + + ConnStates1 = ssl_record:set_master_secret(MasterSecret, ConnectionStates), + ConnStates2 = + ssl_record:set_mac_secret(ClientWriteMacSecret, ServerWriteMacSecret, + Role, ConnStates1), + + ClientCipherState = #cipher_state{iv = ClientIV, key = ClientWriteKey}, + ServerCipherState = #cipher_state{iv = ServerIV, key = ServerWriteKey}, + {MasterSecret, + ssl_record:set_pending_cipher_state(ConnStates2, ClientCipherState, + ServerCipherState, Role)}. + +setup_keys({3,0}, _PrfAlgo, MasterSecret, + ServerRandom, ClientRandom, HashSize, KML, EKML, IVS) -> + ssl_v3:setup_keys(MasterSecret, ServerRandom, + ClientRandom, HashSize, KML, EKML, IVS); + +setup_keys({3,N}, PrfAlgo, MasterSecret, + ServerRandom, ClientRandom, HashSize, KML, _EKML, IVS) -> + tls_v1:setup_keys(N, PrfAlgo, MasterSecret, ServerRandom, ClientRandom, HashSize, + KML, IVS). + +calc_master_secret({3,0}, _PrfAlgo, PremasterSecret, ClientRandom, ServerRandom) -> + ssl_v3:master_secret(PremasterSecret, ClientRandom, ServerRandom); + +calc_master_secret({3,_}, PrfAlgo, PremasterSecret, ClientRandom, ServerRandom) -> + tls_v1:master_secret(PrfAlgo, PremasterSecret, ClientRandom, ServerRandom). + +handle_renegotiation_extension(Role, RecordCB, Version, Info, Random, CipherSuite, Compression, + ConnectionStates0, Renegotiation, SecureRenegotation) -> + case handle_renegotiation_info(RecordCB, Role, Info, ConnectionStates0, + Renegotiation, SecureRenegotation, + [CipherSuite]) of + {ok, ConnectionStates} -> + hello_pending_connection_states(RecordCB, Role, + Version, + CipherSuite, + Random, + Compression, + ConnectionStates); + #alert{} = Alert -> + throw(Alert) + end. + +%% Update pending connection states with parameters exchanged via +%% hello messages +%% NOTE : Role is the role of the receiver of the hello message +%% currently being processed. +hello_pending_connection_states(_RecordCB, Role, Version, CipherSuite, Random, Compression, + ConnectionStates) -> + ReadState = + ssl_record:pending_connection_state(ConnectionStates, read), + WriteState = + ssl_record:pending_connection_state(ConnectionStates, write), + + NewReadSecParams = + hello_security_parameters(Role, Version, ReadState, CipherSuite, + Random, Compression), + + NewWriteSecParams = + hello_security_parameters(Role, Version, WriteState, CipherSuite, + Random, Compression), + + ssl_record:set_security_params(NewReadSecParams, + NewWriteSecParams, + ConnectionStates). + +hello_security_parameters(client, Version, ConnectionState, CipherSuite, Random, + Compression) -> + SecParams = ConnectionState#connection_state.security_parameters, + NewSecParams = ssl_cipher:security_parameters(Version, CipherSuite, SecParams), + NewSecParams#security_parameters{ + server_random = Random, + compression_algorithm = Compression + }; + +hello_security_parameters(server, Version, ConnectionState, CipherSuite, Random, + Compression) -> + SecParams = ConnectionState#connection_state.security_parameters, + NewSecParams = ssl_cipher:security_parameters(Version, CipherSuite, SecParams), + NewSecParams#security_parameters{ + client_random = Random, + compression_algorithm = Compression + }. + +%%-------------Encode/Decode -------------------------------- + +encode_server_key(#server_dh_params{dh_p = P, dh_g = G, dh_y = Y}) -> + PLen = byte_size(P), + GLen = byte_size(G), + YLen = byte_size(Y), + <<?UINT16(PLen), P/binary, ?UINT16(GLen), G/binary, ?UINT16(YLen), Y/binary>>; +encode_server_key(#server_ecdh_params{curve = {namedCurve, ECCurve}, public = ECPubKey}) -> + %%TODO: support arbitrary keys + KLen = size(ECPubKey), + <<?BYTE(?NAMED_CURVE), ?UINT16((tls_v1:oid_to_enum(ECCurve))), + ?BYTE(KLen), ECPubKey/binary>>; +encode_server_key(#server_psk_params{hint = PskIdentityHint}) -> + Len = byte_size(PskIdentityHint), + <<?UINT16(Len), PskIdentityHint/binary>>; +encode_server_key(Params = #server_dhe_psk_params{hint = undefined}) -> + encode_server_key(Params#server_dhe_psk_params{hint = <<>>}); +encode_server_key(#server_dhe_psk_params{ + hint = PskIdentityHint, + dh_params = #server_dh_params{dh_p = P, dh_g = G, dh_y = Y}}) -> + Len = byte_size(PskIdentityHint), + PLen = byte_size(P), + GLen = byte_size(G), + YLen = byte_size(Y), + <<?UINT16(Len), PskIdentityHint/binary, + ?UINT16(PLen), P/binary, ?UINT16(GLen), G/binary, ?UINT16(YLen), Y/binary>>; +encode_server_key(#server_srp_params{srp_n = N, srp_g = G, srp_s = S, srp_b = B}) -> + NLen = byte_size(N), + GLen = byte_size(G), + SLen = byte_size(S), + BLen = byte_size(B), + <<?UINT16(NLen), N/binary, ?UINT16(GLen), G/binary, + ?BYTE(SLen), S/binary, ?UINT16(BLen), B/binary>>. + +encode_client_key(#encrypted_premaster_secret{premaster_secret = PKEPMS},{3, 0}) -> + PKEPMS; +encode_client_key(#encrypted_premaster_secret{premaster_secret = PKEPMS}, _) -> + PKEPMSLen = byte_size(PKEPMS), + <<?UINT16(PKEPMSLen), PKEPMS/binary>>; +encode_client_key(#client_diffie_hellman_public{dh_public = DHPublic}, _) -> + Len = byte_size(DHPublic), + <<?UINT16(Len), DHPublic/binary>>; +encode_client_key(#client_ec_diffie_hellman_public{dh_public = DHPublic}, _) -> + Len = byte_size(DHPublic), + <<?BYTE(Len), DHPublic/binary>>; +encode_client_key(#client_psk_identity{identity = undefined}, _) -> + Id = <<"psk_identity">>, + Len = byte_size(Id), + <<?UINT16(Len), Id/binary>>; +encode_client_key(#client_psk_identity{identity = Id}, _) -> + Len = byte_size(Id), + <<?UINT16(Len), Id/binary>>; +encode_client_key(Identity = #client_dhe_psk_identity{identity = undefined}, Version) -> + encode_client_key(Identity#client_dhe_psk_identity{identity = <<"psk_identity">>}, Version); +encode_client_key(#client_dhe_psk_identity{identity = Id, dh_public = DHPublic}, _) -> + Len = byte_size(Id), + DHLen = byte_size(DHPublic), + <<?UINT16(Len), Id/binary, ?UINT16(DHLen), DHPublic/binary>>; +encode_client_key(Identity = #client_rsa_psk_identity{identity = undefined}, Version) -> + encode_client_key(Identity#client_rsa_psk_identity{identity = <<"psk_identity">>}, Version); +encode_client_key(#client_rsa_psk_identity{identity = Id, exchange_keys = ExchangeKeys}, Version) -> + EncPMS = encode_client_key(ExchangeKeys, Version), + Len = byte_size(Id), + <<?UINT16(Len), Id/binary, EncPMS/binary>>; +encode_client_key(#client_srp_public{srp_a = A}, _) -> + Len = byte_size(A), + <<?UINT16(Len), A/binary>>. + +enc_sign({_, anon}, _Sign, _Version) -> + <<>>; +enc_sign({HashAlg, SignAlg}, Signature, _Version = {Major, Minor}) + when Major == 3, Minor >= 3-> + SignLen = byte_size(Signature), + HashSign = enc_hashsign(HashAlg, SignAlg), + <<HashSign/binary, ?UINT16(SignLen), Signature/binary>>; +enc_sign(_HashSign, Sign, _Version) -> + SignLen = byte_size(Sign), + <<?UINT16(SignLen), Sign/binary>>. + +enc_hashsign(HashAlgo, SignAlgo) -> + Hash = ssl_cipher:hash_algorithm(HashAlgo), + Sign = ssl_cipher:sign_algorithm(SignAlgo), + <<?BYTE(Hash), ?BYTE(Sign)>>. + +encode_protocol(Protocol, Acc) -> + Len = byte_size(Protocol), + <<Acc/binary, ?BYTE(Len), Protocol/binary>>. + +dec_client_key(PKEPMS, ?KEY_EXCHANGE_RSA, {3, 0}) -> + #encrypted_premaster_secret{premaster_secret = PKEPMS}; +dec_client_key(<<?UINT16(_), PKEPMS/binary>>, ?KEY_EXCHANGE_RSA, _) -> + #encrypted_premaster_secret{premaster_secret = PKEPMS}; +dec_client_key(<<>>, ?KEY_EXCHANGE_DIFFIE_HELLMAN, _) -> + throw(?ALERT_REC(?FATAL, ?UNSUPPORTED_CERTIFICATE)); +dec_client_key(<<?UINT16(DH_YLen), DH_Y:DH_YLen/binary>>, + ?KEY_EXCHANGE_DIFFIE_HELLMAN, _) -> + #client_diffie_hellman_public{dh_public = DH_Y}; +dec_client_key(<<>>, ?KEY_EXCHANGE_EC_DIFFIE_HELLMAN, _) -> + throw(?ALERT_REC(?FATAL, ?UNSUPPORTED_CERTIFICATE)); +dec_client_key(<<?BYTE(DH_YLen), DH_Y:DH_YLen/binary>>, + ?KEY_EXCHANGE_EC_DIFFIE_HELLMAN, _) -> + #client_ec_diffie_hellman_public{dh_public = DH_Y}; +dec_client_key(<<?UINT16(Len), Id:Len/binary>>, + ?KEY_EXCHANGE_PSK, _) -> + #client_psk_identity{identity = Id}; +dec_client_key(<<?UINT16(Len), Id:Len/binary, + ?UINT16(DH_YLen), DH_Y:DH_YLen/binary>>, + ?KEY_EXCHANGE_DHE_PSK, _) -> + #client_dhe_psk_identity{identity = Id, dh_public = DH_Y}; +dec_client_key(<<?UINT16(Len), Id:Len/binary, PKEPMS/binary>>, + ?KEY_EXCHANGE_RSA_PSK, {3, 0}) -> + #client_rsa_psk_identity{identity = Id, + exchange_keys = #encrypted_premaster_secret{premaster_secret = PKEPMS}}; +dec_client_key(<<?UINT16(Len), Id:Len/binary, ?UINT16(_), PKEPMS/binary>>, + ?KEY_EXCHANGE_RSA_PSK, _) -> + #client_rsa_psk_identity{identity = Id, + exchange_keys = #encrypted_premaster_secret{premaster_secret = PKEPMS}}; +dec_client_key(<<?UINT16(ALen), A:ALen/binary>>, + ?KEY_EXCHANGE_SRP, _) -> + #client_srp_public{srp_a = A}. + +dec_server_key_params(Len, Keys, Version) -> + <<Params:Len/bytes, Signature/binary>> = Keys, + dec_server_key_signature(Params, Signature, Version). + +dec_server_key_signature(Params, <<?BYTE(HashAlgo), ?BYTE(SignAlgo), + ?UINT16(0)>>, {Major, Minor}) + when Major == 3, Minor >= 3 -> + HashSign = {ssl_cipher:hash_algorithm(HashAlgo), ssl_cipher:sign_algorithm(SignAlgo)}, + {Params, HashSign, <<>>}; +dec_server_key_signature(Params, <<?BYTE(HashAlgo), ?BYTE(SignAlgo), + ?UINT16(Len), Signature:Len/binary>>, {Major, Minor}) + when Major == 3, Minor >= 3 -> + HashSign = {ssl_cipher:hash_algorithm(HashAlgo), ssl_cipher:sign_algorithm(SignAlgo)}, + {Params, HashSign, Signature}; +dec_server_key_signature(Params, <<>>, _) -> + {Params, {null, anon}, <<>>}; +dec_server_key_signature(Params, <<?UINT16(0)>>, _) -> + {Params, {null, anon}, <<>>}; +dec_server_key_signature(Params, <<?UINT16(Len), Signature:Len/binary>>, _) -> + {Params, undefined, Signature}; +dec_server_key_signature(_, _, _) -> + throw(?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE)). + +dec_hello_extensions(<<>>, Acc) -> + Acc; +dec_hello_extensions(<<?UINT16(?NEXTPROTONEG_EXT), ?UINT16(Len), ExtensionData:Len/binary, Rest/binary>>, Acc) -> + NextP = #next_protocol_negotiation{extension_data = ExtensionData}, + dec_hello_extensions(Rest, Acc#hello_extensions{next_protocol_negotiation = NextP}); +dec_hello_extensions(<<?UINT16(?RENEGOTIATION_EXT), ?UINT16(Len), Info:Len/binary, Rest/binary>>, Acc) -> + RenegotiateInfo = case Len of + 1 -> % Initial handshake + Info; % should be <<0>> will be matched in handle_renegotiation_info + _ -> + VerifyLen = Len - 1, + <<?BYTE(VerifyLen), VerifyInfo/binary>> = Info, + VerifyInfo + end, + dec_hello_extensions(Rest, Acc#hello_extensions{renegotiation_info = + #renegotiation_info{renegotiated_connection = + RenegotiateInfo}}); + +dec_hello_extensions(<<?UINT16(?SRP_EXT), ?UINT16(Len), ?BYTE(SRPLen), SRP:SRPLen/binary, Rest/binary>>, Acc) + when Len == SRPLen + 2 -> + dec_hello_extensions(Rest, Acc#hello_extensions{srp = #srp{username = SRP}}); + +dec_hello_extensions(<<?UINT16(?SIGNATURE_ALGORITHMS_EXT), ?UINT16(Len), + ExtData:Len/binary, Rest/binary>>, Acc) -> + SignAlgoListLen = Len - 2, + <<?UINT16(SignAlgoListLen), SignAlgoList/binary>> = ExtData, + HashSignAlgos = [{ssl_cipher:hash_algorithm(Hash), ssl_cipher:sign_algorithm(Sign)} || + <<?BYTE(Hash), ?BYTE(Sign)>> <= SignAlgoList], + dec_hello_extensions(Rest, Acc#hello_extensions{hash_signs = + #hash_sign_algos{hash_sign_algos = HashSignAlgos}}); + +dec_hello_extensions(<<?UINT16(?ELLIPTIC_CURVES_EXT), ?UINT16(Len), + ExtData:Len/binary, Rest/binary>>, Acc) -> + <<?UINT16(_), EllipticCurveList/binary>> = ExtData, + EllipticCurves = [tls_v1:enum_to_oid(X) || <<X:16>> <= EllipticCurveList], + dec_hello_extensions(Rest, Acc#hello_extensions{elliptic_curves = + #elliptic_curves{elliptic_curve_list = + EllipticCurves}}); +dec_hello_extensions(<<?UINT16(?EC_POINT_FORMATS_EXT), ?UINT16(Len), + ExtData:Len/binary, Rest/binary>>, Acc) -> + <<?BYTE(_), ECPointFormatList/binary>> = ExtData, + ECPointFormats = binary_to_list(ECPointFormatList), + dec_hello_extensions(Rest, Acc#hello_extensions{ec_point_formats = + #ec_point_formats{ec_point_format_list = + ECPointFormats}}); +%% Ignore data following the ClientHello (i.e., +%% extensions) if not understood. + +dec_hello_extensions(<<?UINT16(_), ?UINT16(Len), _Unknown:Len/binary, Rest/binary>>, Acc) -> + dec_hello_extensions(Rest, Acc); +%% This theoretically should not happen if the protocol is followed, but if it does it is ignored. +dec_hello_extensions(_, Acc) -> + Acc. + +dec_hashsign(<<?BYTE(HashAlgo), ?BYTE(SignAlgo)>>) -> + {ssl_cipher:hash_algorithm(HashAlgo), ssl_cipher:sign_algorithm(SignAlgo)}. + +decode_next_protocols({next_protocol_negotiation, Protocols}) -> + decode_next_protocols(Protocols, []). +decode_next_protocols(<<>>, Acc) -> + lists:reverse(Acc); +decode_next_protocols(<<?BYTE(Len), Protocol:Len/binary, Rest/binary>>, Acc) -> + case Len of + 0 -> + {error, invalid_next_protocols}; + _ -> + decode_next_protocols(Rest, [Protocol|Acc]) + end; +decode_next_protocols(_Bytes, _Acc) -> + {error, invalid_next_protocols}. + +%% encode/decode stream of certificate data to/from list of certificate data +certs_to_list(ASN1Certs) -> + certs_to_list(ASN1Certs, []). + +certs_to_list(<<?UINT24(CertLen), Cert:CertLen/binary, Rest/binary>>, Acc) -> + certs_to_list(Rest, [Cert | Acc]); +certs_to_list(<<>>, Acc) -> + lists:reverse(Acc, []). + +certs_from_list(ACList) -> + list_to_binary([begin + CertLen = byte_size(Cert), + <<?UINT24(CertLen), Cert/binary>> + end || Cert <- ACList]). +from_3bytes(Bin3) -> + from_3bytes(Bin3, []). + +from_3bytes(<<>>, Acc) -> + lists:reverse(Acc); +from_3bytes(<<?UINT24(N), Rest/binary>>, Acc) -> + from_3bytes(Rest, [?uint16(N) | Acc]). + +from_2bytes(Bin2) -> + from_2bytes(Bin2, []). + +from_2bytes(<<>>, Acc) -> + lists:reverse(Acc); +from_2bytes(<<?UINT16(N), Rest/binary>>, Acc) -> + from_2bytes(Rest, [?uint16(N) | Acc]). +key_exchange_alg(rsa) -> + ?KEY_EXCHANGE_RSA; +key_exchange_alg(Alg) when Alg == dhe_rsa; Alg == dhe_dss; + Alg == dh_dss; Alg == dh_rsa; Alg == dh_anon -> + ?KEY_EXCHANGE_DIFFIE_HELLMAN; +key_exchange_alg(Alg) when Alg == ecdhe_rsa; Alg == ecdh_rsa; + Alg == ecdhe_ecdsa; Alg == ecdh_ecdsa; + Alg == ecdh_anon -> + ?KEY_EXCHANGE_EC_DIFFIE_HELLMAN; +key_exchange_alg(psk) -> + ?KEY_EXCHANGE_PSK; +key_exchange_alg(dhe_psk) -> + ?KEY_EXCHANGE_DHE_PSK; +key_exchange_alg(rsa_psk) -> + ?KEY_EXCHANGE_RSA_PSK; +key_exchange_alg(Alg) + when Alg == srp_rsa; Alg == srp_dss; Alg == srp_anon -> + ?KEY_EXCHANGE_SRP; +key_exchange_alg(_) -> + ?NULL. + +%%-------------Extension handling -------------------------------- + +handle_next_protocol(undefined, + _NextProtocolSelector, _Renegotiating) -> + undefined; + +handle_next_protocol(#next_protocol_negotiation{} = NextProtocols, + NextProtocolSelector, Renegotiating) -> + + case next_protocol_extension_allowed(NextProtocolSelector, Renegotiating) of + true -> + select_next_protocol(decode_next_protocols(NextProtocols), NextProtocolSelector); + false -> + ?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE) % unexpected next protocol extension + end. + + +handle_next_protocol_extension(NextProtocolNegotiation, Renegotiation, SslOpts)-> + case handle_next_protocol_on_server(NextProtocolNegotiation, Renegotiation, SslOpts) of + #alert{} = Alert -> + Alert; + ProtocolsToAdvertise -> + ProtocolsToAdvertise + end. + +handle_next_protocol_on_server(undefined, _Renegotiation, _SslOpts) -> + undefined; + +handle_next_protocol_on_server(#next_protocol_negotiation{extension_data = <<>>}, + false, #ssl_options{next_protocols_advertised = Protocols}) -> + Protocols; + +handle_next_protocol_on_server(_Hello, _Renegotiation, _SSLOpts) -> + ?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE). % unexpected next protocol extension + +next_protocol_extension_allowed(NextProtocolSelector, Renegotiating) -> + NextProtocolSelector =/= undefined andalso not Renegotiating. + +select_next_protocol({error, _Reason}, _NextProtocolSelector) -> + ?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE); +select_next_protocol(Protocols, NextProtocolSelector) -> + case NextProtocolSelector(Protocols) of + ?NO_PROTOCOL -> + ?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE); + Protocol when is_binary(Protocol) -> + Protocol + end. + +handle_srp_extension(undefined, Session) -> + Session; +handle_srp_extension(#srp{username = Username}, Session) -> + Session#session{srp_username = Username}. + +%%-------------Misc -------------------------------- + +select_cipher_suite([], _) -> + no_suite; +select_cipher_suite([Suite | ClientSuites], SupportedSuites) -> + case is_member(Suite, SupportedSuites) of + true -> + Suite; + false -> + select_cipher_suite(ClientSuites, SupportedSuites) + end. + +int_to_bin(I) -> + L = (length(integer_to_list(I, 16)) + 1) div 2, + <<I:(L*8)>>. + +is_member(Suite, SupportedSuites) -> + lists:member(Suite, SupportedSuites). + +select_compression(_CompressionMetodes) -> + ?NULL. + +-define(TLSEXT_SIGALG_RSA(MD), {MD, rsa}). +-define(TLSEXT_SIGALG_DSA(MD), {MD, dsa}). +-define(TLSEXT_SIGALG_ECDSA(MD), {MD, ecdsa}). + +-define(TLSEXT_SIGALG(MD), ?TLSEXT_SIGALG_ECDSA(MD), ?TLSEXT_SIGALG_RSA(MD)). + +advertised_hash_signs({Major, Minor}) when Major >= 3 andalso Minor >= 3 -> + HashSigns = [?TLSEXT_SIGALG(sha512), + ?TLSEXT_SIGALG(sha384), + ?TLSEXT_SIGALG(sha256), + ?TLSEXT_SIGALG(sha224), + ?TLSEXT_SIGALG(sha), + ?TLSEXT_SIGALG_DSA(sha), + ?TLSEXT_SIGALG_RSA(md5)], + CryptoSupport = crypto:supports(), + HasECC = proplists:get_bool(ecdsa, proplists:get_value(public_keys, CryptoSupport)), + Hashs = proplists:get_value(hashs, CryptoSupport), + #hash_sign_algos{hash_sign_algos = + lists:filter(fun({Hash, ecdsa}) -> HasECC andalso proplists:get_bool(Hash, Hashs); + ({Hash, _}) -> proplists:get_bool(Hash, Hashs) end, HashSigns)}; +advertised_hash_signs(_) -> + undefined. + diff --git a/lib/ssl/src/ssl_handshake.hrl b/lib/ssl/src/ssl_handshake.hrl index eb1a1dbf62..f25b0df806 100644 --- a/lib/ssl/src/ssl_handshake.hrl +++ b/lib/ssl/src/ssl_handshake.hrl @@ -28,11 +28,6 @@ -include_lib("public_key/include/public_key.hrl"). --type oid() :: tuple(). --type public_key_params() :: #'Dss-Parms'{} | {namedCurve, oid()} | #'ECParameters'{} | term(). --type public_key_info() :: {oid(), #'RSAPublicKey'{} | integer() | #'ECPoint'{}, public_key_params()}. --type tls_handshake_history() :: {[binary()], [binary()]}. - -define(NO_PROTOCOL, <<>>). %% Signature algorithms @@ -50,7 +45,8 @@ master_secret, srp_username, is_resumable, - time_stamp + time_stamp, + ecc }). -define(NUM_OF_SESSION_ID_BYTES, 32). % TSL 1.1 & SSL 3 @@ -96,17 +92,22 @@ %% client_hello defined in tls_handshake.hrl and dtls_handshake.hrl +-record(hello_extensions, { + renegotiation_info, + hash_signs, % supported combinations of hashes/signature algos + next_protocol_negotiation = undefined, % [binary()] + srp, + ec_point_formats, + elliptic_curves + }). + -record(server_hello, { server_version, random, session_id, % opaque SessionID<0..32> cipher_suite, % cipher_suites compression_method, % compression_method - renegotiation_info, - hash_signs, % supported combinations of hashes/signature algos - ec_point_formats, % supported ec point formats - elliptic_curves, % supported elliptic curver - next_protocol_negotiation = undefined % [binary()] + extensions }). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -337,6 +338,20 @@ -define(EXPLICIT_CHAR2, 2). -define(NAMED_CURVE, 3). +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% Dialyzer types +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +-type oid() :: tuple(). +-type public_key_params() :: #'Dss-Parms'{} | {namedCurve, oid()} | #'ECParameters'{} | term(). +-type public_key_info() :: {oid(), #'RSAPublicKey'{} | integer() | #'ECPoint'{}, public_key_params()}. +-type tls_handshake_history() :: {[binary()], [binary()]}. + +-type ssl_handshake() :: #server_hello{} | #server_hello_done{} | #certificate{} | #certificate_request{} | + #client_key_exchange{} | #finished{} | #certificate_verify{} | + #hello_request{} | #next_protocol{}. + + -endif. % -ifdef(ssl_handshake). diff --git a/lib/ssl/src/ssl_internal.hrl b/lib/ssl/src/ssl_internal.hrl index de8d20d399..96e3280fb5 100644 --- a/lib/ssl/src/ssl_internal.hrl +++ b/lib/ssl/src/ssl_internal.hrl @@ -37,7 +37,6 @@ -type tls_atom_version() :: sslv3 | tlsv1 | 'tlsv1.1' | 'tlsv1.2'. -type certdb_ref() :: reference(). -type db_handle() :: term(). --type key_algo() :: null | rsa | dhe_rsa | dhe_dss | ecdhe_ecdsa| ecdh_ecdsa | ecdh_rsa| srp_rsa| srp_dss | psk | dhe_psk | rsa_psk | dh_anon | ecdh_anon | srp_anon. -type der_cert() :: binary(). -type private_key() :: #'RSAPrivateKey'{} | #'DSAPrivateKey'{} | #'ECPrivateKey'{}. -type issuer() :: tuple(). @@ -50,6 +49,7 @@ -define(UINT16(X), X:16/unsigned-big-integer). -define(UINT24(X), X:24/unsigned-big-integer). -define(UINT32(X), X:32/unsigned-big-integer). +-define(UINT48(X), X:48/unsigned-big-integer). -define(UINT64(X), X:64/unsigned-big-integer). -define(STRING(X), ?UINT32((size(X))), (X)/binary). @@ -57,6 +57,7 @@ -define(uint16(X), << ?UINT16(X) >> ). -define(uint24(X), << ?UINT24(X) >> ). -define(uint32(X), << ?UINT32(X) >> ). +-define(uint48(X), << ?UINT48(X) >> ). -define(uint64(X), << ?UINT64(X) >> ). -define(CDR_MAGIC, "GIOP"). @@ -71,6 +72,8 @@ -define(ALL_SUPPORTED_VERSIONS, ['tlsv1.2', 'tlsv1.1', tlsv1, sslv3]). -define(MIN_SUPPORTED_VERSIONS, ['tlsv1.1', tlsv1, sslv3]). +-define(ALL_DATAGRAM_SUPPORTED_VERSIONS, ['dtlsv1.2', dtlsv1]). +-define(MIN_DATAGRAM_SUPPORTED_VERSIONS, ['dtlsv1.2', dtlsv1]). -record(ssl_options, { versions, % 'tlsv1.2' | 'tlsv1.1' | tlsv1 | sslv3 @@ -124,6 +127,10 @@ active = true }). +-type state_name() :: hello | abbreviated | certify | cipher | connection. +-type gen_fsm_state_return() :: {next_state, state_name(), term()} | + {next_state, state_name(), term(), timeout()} | + {stop, term(), term()}. -endif. % -ifdef(ssl_internal). diff --git a/lib/ssl/src/ssl_record.erl b/lib/ssl/src/ssl_record.erl new file mode 100644 index 0000000000..50a45dc16b --- /dev/null +++ b/lib/ssl/src/ssl_record.erl @@ -0,0 +1,439 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2013-2013. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% + +%%---------------------------------------------------------------------- +%% Purpose: Handle TLS/SSL/DTLS record protocol. Note epoch is only +%% used by DTLS but handled here so we can avoid code duplication. +%%---------------------------------------------------------------------- + +-module(ssl_record). + +-include("ssl_record.hrl"). +-include("ssl_internal.hrl"). +-include("ssl_cipher.hrl"). +-include("ssl_alert.hrl"). + +%% Connection state handling +-export([init_connection_states/1, + current_connection_state/2, pending_connection_state/2, + activate_pending_connection_state/2, + set_security_params/3, + set_mac_secret/4, + set_master_secret/2, + set_pending_cipher_state/4, + set_renegotiation_flag/2, + set_client_verify_data/3, + set_server_verify_data/3]). + +%% Encoding records +-export([encode_handshake/3, encode_alert_record/3, + encode_change_cipher_spec/2, encode_data/3]). + +%% Compression +-export([compress/3, uncompress/3, compressions/0]). + +-export([is_correct_mac/2]). + +%%==================================================================== +%% Internal application API +%%==================================================================== + +%%-------------------------------------------------------------------- +-spec init_connection_states(client | server) -> #connection_states{}. +%% +%% Description: Creates a connection_states record with appropriate +%% values for the initial SSL connection setup. +%%-------------------------------------------------------------------- +init_connection_states(Role) -> + ConnectionEnd = record_protocol_role(Role), + Current = initial_connection_state(ConnectionEnd), + Pending = empty_connection_state(ConnectionEnd), + #connection_states{current_read = Current, + pending_read = Pending, + current_write = Current, + pending_write = Pending + }. + +%%-------------------------------------------------------------------- +-spec current_connection_state(#connection_states{}, read | write) -> + #connection_state{}. +%% +%% Description: Returns the instance of the connection_state record +%% that is currently defined as the current conection state. +%%-------------------------------------------------------------------- +current_connection_state(#connection_states{current_read = Current}, + read) -> + Current; +current_connection_state(#connection_states{current_write = Current}, + write) -> + Current. + +%%-------------------------------------------------------------------- +-spec pending_connection_state(#connection_states{}, read | write) -> + term(). +%% +%% Description: Returns the instance of the connection_state record +%% that is currently defined as the pending conection state. +%%-------------------------------------------------------------------- +pending_connection_state(#connection_states{pending_read = Pending}, + read) -> + Pending; +pending_connection_state(#connection_states{pending_write = Pending}, + write) -> + Pending. + + +%%-------------------------------------------------------------------- +-spec activate_pending_connection_state(#connection_states{}, read | write) -> + #connection_states{}. +%% +%% Description: Creates a new instance of the connection_states record +%% where the pending state of <Type> has been activated. +%%-------------------------------------------------------------------- +activate_pending_connection_state(States = + #connection_states{current_read = Current, + pending_read = Pending}, + read) -> + NewCurrent = Pending#connection_state{epoch = dtls_next_epoch(Current), + sequence_number = 0}, + SecParams = Pending#connection_state.security_parameters, + ConnectionEnd = SecParams#security_parameters.connection_end, + EmptyPending = empty_connection_state(ConnectionEnd), + SecureRenegotation = NewCurrent#connection_state.secure_renegotiation, + NewPending = EmptyPending#connection_state{secure_renegotiation = SecureRenegotation}, + States#connection_states{current_read = NewCurrent, + pending_read = NewPending + }; + +activate_pending_connection_state(States = + #connection_states{current_write = Current, + pending_write = Pending}, + write) -> + NewCurrent = Pending#connection_state{epoch = dtls_next_epoch(Current), + sequence_number = 0}, + SecParams = Pending#connection_state.security_parameters, + ConnectionEnd = SecParams#security_parameters.connection_end, + EmptyPending = empty_connection_state(ConnectionEnd), + SecureRenegotation = NewCurrent#connection_state.secure_renegotiation, + NewPending = EmptyPending#connection_state{secure_renegotiation = SecureRenegotation}, + States#connection_states{current_write = NewCurrent, + pending_write = NewPending + }. + + +%%-------------------------------------------------------------------- +-spec set_security_params(#security_parameters{}, #security_parameters{}, + #connection_states{}) -> #connection_states{}. +%% +%% Description: Creates a new instance of the connection_states record +%% where the pending states gets its security parameters updated. +%%-------------------------------------------------------------------- +set_security_params(ReadParams, WriteParams, States = + #connection_states{pending_read = Read, + pending_write = Write}) -> + States#connection_states{pending_read = + Read#connection_state{security_parameters = + ReadParams}, + pending_write = + Write#connection_state{security_parameters = + WriteParams} + }. +%%-------------------------------------------------------------------- +-spec set_mac_secret(binary(), binary(), client | server, + #connection_states{}) -> #connection_states{}. +%% +%% Description: update the mac_secret field in pending connection states +%%-------------------------------------------------------------------- +set_mac_secret(ClientWriteMacSecret, ServerWriteMacSecret, client, States) -> + set_mac_secret(ServerWriteMacSecret, ClientWriteMacSecret, States); +set_mac_secret(ClientWriteMacSecret, ServerWriteMacSecret, server, States) -> + set_mac_secret(ClientWriteMacSecret, ServerWriteMacSecret, States). + +set_mac_secret(ReadMacSecret, WriteMacSecret, + States = #connection_states{pending_read = Read, + pending_write = Write}) -> + States#connection_states{ + pending_read = Read#connection_state{mac_secret = ReadMacSecret}, + pending_write = Write#connection_state{mac_secret = WriteMacSecret} + }. + + +%%-------------------------------------------------------------------- +-spec set_master_secret(binary(), #connection_states{}) -> #connection_states{}. +%% +%% Description: Set master_secret in pending connection states +%%-------------------------------------------------------------------- +set_master_secret(MasterSecret, + States = #connection_states{pending_read = Read, + pending_write = Write}) -> + ReadSecPar = Read#connection_state.security_parameters, + Read1 = Read#connection_state{ + security_parameters = ReadSecPar#security_parameters{ + master_secret = MasterSecret}}, + WriteSecPar = Write#connection_state.security_parameters, + Write1 = Write#connection_state{ + security_parameters = WriteSecPar#security_parameters{ + master_secret = MasterSecret}}, + States#connection_states{pending_read = Read1, pending_write = Write1}. + +%%-------------------------------------------------------------------- +-spec set_renegotiation_flag(boolean(), #connection_states{}) -> #connection_states{}. +%% +%% Description: Set secure_renegotiation in pending connection states +%%-------------------------------------------------------------------- +set_renegotiation_flag(Flag, #connection_states{ + current_read = CurrentRead0, + current_write = CurrentWrite0, + pending_read = PendingRead0, + pending_write = PendingWrite0} + = ConnectionStates) -> + CurrentRead = CurrentRead0#connection_state{secure_renegotiation = Flag}, + CurrentWrite = CurrentWrite0#connection_state{secure_renegotiation = Flag}, + PendingRead = PendingRead0#connection_state{secure_renegotiation = Flag}, + PendingWrite = PendingWrite0#connection_state{secure_renegotiation = Flag}, + ConnectionStates#connection_states{current_read = CurrentRead, + current_write = CurrentWrite, + pending_read = PendingRead, + pending_write = PendingWrite}. + +%%-------------------------------------------------------------------- +-spec set_client_verify_data(current_read | current_write | current_both, + binary(), #connection_states{})-> + #connection_states{}. +%% +%% Description: Set verify data in connection states. +%%-------------------------------------------------------------------- +set_client_verify_data(current_read, Data, + #connection_states{current_read = CurrentRead0, + pending_write = PendingWrite0} + = ConnectionStates) -> + CurrentRead = CurrentRead0#connection_state{client_verify_data = Data}, + PendingWrite = PendingWrite0#connection_state{client_verify_data = Data}, + ConnectionStates#connection_states{current_read = CurrentRead, + pending_write = PendingWrite}; +set_client_verify_data(current_write, Data, + #connection_states{pending_read = PendingRead0, + current_write = CurrentWrite0} + = ConnectionStates) -> + PendingRead = PendingRead0#connection_state{client_verify_data = Data}, + CurrentWrite = CurrentWrite0#connection_state{client_verify_data = Data}, + ConnectionStates#connection_states{pending_read = PendingRead, + current_write = CurrentWrite}; +set_client_verify_data(current_both, Data, + #connection_states{current_read = CurrentRead0, + current_write = CurrentWrite0} + = ConnectionStates) -> + CurrentRead = CurrentRead0#connection_state{client_verify_data = Data}, + CurrentWrite = CurrentWrite0#connection_state{client_verify_data = Data}, + ConnectionStates#connection_states{current_read = CurrentRead, + current_write = CurrentWrite}. +%%-------------------------------------------------------------------- +-spec set_server_verify_data(current_read | current_write | current_both, + binary(), #connection_states{})-> + #connection_states{}. +%% +%% Description: Set verify data in pending connection states. +%%-------------------------------------------------------------------- +set_server_verify_data(current_write, Data, + #connection_states{pending_read = PendingRead0, + current_write = CurrentWrite0} + = ConnectionStates) -> + PendingRead = PendingRead0#connection_state{server_verify_data = Data}, + CurrentWrite = CurrentWrite0#connection_state{server_verify_data = Data}, + ConnectionStates#connection_states{pending_read = PendingRead, + current_write = CurrentWrite}; + +set_server_verify_data(current_read, Data, + #connection_states{current_read = CurrentRead0, + pending_write = PendingWrite0} + = ConnectionStates) -> + CurrentRead = CurrentRead0#connection_state{server_verify_data = Data}, + PendingWrite = PendingWrite0#connection_state{server_verify_data = Data}, + ConnectionStates#connection_states{current_read = CurrentRead, + pending_write = PendingWrite}; + +set_server_verify_data(current_both, Data, + #connection_states{current_read = CurrentRead0, + current_write = CurrentWrite0} + = ConnectionStates) -> + CurrentRead = CurrentRead0#connection_state{server_verify_data = Data}, + CurrentWrite = CurrentWrite0#connection_state{server_verify_data = Data}, + ConnectionStates#connection_states{current_read = CurrentRead, + current_write = CurrentWrite}. +%%-------------------------------------------------------------------- +-spec set_pending_cipher_state(#connection_states{}, #cipher_state{}, + #cipher_state{}, client | server) -> + #connection_states{}. +%% +%% Description: Set the cipher state in the specified pending connection state. +%%-------------------------------------------------------------------- +set_pending_cipher_state(#connection_states{pending_read = Read, + pending_write = Write} = States, + ClientState, ServerState, server) -> + States#connection_states{ + pending_read = Read#connection_state{cipher_state = ClientState}, + pending_write = Write#connection_state{cipher_state = ServerState}}; + +set_pending_cipher_state(#connection_states{pending_read = Read, + pending_write = Write} = States, + ClientState, ServerState, client) -> + States#connection_states{ + pending_read = Read#connection_state{cipher_state = ServerState}, + pending_write = Write#connection_state{cipher_state = ClientState}}. + + +%%-------------------------------------------------------------------- +-spec encode_handshake(iolist(), tls_version(), #connection_states{}) -> + {iolist(), #connection_states{}}. +%% +%% Description: Encodes a handshake message to send on the ssl-socket. +%%-------------------------------------------------------------------- +encode_handshake(Frag, Version, ConnectionStates) -> + encode_plain_text(?HANDSHAKE, Version, Frag, ConnectionStates). + +%%-------------------------------------------------------------------- +-spec encode_alert_record(#alert{}, tls_version(), #connection_states{}) -> + {iolist(), #connection_states{}}. +%% +%% Description: Encodes an alert message to send on the ssl-socket. +%%-------------------------------------------------------------------- +encode_alert_record(#alert{level = Level, description = Description}, + Version, ConnectionStates) -> + encode_plain_text(?ALERT, Version, <<?BYTE(Level), ?BYTE(Description)>>, + ConnectionStates). + +%%-------------------------------------------------------------------- +-spec encode_change_cipher_spec(tls_version(), #connection_states{}) -> + {iolist(), #connection_states{}}. +%% +%% Description: Encodes a change_cipher_spec-message to send on the ssl socket. +%%-------------------------------------------------------------------- +encode_change_cipher_spec(Version, ConnectionStates) -> + encode_plain_text(?CHANGE_CIPHER_SPEC, Version, <<1:8>>, ConnectionStates). + +%%-------------------------------------------------------------------- +-spec encode_data(binary(), tls_version(), #connection_states{}) -> + {iolist(), #connection_states{}}. +%% +%% Description: Encodes data to send on the ssl-socket. +%%-------------------------------------------------------------------- +encode_data(Frag, Version, + #connection_states{current_write = #connection_state{ + security_parameters = + #security_parameters{bulk_cipher_algorithm = BCA}}} = + ConnectionStates) -> + Data = split_bin(Frag, ?MAX_PLAIN_TEXT_LENGTH, Version, BCA), + encode_iolist(?APPLICATION_DATA, Data, Version, ConnectionStates). + +uncompress(?NULL, Data, CS) -> + {Data, CS}. + +compress(?NULL, Data, CS) -> + {Data, CS}. + +%%-------------------------------------------------------------------- +-spec compressions() -> [binary()]. +%% +%% Description: return a list of compressions supported (currently none) +%%-------------------------------------------------------------------- +compressions() -> + [?byte(?NULL)]. + +%%-------------------------------------------------------------------- +%%% Internal functions +%%-------------------------------------------------------------------- +empty_connection_state(ConnectionEnd) -> + SecParams = empty_security_params(ConnectionEnd), + #connection_state{security_parameters = SecParams}. + +empty_security_params(ConnectionEnd = ?CLIENT) -> + #security_parameters{connection_end = ConnectionEnd, + client_random = random()}; +empty_security_params(ConnectionEnd = ?SERVER) -> + #security_parameters{connection_end = ConnectionEnd, + server_random = random()}. +random() -> + Secs_since_1970 = calendar:datetime_to_gregorian_seconds( + calendar:universal_time()) - 62167219200, + Random_28_bytes = crypto:rand_bytes(28), + <<?UINT32(Secs_since_1970), Random_28_bytes/binary>>. + +dtls_next_epoch(#connection_state{epoch = undefined}) -> %% SSL/TLS + undefined; +dtls_next_epoch(#connection_state{epoch = Epoch}) -> %% DTLS + Epoch + 1. + +is_correct_mac(Mac, Mac) -> + true; +is_correct_mac(_M,_H) -> + false. + +record_protocol_role(client) -> + ?CLIENT; +record_protocol_role(server) -> + ?SERVER. + +initial_connection_state(ConnectionEnd) -> + #connection_state{security_parameters = + initial_security_params(ConnectionEnd), + sequence_number = 0 + }. + +initial_security_params(ConnectionEnd) -> + SecParams = #security_parameters{connection_end = ConnectionEnd, + compression_algorithm = ?NULL}, + ssl_cipher:security_parameters(?TLS_NULL_WITH_NULL_NULL, SecParams). + + +encode_plain_text(Type, Version, Data, ConnectionStates) -> + RecordCB = protocol_module(Version), + RecordCB:encode_plain_text(Type, Version, Data, ConnectionStates). + +encode_iolist(Type, Data, Version, ConnectionStates0) -> + RecordCB = protocol_module(Version), + {ConnectionStates, EncodedMsg} = + lists:foldl(fun(Text, {CS0, Encoded}) -> + {Enc, CS1} = + RecordCB:encode_plain_text(Type, Version, Text, CS0), + {CS1, [Enc | Encoded]} + end, {ConnectionStates0, []}, Data), + {lists:reverse(EncodedMsg), ConnectionStates}. + +%% 1/n-1 splitting countermeasure Rizzo/Duong-Beast, RC4 chiphers are +%% not vulnerable to this attack. +split_bin(<<FirstByte:8, Rest/binary>>, ChunkSize, Version, BCA) when + BCA =/= ?RC4 andalso ({3, 1} == Version orelse + {3, 0} == Version) -> + do_split_bin(Rest, ChunkSize, [[FirstByte]]); +split_bin(Bin, ChunkSize, _, _) -> + do_split_bin(Bin, ChunkSize, []). + +do_split_bin(<<>>, _, Acc) -> + lists:reverse(Acc); +do_split_bin(Bin, ChunkSize, Acc) -> + case Bin of + <<Chunk:ChunkSize/binary, Rest/binary>> -> + do_split_bin(Rest, ChunkSize, [Chunk | Acc]); + _ -> + lists:reverse(Acc, [Bin]) + end. + +protocol_module({3, _}) -> + tls_record; +protocol_module({254, _}) -> + dtls_record. diff --git a/lib/ssl/src/ssl_record.hrl b/lib/ssl/src/ssl_record.hrl index 2fd17f9c35..c17fa53a62 100644 --- a/lib/ssl/src/ssl_record.hrl +++ b/lib/ssl/src/ssl_record.hrl @@ -29,6 +29,18 @@ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% Connection states - RFC 4346 section 6.1 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-record(connection_state, { + security_parameters, + compression_state, + cipher_state, + mac_secret, + epoch, %% Only used by DTLS + sequence_number, + %% RFC 5746 + secure_renegotiation, + client_verify_data, + server_verify_data + }). -record(connection_states, { current_read, @@ -56,17 +68,7 @@ exportable % boolean }). --record(connection_state, { - security_parameters, - compression_state, - cipher_state, - mac_secret, - sequence_number, - %% RFC 5746 - secure_renegotiation, - client_verify_data, - server_verify_data - }). +-define(INITIAL_BYTES, 5). -define(MAX_SEQENCE_NUMBER, 18446744073709552000). %% math:pow(2, 64) - 1 = 1.8446744073709552e19 %% Sequence numbers can not wrap so when max is about to be reached we should renegotiate. diff --git a/lib/ssl/src/ssl_ssl2.erl b/lib/ssl/src/ssl_v2.erl index a9ab6a2678..07876366f1 100644 --- a/lib/ssl/src/ssl_ssl2.erl +++ b/lib/ssl/src/ssl_v2.erl @@ -1,30 +1,30 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2007-2011. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 2007-2013. All Rights Reserved. +%% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in %% compliance with the License. You should have received a copy of the %% Erlang Public License along with this software. If not, it can be %% retrieved online at http://www.erlang.org/. -%% +%% %% Software distributed under the License is distributed on an "AS IS" %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %% the License for the specific language governing rights and limitations %% under the License. -%% +%% %% %CopyrightEnd% %% %% %%---------------------------------------------------------------------- -%% Purpose: Handles sslv2 hello as clients supporting sslv2 and higher +%% Purpose: Handles sslv2 hello as clients supporting sslv2 and higher %% will send an sslv2 hello. %%---------------------------------------------------------------------- --module(ssl_ssl2). - +-module(ssl_v2). + -export([client_random/2]). client_random(ChallengeData, 32) -> diff --git a/lib/ssl/src/ssl_ssl3.erl b/lib/ssl/src/ssl_v3.erl index 013c27ebb5..d477b3df81 100644 --- a/lib/ssl/src/ssl_ssl3.erl +++ b/lib/ssl/src/ssl_v3.erl @@ -22,14 +22,14 @@ %% Purpose: Handles sslv3 encryption. %%---------------------------------------------------------------------- --module(ssl_ssl3). +-module(ssl_v3). -include("ssl_cipher.hrl"). -include("ssl_internal.hrl"). -include("ssl_record.hrl"). % MD5 and SHA -export([master_secret/3, finished/3, certificate_verify/3, - mac_hash/6, setup_keys/7, + mac_hash/6, setup_keys/7, suites/0]). -compile(inline). @@ -40,7 +40,7 @@ -spec master_secret(binary(), binary(), binary()) -> binary(). master_secret(PremasterSecret, ClientRandom, ServerRandom) -> - %% draft-ietf-tls-ssl-version3-00 - 6.2.2 + %% draft-ietf-tls-ssl-version3-00 - 6.2.2 %% key_block = %% MD5(master_secret + SHA(`A' + master_secret + %% ServerHello.random + @@ -62,7 +62,7 @@ finished(Role, MasterSecret, Handshake) -> %% opaque md5_hash[16]; %% opaque sha_hash[20]; %% } Finished; - %% + %% %% md5_hash MD5(master_secret + pad2 + %% MD5(handshake_messages + Sender + %% master_secret + pad1)); @@ -95,23 +95,23 @@ certificate_verify(sha, MasterSecret, Handshake) -> handshake_hash(?SHA, MasterSecret, undefined, Handshake). --spec mac_hash(integer(), binary(), integer(), integer(), integer(), binary()) -> binary(). +-spec mac_hash(integer(), binary(), integer(), integer(), integer(), binary()) -> binary(). mac_hash(Method, Mac_write_secret, Seq_num, Type, Length, Fragment) -> - %% draft-ietf-tls-ssl-version3-00 - 5.2.3.1 + %% draft-ietf-tls-ssl-version3-00 - 5.2.3.1 %% hash(MAC_write_secret + pad_2 + %% hash(MAC_write_secret + pad_1 + seq_num + %% SSLCompressed.type + SSLCompressed.length + %% SSLCompressed.fragment)); - Mac = mac_hash(Method, Mac_write_secret, - [<<?UINT64(Seq_num), ?BYTE(Type), + Mac = mac_hash(Method, Mac_write_secret, + [<<?UINT64(Seq_num), ?BYTE(Type), ?UINT16(Length)>>, Fragment]), Mac. --spec setup_keys(binary(), binary(), binary(), - integer(), integer(), term(), integer()) -> - {binary(), binary(), binary(), - binary(), binary(), binary()}. +-spec setup_keys(binary(), binary(), binary(), + integer(), integer(), term(), integer()) -> + {binary(), binary(), binary(), + binary(), binary(), binary()}. setup_keys(MasterSecret, ServerRandom, ClientRandom, HS, KML, _EKML, IVS) -> KeyBlock = generate_keyblock(MasterSecret, ServerRandom, ClientRandom, @@ -133,7 +133,7 @@ setup_keys(MasterSecret, ServerRandom, ClientRandom, HS, KML, _EKML, IVS) -> -spec suites() -> [cipher_suite()]. suites() -> - [ + [ ?TLS_DHE_RSA_WITH_AES_256_CBC_SHA, ?TLS_DHE_DSS_WITH_AES_256_CBC_SHA, ?TLS_RSA_WITH_AES_256_CBC_SHA, @@ -143,7 +143,7 @@ suites() -> ?TLS_DHE_RSA_WITH_AES_128_CBC_SHA, ?TLS_DHE_DSS_WITH_AES_128_CBC_SHA, ?TLS_RSA_WITH_AES_128_CBC_SHA, - %%?TLS_RSA_WITH_IDEA_CBC_SHA, + %%?TLS_RSA_WITH_IDEA_CBC_SHA, ?TLS_RSA_WITH_RC4_128_SHA, ?TLS_RSA_WITH_RC4_128_MD5, ?TLS_RSA_WITH_DES_CBC_SHA diff --git a/lib/ssl/src/tls_connection.erl b/lib/ssl/src/tls_connection.erl index 77f49c5d2a..39595b4f95 100644 --- a/lib/ssl/src/tls_connection.erl +++ b/lib/ssl/src/tls_connection.erl @@ -76,7 +76,8 @@ negotiated_version, % tls_version() client_certificate_requested = false, key_algorithm, % atom as defined by cipher_suite - hashsign_algorithm, % atom as defined by cipher_suite + hashsign_algorithm = {undefined, undefined}, + cert_hashsign_algorithm, public_key_info, % PKIX: {Algorithm, PublicKey, PublicKeyParams} private_key, % PKIX: #'RSAPrivateKey'{} diffie_hellman_params, % PKIX: #'DHParameter'{} relevant for server side @@ -96,8 +97,7 @@ terminated = false, % allow_renegotiate = true, expecting_next_protocol_negotiation = false :: boolean(), - next_protocol = undefined :: undefined | binary(), - client_ecc % {Curves, PointFmt} + next_protocol = undefined :: undefined | binary() }). -define(DEFAULT_DIFFIE_HELLMAN_PARAMS, @@ -105,10 +105,6 @@ base = ?DEFAULT_DIFFIE_HELLMAN_GENERATOR}). -define(WAIT_TO_ALLOW_RENEGOTIATION, 12000). --type state_name() :: hello | abbreviated | certify | cipher | connection. --type gen_fsm_state_return() :: {next_state, state_name(), #state{}} | - {next_state, state_name(), #state{}, timeout()} | - {stop, term(), #state{}}. %%==================================================================== %% Internal application API @@ -388,9 +384,8 @@ hello(#server_hello{cipher_suite = CipherSuite, _ -> NextProtocol end, - + State = State0#state{key_algorithm = KeyAlgorithm, - hashsign_algorithm = default_hashsign(Version, KeyAlgorithm), negotiated_version = Version, connection_states = ConnectionStates, premaster_secret = PremasterSecret, @@ -406,23 +401,27 @@ hello(#server_hello{cipher_suite = CipherSuite, end end; -hello(Hello = #client_hello{client_version = ClientVersion}, +hello(Hello = #client_hello{client_version = ClientVersion, + extensions = #hello_extensions{hash_signs = HashSigns}}, State = #state{connection_states = ConnectionStates0, - port = Port, session = #session{own_certificate = Cert} = Session0, + port = Port, + session = #session{own_certificate = Cert} = Session0, renegotiation = {Renegotiation, _}, - session_cache = Cache, + session_cache = Cache, session_cache_cb = CacheCb, ssl_options = SslOpts}) -> + HashSign = ssl_handshake:select_hashsign(HashSigns, Cert), case tls_handshake:hello(Hello, SslOpts, {Port, Session0, Cache, CacheCb, - ConnectionStates0, Cert}, Renegotiation) of - {Version, {Type, Session}, ConnectionStates, ProtocolsToAdvertise, - EcPointFormats, EllipticCurves} -> - do_server_hello(Type, ProtocolsToAdvertise, - EcPointFormats, EllipticCurves, + ConnectionStates0, Cert}, Renegotiation) of + {Version, {Type, #session{cipher_suite = CipherSuite} = Session}, + ConnectionStates, ServerHelloExt} -> + {KeyAlg, _, _, _} = ssl_cipher:suite_definition(CipherSuite), + NegotiatedHashSign = negotiated_hashsign(HashSign, KeyAlg, Version), + do_server_hello(Type, ServerHelloExt, State#state{connection_states = ConnectionStates, negotiated_version = Version, session = Session, - client_ecc = {EllipticCurves, EcPointFormats}}); + hashsign_algorithm = NegotiatedHashSign}); #alert{} = Alert -> handle_own_alert(Alert, ClientVersion, hello, State) end; @@ -447,11 +446,11 @@ abbreviated(#finished{verify_data = Data} = Finished, session = #session{master_secret = MasterSecret}, connection_states = ConnectionStates0} = State) -> - case tls_handshake:verify_connection(Version, Finished, client, + case ssl_handshake:verify_connection(Version, Finished, client, get_current_connection_state_prf(ConnectionStates0, write), MasterSecret, Handshake) of verified -> - ConnectionStates = tls_record:set_client_verify_data(current_both, Data, ConnectionStates0), + ConnectionStates = ssl_record:set_client_verify_data(current_both, Data, ConnectionStates0), next_state_connection(abbreviated, ack_connection(State#state{connection_states = ConnectionStates})); #alert{} = Alert -> @@ -463,11 +462,11 @@ abbreviated(#finished{verify_data = Data} = Finished, session = #session{master_secret = MasterSecret}, negotiated_version = Version, connection_states = ConnectionStates0} = State) -> - case tls_handshake:verify_connection(Version, Finished, server, + case ssl_handshake:verify_connection(Version, Finished, server, get_pending_connection_state_prf(ConnectionStates0, write), MasterSecret, Handshake0) of verified -> - ConnectionStates1 = tls_record:set_server_verify_data(current_read, Data, ConnectionStates0), + ConnectionStates1 = ssl_record:set_server_verify_data(current_read, Data, ConnectionStates0), {ConnectionStates, Handshake} = finalize_handshake(State#state{connection_states = ConnectionStates1}, abbreviated), next_state_connection(abbreviated, @@ -522,11 +521,11 @@ certify(#certificate{} = Cert, cert_db = CertDbHandle, cert_db_ref = CertDbRef, ssl_options = Opts} = State) -> - case tls_handshake:certify(Cert, CertDbHandle, CertDbRef, Opts#ssl_options.depth, + case ssl_handshake:certify(Cert, CertDbHandle, CertDbRef, Opts#ssl_options.depth, Opts#ssl_options.verify, Opts#ssl_options.verify_fun, Role) of {PeerCert, PublicKeyInfo} -> - handle_peer_cert(PeerCert, PublicKeyInfo, + handle_peer_cert(Role, PeerCert, PublicKeyInfo, State#state{client_certificate_requested = false}); #alert{} = Alert -> handle_own_alert(Alert, Version, certify, State) @@ -552,9 +551,11 @@ certify(#server_key_exchange{} = Msg, #state{role = client, key_algorithm = rsa} = State) -> handle_unexpected_message(Msg, certify_server_keyexchange, State); -certify(#certificate_request{}, State0) -> +certify(#certificate_request{hashsign_algorithms = HashSigns}, + #state{session = #session{own_certificate = Cert}} = State0) -> + HashSign = ssl_handshake:select_hashsign(HashSigns, Cert), {Record, State} = next_record(State0#state{client_certificate_requested = true}), - next_state(certify, certify, Record, State); + next_state(certify, certify, Record, State#state{cert_hashsign_algorithm = HashSign}); %% PSK and RSA_PSK might bypass the Server-Key-Exchange certify(#server_hello_done{}, @@ -602,7 +603,7 @@ certify(#server_hello_done{}, negotiated_version = Version, premaster_secret = undefined, role = client} = State0) -> - case tls_handshake:master_secret(Version, Session, + case ssl_handshake:master_secret(tls_record, Version, Session, ConnectionStates0, client) of {MasterSecret, ConnectionStates} -> State = State0#state{connection_states = ConnectionStates}, @@ -618,7 +619,7 @@ certify(#server_hello_done{}, negotiated_version = Version, premaster_secret = PremasterSecret, role = client} = State0) -> - case tls_handshake:master_secret(Version, PremasterSecret, + case ssl_handshake:master_secret(tls_record, Version, PremasterSecret, ConnectionStates0, client) of {MasterSecret, ConnectionStates} -> Session = Session0#session{master_secret = MasterSecret}, @@ -639,7 +640,7 @@ certify(#client_key_exchange{} = Msg, certify(#client_key_exchange{exchange_keys = Keys}, State = #state{key_algorithm = KeyAlg, negotiated_version = Version}) -> try - certify_client_key_exchange(tls_handshake:decode_client_key(Keys, KeyAlg, Version), State) + certify_client_key_exchange(ssl_handshake:decode_client_key(Keys, KeyAlg, Version), State) catch #alert{} = Alert -> handle_own_alert(Alert, Version, certify, State) @@ -657,8 +658,8 @@ certify_client_key_exchange(#encrypted_premaster_secret{premaster_secret= EncPMS connection_states = ConnectionStates0, session = Session0, private_key = Key} = State0) -> - PremasterSecret = tls_handshake:decrypt_premaster_secret(EncPMS, Key), - case tls_handshake:master_secret(Version, PremasterSecret, + PremasterSecret = ssl_handshake:decrypt_premaster_secret(EncPMS, Key), + case ssl_handshake:master_secret(tls_record, Version, PremasterSecret, ConnectionStates0, server) of {MasterSecret, ConnectionStates} -> Session = Session0#session{master_secret = MasterSecret}, @@ -724,7 +725,7 @@ certify_client_key_exchange(#client_rsa_psk_identity{ #encrypted_premaster_secret{premaster_secret= EncPMS}}, #state{negotiated_version = Version, private_key = Key} = State0) -> - PremasterSecret = tls_handshake:decrypt_premaster_secret(EncPMS, Key), + PremasterSecret = ssl_handshake:decrypt_premaster_secret(EncPMS, Key), case server_rsa_psk_master_secret(PskIdentity, PremasterSecret, State0) of #state{} = State1 -> {Record, State} = next_record(State1), @@ -757,21 +758,18 @@ cipher(#hello_request{}, State0) -> cipher(#certificate_verify{signature = Signature, hashsign_algorithm = CertHashSign}, #state{role = server, - public_key_info = PublicKeyInfo, + public_key_info = {Algo, _, _} =PublicKeyInfo, negotiated_version = Version, session = #session{master_secret = MasterSecret}, - hashsign_algorithm = ConnectionHashSign, tls_handshake_history = Handshake } = State0) -> - HashSign = case CertHashSign of - {_, _} -> CertHashSign; - _ -> ConnectionHashSign - end, - case tls_handshake:certificate_verify(Signature, PublicKeyInfo, + + HashSign = ssl_handshake:select_cert_hashsign(CertHashSign, Algo, Version), + case ssl_handshake:certificate_verify(Signature, PublicKeyInfo, Version, HashSign, MasterSecret, Handshake) of valid -> {Record, State} = next_record(State0), - next_state(cipher, cipher, Record, State); + next_state(cipher, cipher, Record, State#state{cert_hashsign_algorithm = HashSign}); #alert{} = Alert -> handle_own_alert(Alert, Version, cipher, State0) end; @@ -790,7 +788,7 @@ cipher(#finished{verify_data = Data} = Finished, = Session0, connection_states = ConnectionStates0, tls_handshake_history = Handshake0} = State) -> - case tls_handshake:verify_connection(Version, Finished, + case ssl_handshake:verify_connection(Version, Finished, opposite_role(Role), get_current_connection_state_prf(ConnectionStates0, read), MasterSecret, Handshake0) of @@ -1025,7 +1023,7 @@ handle_sync_event({prf, Secret, Label, Seed, WantedLength}, _, StateName, #state{connection_states = ConnectionStates, negotiated_version = Version} = State) -> ConnectionState = - tls_record:current_connection_state(ConnectionStates, read), + ssl_record:current_connection_state(ConnectionStates, read), SecParams = ConnectionState#connection_state.security_parameters, #security_parameters{master_secret = MasterSecret, client_random = ClientRandom, @@ -1040,7 +1038,7 @@ handle_sync_event({prf, Secret, Label, Seed, WantedLength}, _, StateName, (client_random, Acc) -> [ClientRandom|Acc]; (server_random, Acc) -> [ServerRandom|Acc] end, [], Seed)), - tls_handshake:prf(Version, SecretToUse, Label, SeedToUse, WantedLength) + ssl_handshake:prf(Version, SecretToUse, Label, SeedToUse, WantedLength) catch exit:_ -> {error, badarg}; error:Reason -> {error, Reason} @@ -1369,25 +1367,34 @@ sync_send_all_state_event(FsmPid, Event) -> {error, closed} end. -%% We do currently not support cipher suites that use fixed DH. -%% If we want to implement that we should add a code -%% here to extract DH parameters form cert. -handle_peer_cert(PeerCert, PublicKeyInfo, - #state{session = Session} = State0) -> +handle_peer_cert(Role, PeerCert, PublicKeyInfo, + #state{session = #session{cipher_suite = CipherSuite} = Session} = State0) -> State1 = State0#state{session = Session#session{peer_certificate = PeerCert}, public_key_info = PublicKeyInfo}, - State2 = case PublicKeyInfo of - {?'id-ecPublicKey', #'ECPoint'{point = _ECPoint} = PublicKey, PublicKeyParams} -> - ECDHKey = public_key:generate_key(PublicKeyParams), - State3 = State1#state{diffie_hellman_keys = ECDHKey}, - ec_dh_master_secret(ECDHKey, PublicKey, State3); - - _ -> State1 - end, + {KeyAlg,_,_,_} = ssl_cipher:suite_definition(CipherSuite), + State2 = handle_peer_cert_key(Role, PeerCert, PublicKeyInfo, KeyAlg, State1), + {Record, State} = next_record(State2), next_state(certify, certify, Record, State). +handle_peer_cert_key(client, _, + {?'id-ecPublicKey', #'ECPoint'{point = _ECPoint} = PublicKey, PublicKeyParams}, + KeyAlg, State) when KeyAlg == ecdh_rsa; + KeyAlg == ecdh_ecdsa -> + ECDHKey = public_key:generate_key(PublicKeyParams), + ec_dh_master_secret(ECDHKey, PublicKey, State#state{diffie_hellman_keys = ECDHKey}); + +%% We do currently not support cipher suites that use fixed DH. +%% If we want to implement that the following clause can be used +%% to extract DH parameters form cert. +%% handle_peer_cert_key(client, _PeerCert, {?dhpublicnumber, PublicKey, PublicKeyParams}, {_,SignAlg}, +%% #state{diffie_hellman_keys = {_, MyPrivatKey}} = State) when SignAlg == dh_rsa; +%% SignAlg == dh_dss -> +%% dh_master_secret(PublicKeyParams, PublicKey, MyPrivatKey, State); +handle_peer_cert_key(_, _, _, _, State) -> + State. + certify_client(#state{client_certificate_requested = true, role = client, connection_states = ConnectionStates0, transport_cb = Transport, @@ -1397,7 +1404,7 @@ certify_client(#state{client_certificate_requested = true, role = client, session = #session{own_certificate = OwnCert}, socket = Socket, tls_handshake_history = Handshake0} = State) -> - Certificate = tls_handshake:certificate(OwnCert, CertDbHandle, CertDbRef, client), + Certificate = ssl_handshake:certificate(OwnCert, CertDbHandle, CertDbRef, client), {BinCert, ConnectionStates, Handshake} = encode_handshake(Certificate, Version, ConnectionStates0, Handshake0), Transport:send(Socket, BinCert), @@ -1414,11 +1421,10 @@ verify_client_cert(#state{client_certificate_requested = true, role = client, private_key = PrivateKey, session = #session{master_secret = MasterSecret, own_certificate = OwnCert}, - hashsign_algorithm = HashSign, + cert_hashsign_algorithm = HashSign, tls_handshake_history = Handshake0} = State) -> - %%TODO: for TLS 1.2 we can choose a different/stronger HashSign combination for this. - case tls_handshake:client_certificate_verify(OwnCert, MasterSecret, + case ssl_handshake:client_certificate_verify(OwnCert, MasterSecret, Version, HashSign, PrivateKey, Handshake0) of #certificate_verify{} = Verified -> {BinVerified, ConnectionStates, Handshake} = @@ -1435,21 +1441,17 @@ verify_client_cert(#state{client_certificate_requested = true, role = client, verify_client_cert(#state{client_certificate_requested = false} = State) -> State. -do_server_hello(Type, NextProtocolsToSend, - EcPointFormats, EllipticCurves, +do_server_hello(Type, #hello_extensions{next_protocol_negotiation = NextProtocols} = ServerHelloExt, #state{negotiated_version = Version, session = #session{session_id = SessId}, - connection_states = ConnectionStates0, - renegotiation = {Renegotiation, _}} + connection_states = ConnectionStates0} = State0) when is_atom(Type) -> ServerHello = - tls_handshake:server_hello(SessId, Version, - ConnectionStates0, Renegotiation, - NextProtocolsToSend, EcPointFormats, EllipticCurves), + tls_handshake:server_hello(SessId, Version, ConnectionStates0, ServerHelloExt), State = server_hello(ServerHello, State0#state{expecting_next_protocol_negotiation = - NextProtocolsToSend =/= undefined}), + NextProtocols =/= undefined}), case Type of new -> new_server_hello(ServerHello, State); @@ -1480,7 +1482,7 @@ resumed_server_hello(#state{session = Session, connection_states = ConnectionStates0, negotiated_version = Version} = State0) -> - case tls_handshake:master_secret(Version, Session, + case ssl_handshake:master_secret(tls_record, Version, Session, ConnectionStates0, server) of {_, ConnectionStates1} -> State1 = State0#state{connection_states = ConnectionStates1, @@ -1509,7 +1511,7 @@ handle_resumed_session(SessId, #state{connection_states = ConnectionStates0, session_cache = Cache, session_cache_cb = CacheCb} = State0) -> Session = CacheCb:lookup(Cache, {{Host, Port}, SessId}), - case tls_handshake:master_secret(Version, Session, + case ssl_handshake:master_secret(tls_record, Version, Session, ConnectionStates0, client) of {_, ConnectionStates} -> {Record, State} = @@ -1560,8 +1562,7 @@ server_hello(ServerHello, #state{transport_cb = Transport, Transport:send(Socket, BinMsg), State#state{connection_states = ConnectionStates1, tls_handshake_history = Handshake1, - key_algorithm = KeyAlgorithm, - hashsign_algorithm = default_hashsign(Version, KeyAlgorithm)}. + key_algorithm = KeyAlgorithm}. server_hello_done(#state{transport_cb = Transport, socket = Socket, @@ -1569,7 +1570,7 @@ server_hello_done(#state{transport_cb = Transport, connection_states = ConnectionStates0, tls_handshake_history = Handshake0} = State) -> - HelloDone = tls_handshake:server_hello_done(), + HelloDone = ssl_handshake:server_hello_done(), {BinHelloDone, ConnectionStates, Handshake} = encode_handshake(HelloDone, Version, ConnectionStates0, Handshake0), @@ -1589,7 +1590,7 @@ certify_server(#state{transport_cb = Transport, cert_db = CertDbHandle, cert_db_ref = CertDbRef, session = #session{own_certificate = OwnCert}} = State) -> - case tls_handshake:certificate(OwnCert, CertDbHandle, CertDbRef, server) of + case ssl_handshake:certificate(OwnCert, CertDbHandle, CertDbRef, server) of CertMsg = #certificate{} -> {BinCertMsg, ConnectionStates, Handshake} = encode_handshake(CertMsg, Version, ConnectionStates0, Handshake0), @@ -1618,11 +1619,11 @@ key_exchange(#state{role = server, key_algorithm = Algo, Algo == dh_anon -> DHKeys = public_key:generate_key(Params), ConnectionState = - tls_record:pending_connection_state(ConnectionStates0, read), + ssl_record:pending_connection_state(ConnectionStates0, read), SecParams = ConnectionState#connection_state.security_parameters, #security_parameters{client_random = ClientRandom, server_random = ServerRandom} = SecParams, - Msg = tls_handshake:key_exchange(server, Version, {dh, DHKeys, Params, + Msg = ssl_handshake:key_exchange(server, Version, {dh, DHKeys, Params, HashSignAlgo, ClientRandom, ServerRandom, PrivateKey}), @@ -1643,18 +1644,19 @@ key_exchange(#state{role = server, key_algorithm = Algo, negotiated_version = Version, tls_handshake_history = Handshake0, socket = Socket, - transport_cb = Transport + transport_cb = Transport, + session = #session{ecc = Curve} } = State) when Algo == ecdhe_ecdsa; Algo == ecdhe_rsa; Algo == ecdh_anon -> - ECDHKeys = public_key:generate_key(select_curve(State)), + ECDHKeys = public_key:generate_key(Curve), ConnectionState = - tls_record:pending_connection_state(ConnectionStates0, read), + ssl_record:pending_connection_state(ConnectionStates0, read), SecParams = ConnectionState#connection_state.security_parameters, #security_parameters{client_random = ClientRandom, server_random = ServerRandom} = SecParams, - Msg = tls_handshake:key_exchange(server, Version, {ecdh, ECDHKeys, + Msg = ssl_handshake:key_exchange(server, Version, {ecdh, ECDHKeys, HashSignAlgo, ClientRandom, ServerRandom, PrivateKey}), @@ -1679,11 +1681,11 @@ key_exchange(#state{role = server, key_algorithm = psk, transport_cb = Transport } = State) -> ConnectionState = - tls_record:pending_connection_state(ConnectionStates0, read), + ssl_record:pending_connection_state(ConnectionStates0, read), SecParams = ConnectionState#connection_state.security_parameters, #security_parameters{client_random = ClientRandom, server_random = ServerRandom} = SecParams, - Msg = tls_handshake:key_exchange(server, Version, {psk, PskIdentityHint, + Msg = ssl_handshake:key_exchange(server, Version, {psk, PskIdentityHint, HashSignAlgo, ClientRandom, ServerRandom, PrivateKey}), @@ -1706,11 +1708,11 @@ key_exchange(#state{role = server, key_algorithm = dhe_psk, } = State) -> DHKeys = public_key:generate_key(Params), ConnectionState = - tls_record:pending_connection_state(ConnectionStates0, read), + ssl_record:pending_connection_state(ConnectionStates0, read), SecParams = ConnectionState#connection_state.security_parameters, #security_parameters{client_random = ClientRandom, server_random = ServerRandom} = SecParams, - Msg = tls_handshake:key_exchange(server, Version, {dhe_psk, PskIdentityHint, DHKeys, Params, + Msg = ssl_handshake:key_exchange(server, Version, {dhe_psk, PskIdentityHint, DHKeys, Params, HashSignAlgo, ClientRandom, ServerRandom, PrivateKey}), @@ -1735,11 +1737,11 @@ key_exchange(#state{role = server, key_algorithm = rsa_psk, transport_cb = Transport } = State) -> ConnectionState = - tls_record:pending_connection_state(ConnectionStates0, read), + ssl_record:pending_connection_state(ConnectionStates0, read), SecParams = ConnectionState#connection_state.security_parameters, #security_parameters{client_random = ClientRandom, server_random = ServerRandom} = SecParams, - Msg = tls_handshake:key_exchange(server, Version, {psk, PskIdentityHint, + Msg = ssl_handshake:key_exchange(server, Version, {psk, PskIdentityHint, HashSignAlgo, ClientRandom, ServerRandom, PrivateKey}), @@ -1771,11 +1773,11 @@ key_exchange(#state{role = server, key_algorithm = Algo, Keys0 end, ConnectionState = - tls_record:pending_connection_state(ConnectionStates0, read), + ssl_record:pending_connection_state(ConnectionStates0, read), SecParams = ConnectionState#connection_state.security_parameters, #security_parameters{client_random = ClientRandom, server_random = ServerRandom} = SecParams, - Msg = tls_handshake:key_exchange(server, Version, {srp, Keys, SrpParams, + Msg = ssl_handshake:key_exchange(server, Version, {srp, Keys, SrpParams, HashSignAlgo, ClientRandom, ServerRandom, PrivateKey}), @@ -1811,7 +1813,7 @@ key_exchange(#state{role = client, when Algorithm == dhe_dss; Algorithm == dhe_rsa; Algorithm == dh_anon -> - Msg = tls_handshake:key_exchange(client, Version, {dh, DhPubKey}), + Msg = ssl_handshake:key_exchange(client, Version, {dh, DhPubKey}), {BinMsg, ConnectionStates, Handshake} = encode_handshake(Msg, Version, ConnectionStates0, Handshake0), Transport:send(Socket, BinMsg), @@ -1828,7 +1830,7 @@ key_exchange(#state{role = client, when Algorithm == ecdhe_ecdsa; Algorithm == ecdhe_rsa; Algorithm == ecdh_ecdsa; Algorithm == ecdh_rsa; Algorithm == ecdh_anon -> - Msg = tls_handshake:key_exchange(client, Version, {ecdh, Keys}), + Msg = ssl_handshake:key_exchange(client, Version, {ecdh, Keys}), {BinMsg, ConnectionStates, Handshake} = encode_handshake(Msg, Version, ConnectionStates0, Handshake0), Transport:send(Socket, BinMsg), @@ -1842,7 +1844,7 @@ key_exchange(#state{role = client, negotiated_version = Version, socket = Socket, transport_cb = Transport, tls_handshake_history = Handshake0} = State) -> - Msg = tls_handshake:key_exchange(client, Version, {psk, SslOpts#ssl_options.psk_identity}), + Msg = ssl_handshake:key_exchange(client, Version, {psk, SslOpts#ssl_options.psk_identity}), {BinMsg, ConnectionStates, Handshake} = encode_handshake(Msg, Version, ConnectionStates0, Handshake0), Transport:send(Socket, BinMsg), @@ -1857,7 +1859,7 @@ key_exchange(#state{role = client, diffie_hellman_keys = {DhPubKey, _}, socket = Socket, transport_cb = Transport, tls_handshake_history = Handshake0} = State) -> - Msg = tls_handshake:key_exchange(client, Version, {dhe_psk, SslOpts#ssl_options.psk_identity, DhPubKey}), + Msg = ssl_handshake:key_exchange(client, Version, {dhe_psk, SslOpts#ssl_options.psk_identity, DhPubKey}), {BinMsg, ConnectionStates, Handshake} = encode_handshake(Msg, Version, ConnectionStates0, Handshake0), Transport:send(Socket, BinMsg), @@ -1890,7 +1892,7 @@ key_exchange(#state{role = client, when Algorithm == srp_dss; Algorithm == srp_rsa; Algorithm == srp_anon -> - Msg = tls_handshake:key_exchange(client, Version, {srp, ClientPubKey}), + Msg = ssl_handshake:key_exchange(client, Version, {srp, ClientPubKey}), {BinMsg, ConnectionStates, Handshake} = encode_handshake(Msg, Version, ConnectionStates0, Handshake0), Transport:send(Socket, BinMsg), @@ -1907,7 +1909,7 @@ rsa_key_exchange(Version, PremasterSecret, PublicKeyInfo = {Algorithm, _, _}) Algorithm == ?sha384WithRSAEncryption; Algorithm == ?sha512WithRSAEncryption -> - tls_handshake:key_exchange(client, Version, + ssl_handshake:key_exchange(client, Version, {premaster_secret, PremasterSecret, PublicKeyInfo}); rsa_key_exchange(_, _, _) -> @@ -1923,7 +1925,7 @@ rsa_psk_key_exchange(Version, PskIdentity, PremasterSecret, PublicKeyInfo = {Alg Algorithm == ?sha384WithRSAEncryption; Algorithm == ?sha512WithRSAEncryption -> - tls_handshake:key_exchange(client, Version, + ssl_handshake:key_exchange(client, Version, {psk_premaster_secret, PskIdentity, PremasterSecret, PublicKeyInfo}); rsa_psk_key_exchange(_, _, _, _) -> @@ -1937,7 +1939,11 @@ request_client_cert(#state{ssl_options = #ssl_options{verify = verify_peer}, negotiated_version = Version, socket = Socket, transport_cb = Transport} = State) -> - Msg = tls_handshake:certificate_request(ConnectionStates0, CertDbHandle, CertDbRef), + #connection_state{security_parameters = + #security_parameters{cipher_suite = CipherSuite}} = + ssl_record:pending_connection_state(ConnectionStates0, read), + Msg = ssl_handshake:certificate_request(CipherSuite, CertDbHandle, CertDbRef, Version), + {BinMsg, ConnectionStates, Handshake} = encode_handshake(Msg, Version, ConnectionStates0, Handshake0), Transport:send(Socket, BinMsg), @@ -1952,7 +1958,7 @@ finalize_handshake(State, StateName) -> ConnectionStates0 = cipher_protocol(State), ConnectionStates = - tls_record:activate_pending_connection_state(ConnectionStates0, + ssl_record:activate_pending_connection_state(ConnectionStates0, write), State1 = State#state{connection_states = ConnectionStates}, @@ -1970,7 +1976,7 @@ next_protocol(#state{transport_cb = Transport, socket = Socket, next_protocol = NextProtocol, connection_states = ConnectionStates0, tls_handshake_history = Handshake0} = State) -> - NextProtocolMessage = tls_handshake:next_protocol(NextProtocol), + NextProtocolMessage = ssl_handshake:next_protocol(NextProtocol), {BinMsg, ConnectionStates, Handshake} = encode_handshake(NextProtocolMessage, Version, ConnectionStates0, Handshake0), Transport:send(Socket, BinMsg), State#state{connection_states = ConnectionStates, @@ -1992,7 +1998,7 @@ finished(#state{role = Role, socket = Socket, negotiated_version = Version, connection_states = ConnectionStates0, tls_handshake_history = Handshake0}, StateName) -> MasterSecret = Session#session.master_secret, - Finished = tls_handshake:finished(Version, Role, + Finished = ssl_handshake:finished(Version, Role, get_current_connection_state_prf(ConnectionStates0, write), MasterSecret, Handshake0), ConnectionStates1 = save_verify_data(Role, Finished, ConnectionStates0, StateName), @@ -2002,24 +2008,26 @@ finished(#state{role = Role, socket = Socket, negotiated_version = Version, {ConnectionStates, Handshake}. save_verify_data(client, #finished{verify_data = Data}, ConnectionStates, certify) -> - tls_record:set_client_verify_data(current_write, Data, ConnectionStates); + ssl_record:set_client_verify_data(current_write, Data, ConnectionStates); save_verify_data(server, #finished{verify_data = Data}, ConnectionStates, cipher) -> - tls_record:set_server_verify_data(current_both, Data, ConnectionStates); + ssl_record:set_server_verify_data(current_both, Data, ConnectionStates); save_verify_data(client, #finished{verify_data = Data}, ConnectionStates, abbreviated) -> - tls_record:set_client_verify_data(current_both, Data, ConnectionStates); + ssl_record:set_client_verify_data(current_both, Data, ConnectionStates); save_verify_data(server, #finished{verify_data = Data}, ConnectionStates, abbreviated) -> - tls_record:set_server_verify_data(current_write, Data, ConnectionStates). + ssl_record:set_server_verify_data(current_write, Data, ConnectionStates). handle_server_key(#server_key_exchange{exchange_keys = Keys}, #state{key_algorithm = KeyAlg, negotiated_version = Version} = State) -> - Params = tls_handshake:decode_server_key(Keys, KeyAlg, Version), - HashSign = connection_hashsign(Params#server_key_params.hashsign, State), - case HashSign of - {_, SignAlgo} when SignAlgo == anon; SignAlgo == ecdh_anon -> - server_master_secret(Params#server_key_params.params, State); - _ -> - verify_server_key(Params, HashSign, State) + + Params = ssl_handshake:decode_server_key(Keys, KeyAlg, Version), + HashSign = negotiated_hashsign(Params#server_key_params.hashsign, KeyAlg, Version), + case is_anonymous(KeyAlg) of + true -> + server_master_secret(Params#server_key_params.params, + State#state{hashsign_algorithm = HashSign}); + false -> + verify_server_key(Params, HashSign, State#state{hashsign_algorithm = HashSign}) end. verify_server_key(#server_key_params{params = Params, @@ -2030,15 +2038,15 @@ verify_server_key(#server_key_params{params = Params, public_key_info = PubKeyInfo, connection_states = ConnectionStates} = State) -> ConnectionState = - tls_record:pending_connection_state(ConnectionStates, read), + ssl_record:pending_connection_state(ConnectionStates, read), SecParams = ConnectionState#connection_state.security_parameters, #security_parameters{client_random = ClientRandom, server_random = ServerRandom} = SecParams, - Hash = tls_handshake:server_key_exchange_hash(HashAlgo, + Hash = ssl_handshake:server_key_exchange_hash(HashAlgo, <<ClientRandom/binary, ServerRandom/binary, EncParams/binary>>), - case tls_handshake:verify_signature(Version, Hash, HashSign, Signature, PubKeyInfo) of + case ssl_handshake:verify_signature(Version, Hash, HashSign, Signature, PubKeyInfo) of true -> server_master_secret(Params, State); false -> @@ -2074,7 +2082,7 @@ master_from_premaster_secret(PremasterSecret, #state{session = Session, negotiated_version = Version, role = Role, connection_states = ConnectionStates0} = State) -> - case tls_handshake:master_secret(Version, PremasterSecret, + case ssl_handshake:master_secret(tls_record, Version, PremasterSecret, ConnectionStates0, Role) of {MasterSecret, ConnectionStates} -> State#state{ @@ -2227,12 +2235,12 @@ client_srp_master_secret(Generator, Prime, Salt, ServerPub, ClientKeys, end. cipher_role(client, Data, Session, #state{connection_states = ConnectionStates0} = State) -> - ConnectionStates = tls_record:set_server_verify_data(current_both, Data, ConnectionStates0), + ConnectionStates = ssl_record:set_server_verify_data(current_both, Data, ConnectionStates0), next_state_connection(cipher, ack_connection(State#state{session = Session, connection_states = ConnectionStates})); cipher_role(server, Data, Session, #state{connection_states = ConnectionStates0} = State) -> - ConnectionStates1 = tls_record:set_client_verify_data(current_read, Data, ConnectionStates0), + ConnectionStates1 = ssl_record:set_client_verify_data(current_read, Data, ConnectionStates0), {ConnectionStates, Handshake} = finalize_handshake(State#state{connection_states = ConnectionStates1, session = Session}, cipher), @@ -2242,16 +2250,16 @@ cipher_role(server, Data, Session, #state{connection_states = ConnectionStates0 tls_handshake_history = Handshake})). encode_alert(#alert{} = Alert, Version, ConnectionStates) -> - tls_record:encode_alert_record(Alert, Version, ConnectionStates). + ssl_record:encode_alert_record(Alert, Version, ConnectionStates). encode_change_cipher(#change_cipher_spec{}, Version, ConnectionStates) -> - tls_record:encode_change_cipher_spec(Version, ConnectionStates). + ssl_record:encode_change_cipher_spec(Version, ConnectionStates). encode_handshake(HandshakeRec, Version, ConnectionStates0, Handshake0) -> Frag = tls_handshake:encode_handshake(HandshakeRec, Version), Handshake1 = tls_handshake:update_handshake_history(Handshake0, Frag), {E, ConnectionStates1} = - tls_record:encode_handshake(Frag, Version, ConnectionStates0), + ssl_record:encode_handshake(Frag, Version, ConnectionStates0), {E, ConnectionStates1, Handshake1}. encode_packet(Data, #socket_options{packet=Packet}) -> @@ -2346,7 +2354,7 @@ write_application_data(Data0, From, #state{socket = Socket, renegotiate(State#state{send_queue = queue:in_r({From, Data}, SendQueue), renegotiation = {true, internal}}); false -> - {Msgs, ConnectionStates} = tls_record:encode_data(Data, Version, ConnectionStates0), + {Msgs, ConnectionStates} = ssl_record:encode_data(Data, Version, ConnectionStates0), Result = Transport:send(Socket, Msgs), {reply, Result, connection, State#state{connection_states = ConnectionStates}, get_timeout(State)} @@ -2551,7 +2559,7 @@ next_state(Current, Next, #ssl_tls{type = ?CHANGE_CIPHER_SPEC, fragment = <<1>>} _ChangeCipher, #state{connection_states = ConnectionStates0} = State0) -> ConnectionStates1 = - tls_record:activate_pending_connection_state(ConnectionStates0, read), + ssl_record:activate_pending_connection_state(ConnectionStates0, read), {Record, State} = next_record(State0#state{connection_states = ConnectionStates1}), next_state(Current, Next, Record, State); next_state(Current, Next, #ssl_tls{type = _Unknown}, State0) -> @@ -2603,7 +2611,7 @@ next_state_connection(StateName, #state{send_queue = Queue0, case queue:out(Queue0) of {{value, {From, Data}}, Queue} -> {Msgs, ConnectionStates} = - tls_record:encode_data(Data, Version, ConnectionStates0), + ssl_record:encode_data(Data, Version, ConnectionStates0), Result = Transport:send(Socket, Msgs), gen_fsm:reply(From, Result), next_state_connection(StateName, @@ -2648,7 +2656,7 @@ invalidate_session(server, _, Port, Session) -> initial_state(Role, Host, Port, Socket, {SSLOptions, SocketOptions}, User, {CbModule, DataTag, CloseTag, ErrorTag}) -> - ConnectionStates = tls_record:init_connection_states(Role), + ConnectionStates = ssl_record:init_connection_states(Role), SessionCacheCb = case application:get_env(ssl, session_cb) of {ok, Cb} when is_atom(Cb) -> @@ -2910,11 +2918,11 @@ renegotiate(#state{role = server, transport_cb = Transport, negotiated_version = Version, connection_states = ConnectionStates0} = State0) -> - HelloRequest = tls_handshake:hello_request(), + HelloRequest = ssl_handshake:hello_request(), Frag = tls_handshake:encode_handshake(HelloRequest, Version), Hs0 = tls_handshake:init_handshake_history(), {BinMsg, ConnectionStates} = - tls_record:encode_handshake(Frag, Version, ConnectionStates0), + ssl_record:encode_handshake(Frag, Version, ConnectionStates0), Transport:send(Socket, BinMsg), {Record, State} = next_record(State0#state{connection_states = ConnectionStates, @@ -2989,15 +2997,43 @@ handle_trusted_certs_db(#state{cert_db_ref = Ref, end. get_current_connection_state_prf(CStates, Direction) -> - CS = tls_record:current_connection_state(CStates, Direction), + CS = ssl_record:current_connection_state(CStates, Direction), CS#connection_state.security_parameters#security_parameters.prf_algorithm. get_pending_connection_state_prf(CStates, Direction) -> - CS = tls_record:pending_connection_state(CStates, Direction), + CS = ssl_record:pending_connection_state(CStates, Direction), CS#connection_state.security_parameters#security_parameters.prf_algorithm. -connection_hashsign(HashSign = {_, _}, _State) -> - HashSign; -connection_hashsign(_, #state{hashsign_algorithm = HashSign}) -> +start_or_recv_cancel_timer(infinity, _RecvFrom) -> + undefined; +start_or_recv_cancel_timer(Timeout, RecvFrom) -> + erlang:send_after(Timeout, self(), {cancel_start_or_recv, RecvFrom}). + +cancel_timer(undefined) -> + ok; +cancel_timer(Timer) -> + erlang:cancel_timer(Timer), + ok. + +handle_unrecv_data(StateName, #state{socket = Socket, transport_cb = Transport} = State) -> + ssl_socket:setopts(Transport, Socket, [{active, false}]), + case Transport:recv(Socket, 0, 0) of + {error, closed} -> + ok; + {ok, Data} -> + handle_close_alert(Data, StateName, State) + end. + +handle_close_alert(Data, StateName, State0) -> + case next_tls_record(Data, State0) of + {#ssl_tls{type = ?ALERT, fragment = EncAlerts}, State} -> + [Alert|_] = decode_alerts(EncAlerts), + handle_normal_shutdown(Alert, StateName, State); + _ -> + ok + end. +negotiated_hashsign(undefined, Algo, Version) -> + default_hashsign(Version, Algo); +negotiated_hashsign(HashSign = {_, _}, _, _) -> HashSign. %% RFC 5246, Sect. 7.4.1.4.1. Signature Algorithms @@ -3015,11 +3051,12 @@ connection_hashsign(_, #state{hashsign_algorithm = HashSign}) -> %% ECDHE_ECDSA), behave as if the client had sent value {sha1,ecdsa}. default_hashsign(_Version = {Major, Minor}, KeyExchange) - when Major == 3 andalso Minor >= 3 andalso + when Major >= 3 andalso Minor >= 3 andalso (KeyExchange == rsa orelse KeyExchange == dhe_rsa orelse KeyExchange == dh_rsa orelse KeyExchange == ecdhe_rsa orelse + KeyExchange == ecdh_rsa orelse KeyExchange == srp_rsa) -> {sha, rsa}; default_hashsign(_Version, KeyExchange) @@ -3027,12 +3064,12 @@ default_hashsign(_Version, KeyExchange) KeyExchange == dhe_rsa; KeyExchange == dh_rsa; KeyExchange == ecdhe_rsa; + KeyExchange == ecdh_rsa; KeyExchange == srp_rsa -> {md5sha, rsa}; default_hashsign(_Version, KeyExchange) when KeyExchange == ecdhe_ecdsa; - KeyExchange == ecdh_ecdsa; - KeyExchange == ecdh_rsa -> + KeyExchange == ecdh_ecdsa -> {sha, ecdsa}; default_hashsign(_Version, KeyExchange) when KeyExchange == dhe_dss; @@ -3047,37 +3084,13 @@ default_hashsign(_Version, KeyExchange) KeyExchange == rsa_psk; KeyExchange == srp_anon -> {null, anon}. - -start_or_recv_cancel_timer(infinity, _RecvFrom) -> - undefined; -start_or_recv_cancel_timer(Timeout, RecvFrom) -> - erlang:send_after(Timeout, self(), {cancel_start_or_recv, RecvFrom}). - -cancel_timer(undefined) -> - ok; -cancel_timer(Timer) -> - erlang:cancel_timer(Timer), - ok. - -handle_unrecv_data(StateName, #state{socket = Socket, transport_cb = Transport} = State) -> - ssl_socket:setopts(Transport, Socket, [{active, false}]), - case Transport:recv(Socket, 0, 0) of - {error, closed} -> - ok; - {ok, Data} -> - handle_close_alert(Data, StateName, State) - end. - -handle_close_alert(Data, StateName, State0) -> - case next_tls_record(Data, State0) of - {#ssl_tls{type = ?ALERT, fragment = EncAlerts}, State} -> - [Alert|_] = decode_alerts(EncAlerts), - handle_normal_shutdown(Alert, StateName, State); - _ -> - ok - end. - -select_curve(#state{client_ecc = {[Curve|_], _}}) -> - {namedCurve, Curve}; -select_curve(_) -> - {namedCurve, ?secp256k1}. + +is_anonymous(Algo) when Algo == dh_anon; + Algo == ecdh_anon; + Algo == psk; + Algo == dhe_psk; + Algo == rsa_psk; + Algo == srp_anon -> + true; +is_anonymous(_) -> + false. diff --git a/lib/ssl/src/tls_handshake.erl b/lib/ssl/src/tls_handshake.erl index 51fd2e1dc9..ecbca83e10 100644 --- a/lib/ssl/src/tls_handshake.erl +++ b/lib/ssl/src/tls_handshake.erl @@ -18,7 +18,8 @@ %% %%---------------------------------------------------------------------- -%% Purpose: Help funtions for handling the SSL-handshake protocol +%% Purpose: Help funtions for handling the TLS (specific parts of) +%%% SSL/TLS/DTLS handshake protocol %%---------------------------------------------------------------------- -module(tls_handshake). @@ -31,23 +32,9 @@ -include("ssl_srp.hrl"). -include_lib("public_key/include/public_key.hrl"). --export([master_secret/4, client_hello/8, server_hello/7, hello/4, - hello_request/0, certify/7, certificate/4, - client_certificate_verify/6, certificate_verify/6, verify_signature/5, - certificate_request/3, key_exchange/3, server_key_exchange_hash/2, - finished/5, verify_connection/6, get_tls_handshake/3, - decode_client_key/3, decode_server_key/3, server_hello_done/0, - encode_handshake/2, init_handshake_history/0, update_handshake_history/2, - decrypt_premaster_secret/2, prf/5, next_protocol/1]). - --export([dec_hello_extensions/2]). - --type tls_handshake() :: #client_hello{} | #server_hello{} | - #server_hello_done{} | #certificate{} | #certificate_request{} | - #client_key_exchange{} | #finished{} | #certificate_verify{} | - #hello_request{} | #next_protocol{}. - --define(NAMED_CURVE_TYPE, 3). +-export([client_hello/8, server_hello/4, hello/4, + get_tls_handshake/3, encode_handshake/2, decode_handshake/3, + init_handshake_history/0, update_handshake_history/2]). %%==================================================================== %% Internal application API @@ -65,517 +52,104 @@ client_hello(Host, Port, ConnectionStates, } = SslOpts, Cache, CacheCb, Renegotiation, OwnCert) -> Version = tls_record:highest_protocol_version(Versions), - Pending = tls_record:pending_connection_state(ConnectionStates, read), + Pending = ssl_record:pending_connection_state(ConnectionStates, read), SecParams = Pending#connection_state.security_parameters, - Ciphers = available_suites(UserSuites, Version), - SRP = srp_user(SslOpts), - {EcPointFormats, EllipticCurves} = default_ecc_extensions(Version), + CipherSuites = ssl_handshake:available_suites(UserSuites, Version), + + Extensions = ssl_handshake:client_hello_extensions(Version, CipherSuites, + SslOpts, ConnectionStates, Renegotiation), Id = ssl_session:client_id({Host, Port, SslOpts}, Cache, CacheCb, OwnCert), #client_hello{session_id = Id, client_version = Version, - cipher_suites = cipher_suites(Ciphers, Renegotiation), - compression_methods = tls_record:compressions(), + cipher_suites = ssl_handshake:cipher_suites(CipherSuites, Renegotiation), + compression_methods = ssl_record:compressions(), random = SecParams#security_parameters.client_random, - - renegotiation_info = - renegotiation_info(client, ConnectionStates, Renegotiation), - srp = SRP, - hash_signs = default_hash_signs(), - ec_point_formats = EcPointFormats, - elliptic_curves = EllipticCurves, - next_protocol_negotiation = - encode_client_protocol_negotiation(SslOpts#ssl_options.next_protocol_selector, Renegotiation) + extensions = Extensions }. -encode_protocol(Protocol, Acc) -> - Len = byte_size(Protocol), - <<Acc/binary, ?BYTE(Len), Protocol/binary>>. - -encode_protocols_advertised_on_server(undefined) -> - undefined; - -encode_protocols_advertised_on_server(Protocols) -> - #next_protocol_negotiation{extension_data = lists:foldl(fun encode_protocol/2, <<>>, Protocols)}. - %%-------------------------------------------------------------------- --spec server_hello(session_id(), tls_version(), #connection_states{}, - boolean(), [binary()] | undefined, - #ec_point_formats{} | undefined, - #elliptic_curves{} | undefined) -> #server_hello{}. +-spec server_hello(binary(), tls_version(), #connection_states{}, + #hello_extensions{}) -> #server_hello{}. %% %% Description: Creates a server hello message. %%-------------------------------------------------------------------- -server_hello(SessionId, Version, ConnectionStates, Renegotiation, - ProtocolsAdvertisedOnServer, EcPointFormats, EllipticCurves) -> - Pending = tls_record:pending_connection_state(ConnectionStates, read), +server_hello(SessionId, Version, ConnectionStates, Extensions) -> + Pending = ssl_record:pending_connection_state(ConnectionStates, read), SecParams = Pending#connection_state.security_parameters, + #server_hello{server_version = Version, cipher_suite = SecParams#security_parameters.cipher_suite, compression_method = SecParams#security_parameters.compression_algorithm, random = SecParams#security_parameters.server_random, session_id = SessionId, - renegotiation_info = - renegotiation_info(server, ConnectionStates, Renegotiation), - ec_point_formats = EcPointFormats, - elliptic_curves = EllipticCurves, - next_protocol_negotiation = encode_protocols_advertised_on_server(ProtocolsAdvertisedOnServer) + extensions = Extensions }. %%-------------------------------------------------------------------- --spec hello_request() -> #hello_request{}. -%% -%% Description: Creates a hello request message sent by server to -%% trigger renegotiation. -%%-------------------------------------------------------------------- -hello_request() -> - #hello_request{}. - -%%-------------------------------------------------------------------- -spec hello(#server_hello{} | #client_hello{}, #ssl_options{}, #connection_states{} | {inet:port_number(), #session{}, db_handle(), - atom(), #connection_states{}, binary()}, + atom(), #connection_states{}, binary() | undefined}, boolean()) -> {tls_version(), session_id(), #connection_states{}, binary() | undefined}| - {tls_version(), {resumed | new, #session{}}, #connection_states{}, [binary()] | undefined, + {tls_version(), {resumed | new, #session{}}, #connection_states{}, + [binary()] | undefined, [oid()] | undefined, [oid()] | undefined} | #alert{}. %% %% Description: Handles a recieved hello message %%-------------------------------------------------------------------- -hello(#server_hello{cipher_suite = CipherSuite, server_version = Version, - compression_method = Compression, random = Random, - session_id = SessionId, renegotiation_info = Info, - hash_signs = _HashSigns} = Hello, - #ssl_options{secure_renegotiate = SecureRenegotation, next_protocol_selector = NextProtocolSelector, - versions = SupportedVersions}, +hello(#server_hello{server_version = Version, random = Random, + cipher_suite = CipherSuite, + compression_method = Compression, + session_id = SessionId, extensions = HelloExt}, + #ssl_options{versions = SupportedVersions} = SslOpt, ConnectionStates0, Renegotiation) -> - %%TODO: select hash and signature algorigthm case tls_record:is_acceptable_version(Version, SupportedVersions) of true -> - case handle_renegotiation_info(client, Info, ConnectionStates0, - Renegotiation, SecureRenegotation, []) of - {ok, ConnectionStates1} -> - ConnectionStates = - hello_pending_connection_states(client, Version, CipherSuite, Random, - Compression, ConnectionStates1), - case handle_next_protocol(Hello, NextProtocolSelector, Renegotiation) of - #alert{} = Alert -> - Alert; - Protocol -> - {Version, SessionId, ConnectionStates, Protocol} - end; - #alert{} = Alert -> - Alert - end; + handle_hello_extensions(Version, SessionId, Random, CipherSuite, + Compression, HelloExt, SslOpt, ConnectionStates0, Renegotiation); false -> ?ALERT_REC(?FATAL, ?PROTOCOL_VERSION) end; -hello(#client_hello{client_version = ClientVersion} = Hello, +hello(#client_hello{client_version = ClientVersion, + session_id = SugesstedId, + cipher_suites = CipherSuites, + compression_methods = Compressions, + random = Random, + extensions = #hello_extensions{elliptic_curves = Curves} = HelloExt}, #ssl_options{versions = Versions} = SslOpts, {Port, Session0, Cache, CacheCb, ConnectionStates0, Cert}, Renegotiation) -> - %% TODO: select hash and signature algorithm - Version = select_version(ClientVersion, Versions), + Version = ssl_handshake:select_version(tls_record, ClientVersion, Versions), case tls_record:is_acceptable_version(Version, Versions) of true -> - %% TODO: need to take supported Curves into Account when selecting the CipherSuite.... - %% if whe have an ECDSA cert with an unsupported curve, we need to drop ECDSA ciphers + ECCCurve = ssl_handshake:select_curve(Curves, ssl_handshake:supported_ecc(Version)), {Type, #session{cipher_suite = CipherSuite} = Session1} - = select_session(Hello, Port, Session0, Version, - SslOpts, Cache, CacheCb, Cert), + = ssl_handshake:select_session(SugesstedId, CipherSuites, Compressions, + Port, Session0#session{ecc = ECCCurve}, Version, + SslOpts, Cache, CacheCb, Cert), case CipherSuite of no_suite -> ?ALERT_REC(?FATAL, ?INSUFFICIENT_SECURITY); _ -> - try handle_hello_extensions(Hello, Version, SslOpts, Session1, ConnectionStates0, Renegotiation) of - {Session, ConnectionStates, ProtocolsToAdvertise, ECPointFormats, EllipticCurves} -> - {Version, {Type, Session}, ConnectionStates, - ProtocolsToAdvertise, ECPointFormats, EllipticCurves} - catch throw:Alert -> - Alert - end + handle_hello_extensions(Version, Type, Random, HelloExt, + SslOpts, Session1, ConnectionStates0, + Renegotiation) end; false -> ?ALERT_REC(?FATAL, ?PROTOCOL_VERSION) end. %%-------------------------------------------------------------------- --spec certify(#certificate{}, db_handle(), certdb_ref(), integer() | nolimit, - verify_peer | verify_none, {fun(), term}, - client | server) -> {der_cert(), public_key_info()} | #alert{}. -%% -%% Description: Handles a certificate handshake message -%%-------------------------------------------------------------------- -certify(#certificate{asn1_certificates = ASN1Certs}, CertDbHandle, CertDbRef, - MaxPathLen, _Verify, VerifyFunAndState, Role) -> - [PeerCert | _] = ASN1Certs, - - ValidationFunAndState = - case VerifyFunAndState of - undefined -> - {fun(OtpCert, ExtensionOrVerifyResult, SslState) -> - ssl_certificate:validate_extension(OtpCert, - ExtensionOrVerifyResult, SslState) - end, Role}; - {Fun, UserState0} -> - {fun(OtpCert, {extension, _} = Extension, {SslState, UserState}) -> - case ssl_certificate:validate_extension(OtpCert, - Extension, - SslState) of - {valid, NewSslState} -> - {valid, {NewSslState, UserState}}; - {fail, Reason} -> - apply_user_fun(Fun, OtpCert, Reason, UserState, - SslState); - {unknown, _} -> - apply_user_fun(Fun, OtpCert, - Extension, UserState, SslState) - end; - (OtpCert, VerifyResult, {SslState, UserState}) -> - apply_user_fun(Fun, OtpCert, VerifyResult, UserState, - SslState) - end, {Role, UserState0}} - end, - - try - {TrustedErlCert, CertPath} = - ssl_certificate:trusted_cert_and_path(ASN1Certs, CertDbHandle, CertDbRef), - case public_key:pkix_path_validation(TrustedErlCert, - CertPath, - [{max_path_length, - MaxPathLen}, - {verify_fun, ValidationFunAndState}]) of - {ok, {PublicKeyInfo,_}} -> - {PeerCert, PublicKeyInfo}; - {error, Reason} -> - path_validation_alert(Reason) - end - catch - error:_ -> - %% ASN-1 decode of certificate somehow failed - ?ALERT_REC(?FATAL, ?CERTIFICATE_UNKNOWN) - end. - -%%-------------------------------------------------------------------- --spec certificate(der_cert(), db_handle(), certdb_ref(), client | server) -> #certificate{} | #alert{}. -%% -%% Description: Creates a certificate message. -%%-------------------------------------------------------------------- -certificate(OwnCert, CertDbHandle, CertDbRef, client) -> - Chain = - case ssl_certificate:certificate_chain(OwnCert, CertDbHandle, CertDbRef) of - {ok, CertChain} -> - CertChain; - {error, _} -> - %% If no suitable certificate is available, the client - %% SHOULD send a certificate message containing no - %% certificates. (chapter 7.4.6. RFC 4346) - [] - end, - #certificate{asn1_certificates = Chain}; - -certificate(OwnCert, CertDbHandle, CertDbRef, server) -> - case ssl_certificate:certificate_chain(OwnCert, CertDbHandle, CertDbRef) of - {ok, Chain} -> - #certificate{asn1_certificates = Chain}; - {error, _} -> - ?ALERT_REC(?FATAL, ?INTERNAL_ERROR) - end. - -%%-------------------------------------------------------------------- --spec client_certificate_verify(undefined | der_cert(), binary(), - tls_version(), term(), private_key(), - tls_handshake_history()) -> - #certificate_verify{} | ignore | #alert{}. -%% -%% Description: Creates a certificate_verify message, called by the client. -%%-------------------------------------------------------------------- -client_certificate_verify(undefined, _, _, _, _, _) -> - ignore; -client_certificate_verify(_, _, _, _, undefined, _) -> - ignore; -client_certificate_verify(OwnCert, MasterSecret, Version, - {HashAlgo, SignAlgo}, - PrivateKey, {Handshake, _}) -> - case public_key:pkix_is_fixed_dh_cert(OwnCert) of - true -> - ?ALERT_REC(?FATAL, ?UNSUPPORTED_CERTIFICATE); - false -> - Hashes = - calc_certificate_verify(Version, HashAlgo, MasterSecret, Handshake), - Signed = digitally_signed(Version, Hashes, HashAlgo, PrivateKey), - #certificate_verify{signature = Signed, hashsign_algorithm = {HashAlgo, SignAlgo}} - end. - -%%-------------------------------------------------------------------- --spec certificate_verify(binary(), public_key_info(), tls_version(), term(), - binary(), tls_handshake_history()) -> valid | #alert{}. -%% -%% Description: Checks that the certificate_verify message is valid. -%%-------------------------------------------------------------------- -certificate_verify(Signature, PublicKeyInfo, Version, - HashSign = {HashAlgo, _}, MasterSecret, {_, Handshake}) -> - Hash = calc_certificate_verify(Version, HashAlgo, MasterSecret, Handshake), - case verify_signature(Version, Hash, HashSign, Signature, PublicKeyInfo) of - true -> - valid; - _ -> - ?ALERT_REC(?FATAL, ?BAD_CERTIFICATE) - end. - -%%-------------------------------------------------------------------- --spec verify_signature(tls_version(), binary(), {term(), term()}, binary(), - public_key_info()) -> true | false. -%% -%% Description: Checks that a public_key signature is valid. -%%-------------------------------------------------------------------- -verify_signature(_Version, _Hash, {_HashAlgo, anon}, _Signature, _) -> - true; -verify_signature({3, Minor}, Hash, {HashAlgo, rsa}, Signature, {?rsaEncryption, PubKey, _PubKeyParams}) - when Minor >= 3 -> - public_key:verify({digest, Hash}, HashAlgo, Signature, PubKey); -verify_signature(_Version, Hash, _HashAlgo, Signature, {?rsaEncryption, PubKey, _PubKeyParams}) -> - case public_key:decrypt_public(Signature, PubKey, - [{rsa_pad, rsa_pkcs1_padding}]) of - Hash -> true; - _ -> false - end; -verify_signature(_Version, Hash, {HashAlgo, dsa}, Signature, {?'id-dsa', PublicKey, PublicKeyParams}) -> - public_key:verify({digest, Hash}, HashAlgo, Signature, {PublicKey, PublicKeyParams}); -verify_signature(_Version, Hash, {HashAlgo, ecdsa}, Signature, {?'id-ecPublicKey', PublicKey, PublicKeyParams}) -> - public_key:verify({digest, Hash}, HashAlgo, Signature, {PublicKey, PublicKeyParams}). - -%%-------------------------------------------------------------------- --spec certificate_request(#connection_states{}, db_handle(), certdb_ref()) -> - #certificate_request{}. -%% -%% Description: Creates a certificate_request message, called by the server. -%%-------------------------------------------------------------------- -certificate_request(ConnectionStates, CertDbHandle, CertDbRef) -> - #connection_state{security_parameters = - #security_parameters{cipher_suite = CipherSuite}} = - tls_record:pending_connection_state(ConnectionStates, read), - Types = certificate_types(CipherSuite), - HashSigns = default_hash_signs(), - Authorities = certificate_authorities(CertDbHandle, CertDbRef), - #certificate_request{ - certificate_types = Types, - hashsign_algorithms = HashSigns, - certificate_authorities = Authorities - }. - -%%-------------------------------------------------------------------- --spec key_exchange(client | server, tls_version(), - {premaster_secret, binary(), public_key_info()} | - {dh, binary()} | - {dh, {binary(), binary()}, #'DHParameter'{}, {HashAlgo::atom(), SignAlgo::atom()}, - binary(), binary(), private_key()} | - {ecdh, #'ECPrivateKey'{}} | - {psk, binary()} | - {dhe_psk, binary(), binary()} | - {srp, {binary(), binary()}, #srp_user{}, {HashAlgo::atom(), SignAlgo::atom()}, - binary(), binary(), private_key()}) -> - #client_key_exchange{} | #server_key_exchange{}. -%% -%% Description: Creates a keyexchange message. -%%-------------------------------------------------------------------- -key_exchange(client, _Version, {premaster_secret, Secret, {_, PublicKey, _}}) -> - EncPremasterSecret = - encrypted_premaster_secret(Secret, PublicKey), - #client_key_exchange{exchange_keys = EncPremasterSecret}; - -key_exchange(client, _Version, {dh, PublicKey}) -> - #client_key_exchange{ - exchange_keys = #client_diffie_hellman_public{ - dh_public = PublicKey} - }; - -key_exchange(client, _Version, {ecdh, #'ECPrivateKey'{publicKey = {0, ECPublicKey}}}) -> - #client_key_exchange{ - exchange_keys = #client_ec_diffie_hellman_public{ - dh_public = ECPublicKey} - }; - -key_exchange(client, _Version, {psk, Identity}) -> - #client_key_exchange{ - exchange_keys = #client_psk_identity{ - identity = Identity} - }; - -key_exchange(client, _Version, {dhe_psk, Identity, PublicKey}) -> - #client_key_exchange{ - exchange_keys = #client_dhe_psk_identity{ - identity = Identity, - dh_public = PublicKey} - }; - -key_exchange(client, _Version, {psk_premaster_secret, PskIdentity, Secret, {_, PublicKey, _}}) -> - EncPremasterSecret = - encrypted_premaster_secret(Secret, PublicKey), - #client_key_exchange{ - exchange_keys = #client_rsa_psk_identity{ - identity = PskIdentity, - exchange_keys = EncPremasterSecret}}; - -key_exchange(client, _Version, {srp, PublicKey}) -> - #client_key_exchange{ - exchange_keys = #client_srp_public{ - srp_a = PublicKey} - }; - -key_exchange(server, Version, {dh, {PublicKey, _}, - #'DHParameter'{prime = P, base = G}, - HashSign, ClientRandom, ServerRandom, PrivateKey}) -> - ServerDHParams = #server_dh_params{dh_p = int_to_bin(P), - dh_g = int_to_bin(G), dh_y = PublicKey}, - enc_server_key_exchange(Version, ServerDHParams, HashSign, - ClientRandom, ServerRandom, PrivateKey); - -key_exchange(server, Version, {ecdh, #'ECPrivateKey'{publicKey = {0, ECPublicKey}, - parameters = ECCurve}, HashSign, ClientRandom, ServerRandom, - PrivateKey}) -> - ServerECParams = #server_ecdh_params{curve = ECCurve, public = ECPublicKey}, - enc_server_key_exchange(Version, ServerECParams, HashSign, - ClientRandom, ServerRandom, PrivateKey); - -key_exchange(server, Version, {psk, PskIdentityHint, - HashSign, ClientRandom, ServerRandom, PrivateKey}) -> - ServerPSKParams = #server_psk_params{hint = PskIdentityHint}, - enc_server_key_exchange(Version, ServerPSKParams, HashSign, - ClientRandom, ServerRandom, PrivateKey); - -key_exchange(server, Version, {dhe_psk, PskIdentityHint, {PublicKey, _}, - #'DHParameter'{prime = P, base = G}, - HashSign, ClientRandom, ServerRandom, PrivateKey}) -> - ServerEDHPSKParams = #server_dhe_psk_params{ - hint = PskIdentityHint, - dh_params = #server_dh_params{dh_p = int_to_bin(P), - dh_g = int_to_bin(G), dh_y = PublicKey} - }, - enc_server_key_exchange(Version, ServerEDHPSKParams, - HashSign, ClientRandom, ServerRandom, PrivateKey); - -key_exchange(server, Version, {srp, {PublicKey, _}, - #srp_user{generator = Generator, prime = Prime, - salt = Salt}, - HashSign, ClientRandom, ServerRandom, PrivateKey}) -> - ServerSRPParams = #server_srp_params{srp_n = Prime, srp_g = Generator, - srp_s = Salt, srp_b = PublicKey}, - enc_server_key_exchange(Version, ServerSRPParams, HashSign, - ClientRandom, ServerRandom, PrivateKey). - -enc_server_key_exchange(Version, Params, {HashAlgo, SignAlgo}, - ClientRandom, ServerRandom, PrivateKey) -> - EncParams = enc_server_key(Params), - case HashAlgo of - null -> - #server_key_params{params = Params, - params_bin = EncParams, - hashsign = {null, anon}, - signature = <<>>}; - _ -> - Hash = - server_key_exchange_hash(HashAlgo, <<ClientRandom/binary, - ServerRandom/binary, - EncParams/binary>>), - Signature = digitally_signed(Version, Hash, HashAlgo, PrivateKey), - #server_key_params{params = Params, - params_bin = EncParams, - hashsign = {HashAlgo, SignAlgo}, - signature = Signature} - end. - -%%-------------------------------------------------------------------- --spec master_secret(tls_version(), #session{} | binary(), #connection_states{}, - client | server) -> {binary(), #connection_states{}} | #alert{}. -%% -%% Description: Sets or calculates the master secret and calculate keys, -%% updating the pending connection states. The Mastersecret and the update -%% connection states are returned or an alert if the calculation fails. -%%------------------------------------------------------------------- -master_secret(Version, #session{master_secret = Mastersecret}, - ConnectionStates, Role) -> - ConnectionState = - tls_record:pending_connection_state(ConnectionStates, read), - SecParams = ConnectionState#connection_state.security_parameters, - try master_secret(Version, Mastersecret, SecParams, - ConnectionStates, Role) - catch - exit:Reason -> - Report = io_lib:format("Key calculation failed due to ~p", - [Reason]), - error_logger:error_report(Report), - ?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE) - end; - -master_secret(Version, PremasterSecret, ConnectionStates, Role) -> - ConnectionState = - tls_record:pending_connection_state(ConnectionStates, read), - SecParams = ConnectionState#connection_state.security_parameters, - #security_parameters{prf_algorithm = PrfAlgo, - client_random = ClientRandom, - server_random = ServerRandom} = SecParams, - try master_secret(Version, - calc_master_secret(Version,PrfAlgo,PremasterSecret, - ClientRandom, ServerRandom), - SecParams, ConnectionStates, Role) - catch - exit:Reason -> - Report = io_lib:format("Master secret calculation failed" - " due to ~p", [Reason]), - error_logger:error_report(Report), - ?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE) - end. - --spec next_protocol(binary()) -> #next_protocol{}. - -next_protocol(SelectedProtocol) -> - #next_protocol{selected_protocol = SelectedProtocol}. - -%%-------------------------------------------------------------------- --spec finished(tls_version(), client | server, integer(), binary(), tls_handshake_history()) -> - #finished{}. -%% -%% Description: Creates a handshake finished message -%%------------------------------------------------------------------- -finished(Version, Role, PrfAlgo, MasterSecret, {Handshake, _}) -> % use the current handshake - #finished{verify_data = - calc_finished(Version, Role, PrfAlgo, MasterSecret, Handshake)}. - -%%-------------------------------------------------------------------- --spec verify_connection(tls_version(), #finished{}, client | server, integer(), binary(), - tls_handshake_history()) -> verified | #alert{}. -%% -%% Description: Checks the ssl handshake finished message to verify -%% the connection. -%%------------------------------------------------------------------- -verify_connection(Version, #finished{verify_data = Data}, - Role, PrfAlgo, MasterSecret, {_, Handshake}) -> - %% use the previous hashes - case calc_finished(Version, Role, PrfAlgo, MasterSecret, Handshake) of - Data -> - verified; - _ -> - ?ALERT_REC(?FATAL, ?DECRYPT_ERROR) - end. -%%-------------------------------------------------------------------- --spec server_hello_done() -> #server_hello_done{}. -%% -%% Description: Creates a server hello done message. -%%-------------------------------------------------------------------- -server_hello_done() -> - #server_hello_done{}. - -%%-------------------------------------------------------------------- -spec encode_handshake(tls_handshake(), tls_version()) -> iolist(). %% -%% Description: Encode a handshake packet to binary +%% Description: Encode a handshake packet %%--------------------------------------------------------------------x encode_handshake(Package, Version) -> - {MsgType, Bin} = enc_hs(Package, Version), + {MsgType, Bin} = enc_handshake(Package, Version), Len = byte_size(Bin), [MsgType, ?uint24(Len), Bin]. @@ -593,30 +167,6 @@ get_tls_handshake(Version, Data, Buffer) -> get_tls_handshake_aux(Version, list_to_binary([Buffer, Data]), []). %%-------------------------------------------------------------------- --spec decode_client_key(binary(), key_algo(), tls_version()) -> - #encrypted_premaster_secret{} - | #client_diffie_hellman_public{} - | #client_ec_diffie_hellman_public{} - | #client_psk_identity{} - | #client_dhe_psk_identity{} - | #client_rsa_psk_identity{} - | #client_srp_public{}. -%% -%% Description: Decode client_key data and return appropriate type -%%-------------------------------------------------------------------- -decode_client_key(ClientKey, Type, Version) -> - dec_client_key(ClientKey, key_exchange_alg(Type), Version). - -%%-------------------------------------------------------------------- --spec decode_server_key(binary(), key_algo(), tls_version()) -> - #server_key_params{}. -%% -%% Description: Decode server_key data and return appropriate type -%%-------------------------------------------------------------------- -decode_server_key(ServerKey, Type, Version) -> - dec_server_key(ServerKey, key_exchange_alg(Type), Version). - -%%-------------------------------------------------------------------- -spec init_handshake_history() -> tls_handshake_history(). %% @@ -646,1182 +196,99 @@ update_handshake_history(Handshake, % special-case SSL2 client hello update_handshake_history({Handshake0, _Prev}, Data) -> {[Data|Handshake0], Handshake0}. -%%-------------------------------------------------------------------- --spec decrypt_premaster_secret(binary(), #'RSAPrivateKey'{}) -> binary(). -%% -%% Description: Public key decryption using the private key. -%%-------------------------------------------------------------------- -decrypt_premaster_secret(Secret, RSAPrivateKey) -> - try public_key:decrypt_private(Secret, RSAPrivateKey, - [{rsa_pad, rsa_pkcs1_padding}]) - catch - _:_ -> - io:format("decrypt_premaster_secret error"), - throw(?ALERT_REC(?FATAL, ?DECRYPT_ERROR)) - end. - -%%-------------------------------------------------------------------- --spec server_key_exchange_hash(md5sha | md5 | sha | sha224 |sha256 | sha384 | sha512, binary()) -> binary(). -%% -%% Description: Calculate server key exchange hash -%%-------------------------------------------------------------------- -server_key_exchange_hash(md5sha, Value) -> - MD5 = crypto:hash(md5, Value), - SHA = crypto:hash(sha, Value), - <<MD5/binary, SHA/binary>>; - -server_key_exchange_hash(Hash, Value) -> - crypto:hash(Hash, Value). - -%%-------------------------------------------------------------------- --spec prf(tls_version(), binary(), binary(), [binary()], non_neg_integer()) -> - {ok, binary()} | {error, undefined}. -%% -%% Description: use the TLS PRF to generate key material -%%-------------------------------------------------------------------- -prf({3,0}, _, _, _, _) -> - {error, undefined}; -prf({3,1}, Secret, Label, Seed, WantedLength) -> - {ok, ssl_tls1:prf(?MD5SHA, Secret, Label, Seed, WantedLength)}; -prf({3,_N}, Secret, Label, Seed, WantedLength) -> - {ok, ssl_tls1:prf(?SHA256, Secret, Label, Seed, WantedLength)}. - -%%-------------------------------------------------------------------- -%%% Internal functions -%%-------------------------------------------------------------------- get_tls_handshake_aux(Version, <<?BYTE(Type), ?UINT24(Length), Body:Length/binary,Rest/binary>>, Acc) -> Raw = <<?BYTE(Type), ?UINT24(Length), Body/binary>>, - H = dec_hs(Version, Type, Body), - get_tls_handshake_aux(Version, Rest, [{H,Raw} | Acc]); + Handshake = decode_handshake(Version, Type, Body), + get_tls_handshake_aux(Version, Rest, [{Handshake,Raw} | Acc]); get_tls_handshake_aux(_Version, Data, Acc) -> {lists:reverse(Acc), Data}. -path_validation_alert({bad_cert, cert_expired}) -> - ?ALERT_REC(?FATAL, ?CERTIFICATE_EXPIRED); -path_validation_alert({bad_cert, invalid_issuer}) -> - ?ALERT_REC(?FATAL, ?BAD_CERTIFICATE); -path_validation_alert({bad_cert, invalid_signature}) -> - ?ALERT_REC(?FATAL, ?BAD_CERTIFICATE); -path_validation_alert({bad_cert, name_not_permitted}) -> - ?ALERT_REC(?FATAL, ?BAD_CERTIFICATE); -path_validation_alert({bad_cert, unknown_critical_extension}) -> - ?ALERT_REC(?FATAL, ?UNSUPPORTED_CERTIFICATE); -path_validation_alert({bad_cert, cert_revoked}) -> - ?ALERT_REC(?FATAL, ?CERTIFICATE_REVOKED); -path_validation_alert({bad_cert, selfsigned_peer}) -> - ?ALERT_REC(?FATAL, ?BAD_CERTIFICATE); -path_validation_alert({bad_cert, unknown_ca}) -> - ?ALERT_REC(?FATAL, ?UNKNOWN_CA); -path_validation_alert(_) -> - ?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE). - -select_session(Hello, Port, Session, Version, - #ssl_options{ciphers = UserSuites} = SslOpts, Cache, CacheCb, Cert) -> - SuggestedSessionId = Hello#client_hello.session_id, - {SessionId, Resumed} = ssl_session:server_id(Port, SuggestedSessionId, - SslOpts, Cert, - Cache, CacheCb), - Suites = available_suites(Cert, UserSuites, Version), - case Resumed of - undefined -> - CipherSuite = select_cipher_suite(Hello#client_hello.cipher_suites, Suites), - Compressions = Hello#client_hello.compression_methods, - Compression = select_compression(Compressions), - {new, Session#session{session_id = SessionId, - cipher_suite = CipherSuite, - compression_method = Compression}}; - _ -> - {resumed, Resumed} - end. - -available_suites(UserSuites, Version) -> - case UserSuites of - [] -> - ssl_cipher:suites(Version); - _ -> - UserSuites - end. - -available_suites(ServerCert, UserSuites, Version) -> - ssl_cipher:filter(ServerCert, available_suites(UserSuites, Version)). - -cipher_suites(Suites, false) -> - [?TLS_EMPTY_RENEGOTIATION_INFO_SCSV | Suites]; -cipher_suites(Suites, true) -> - Suites. - -srp_user(#ssl_options{srp_identity = {UserName, _}}) -> - #srp{username = UserName}; -srp_user(_) -> - undefined. - -renegotiation_info(client, _, false) -> - #renegotiation_info{renegotiated_connection = undefined}; -renegotiation_info(server, ConnectionStates, false) -> - CS = tls_record:current_connection_state(ConnectionStates, read), - case CS#connection_state.secure_renegotiation of - true -> - #renegotiation_info{renegotiated_connection = ?byte(0)}; - false -> - #renegotiation_info{renegotiated_connection = undefined} - end; -renegotiation_info(client, ConnectionStates, true) -> - CS = tls_record:current_connection_state(ConnectionStates, read), - case CS#connection_state.secure_renegotiation of - true -> - Data = CS#connection_state.client_verify_data, - #renegotiation_info{renegotiated_connection = Data}; - false -> - #renegotiation_info{renegotiated_connection = undefined} - end; - -renegotiation_info(server, ConnectionStates, true) -> - CS = tls_record:current_connection_state(ConnectionStates, read), - case CS#connection_state.secure_renegotiation of - true -> - CData = CS#connection_state.client_verify_data, - SData =CS#connection_state.server_verify_data, - #renegotiation_info{renegotiated_connection = <<CData/binary, SData/binary>>}; - false -> - #renegotiation_info{renegotiated_connection = undefined} - end. - -decode_next_protocols({next_protocol_negotiation, Protocols}) -> - decode_next_protocols(Protocols, []). -decode_next_protocols(<<>>, Acc) -> - lists:reverse(Acc); -decode_next_protocols(<<?BYTE(Len), Protocol:Len/binary, Rest/binary>>, Acc) -> - case Len of - 0 -> - {error, invalid_next_protocols}; - _ -> - decode_next_protocols(Rest, [Protocol|Acc]) - end; -decode_next_protocols(_Bytes, _Acc) -> - {error, invalid_next_protocols}. - -next_protocol_extension_allowed(NextProtocolSelector, Renegotiating) -> - NextProtocolSelector =/= undefined andalso not Renegotiating. - -handle_next_protocol_on_server(#client_hello{next_protocol_negotiation = undefined}, _Renegotiation, _SslOpts) -> - undefined; - -handle_next_protocol_on_server(#client_hello{next_protocol_negotiation = {next_protocol_negotiation, <<>>}}, - false, #ssl_options{next_protocols_advertised = Protocols}) -> - Protocols; - -handle_next_protocol_on_server(_Hello, _Renegotiation, _SSLOpts) -> - ?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE). % unexpected next protocol extension - -handle_next_protocol(#server_hello{next_protocol_negotiation = undefined}, - _NextProtocolSelector, _Renegotiating) -> - undefined; - -handle_next_protocol(#server_hello{next_protocol_negotiation = Protocols}, - NextProtocolSelector, Renegotiating) -> - - case next_protocol_extension_allowed(NextProtocolSelector, Renegotiating) of - true -> - select_next_protocol(decode_next_protocols(Protocols), NextProtocolSelector); - false -> - ?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE) % unexpected next protocol extension - end. - -select_next_protocol({error, _Reason}, _NextProtocolSelector) -> - ?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE); -select_next_protocol(Protocols, NextProtocolSelector) -> - case NextProtocolSelector(Protocols) of - ?NO_PROTOCOL -> - ?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE); - Protocol when is_binary(Protocol) -> - Protocol - end. - -default_ecc_extensions(Version) -> - CryptoSupport = proplists:get_value(public_keys, crypto:supports()), - case proplists:get_bool(ecdh, CryptoSupport) of - true -> - EcPointFormats = #ec_point_formats{ec_point_format_list = [?ECPOINT_UNCOMPRESSED]}, - EllipticCurves = #elliptic_curves{elliptic_curve_list = ssl_tls1:ecc_curves(Version)}, - {EcPointFormats, EllipticCurves}; - _ -> - {undefined, undefined} - end. - -handle_ecc_extensions(Version, EcPointFormats0, EllipticCurves0) -> - CryptoSupport = proplists:get_value(public_keys, crypto:supports()), - case proplists:get_bool(ecdh, CryptoSupport) of - true -> - EcPointFormats1 = handle_ecc_point_fmt_extension(EcPointFormats0), - EllipticCurves1 = handle_ecc_curves_extension(Version, EllipticCurves0), - {EcPointFormats1, EllipticCurves1}; - _ -> - {undefined, undefined} - end. - -handle_ecc_point_fmt_extension(undefined) -> - undefined; -handle_ecc_point_fmt_extension(_) -> - #ec_point_formats{ec_point_format_list = [?ECPOINT_UNCOMPRESSED]}. - -handle_ecc_curves_extension(_Version, undefined) -> - undefined; -handle_ecc_curves_extension(Version, _) -> - #elliptic_curves{elliptic_curve_list = ssl_tls1:ecc_curves(Version)}. - -handle_renegotiation_info(_, #renegotiation_info{renegotiated_connection = ?byte(0)}, - ConnectionStates, false, _, _) -> - {ok, tls_record:set_renegotiation_flag(true, ConnectionStates)}; - -handle_renegotiation_info(server, undefined, ConnectionStates, _, _, CipherSuites) -> - case is_member(?TLS_EMPTY_RENEGOTIATION_INFO_SCSV, CipherSuites) of - true -> - {ok, tls_record:set_renegotiation_flag(true, ConnectionStates)}; - false -> - {ok, tls_record:set_renegotiation_flag(false, ConnectionStates)} - end; - -handle_renegotiation_info(_, undefined, ConnectionStates, false, _, _) -> - {ok, tls_record:set_renegotiation_flag(false, ConnectionStates)}; - -handle_renegotiation_info(client, #renegotiation_info{renegotiated_connection = ClientServerVerify}, - ConnectionStates, true, _, _) -> - CS = tls_record:current_connection_state(ConnectionStates, read), - CData = CS#connection_state.client_verify_data, - SData = CS#connection_state.server_verify_data, - case <<CData/binary, SData/binary>> == ClientServerVerify of - true -> - {ok, ConnectionStates}; - false -> - ?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE) - end; -handle_renegotiation_info(server, #renegotiation_info{renegotiated_connection = ClientVerify}, - ConnectionStates, true, _, CipherSuites) -> - - case is_member(?TLS_EMPTY_RENEGOTIATION_INFO_SCSV, CipherSuites) of - true -> - ?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE); - false -> - CS = tls_record:current_connection_state(ConnectionStates, read), - Data = CS#connection_state.client_verify_data, - case Data == ClientVerify of - true -> - {ok, ConnectionStates}; - false -> - ?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE) - end - end; - -handle_renegotiation_info(client, undefined, ConnectionStates, true, SecureRenegotation, _) -> - handle_renegotiation_info(ConnectionStates, SecureRenegotation); - -handle_renegotiation_info(server, undefined, ConnectionStates, true, SecureRenegotation, CipherSuites) -> - case is_member(?TLS_EMPTY_RENEGOTIATION_INFO_SCSV, CipherSuites) of - true -> - ?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE); - false -> - handle_renegotiation_info(ConnectionStates, SecureRenegotation) - end. - -handle_renegotiation_info(ConnectionStates, SecureRenegotation) -> - CS = tls_record:current_connection_state(ConnectionStates, read), - case {SecureRenegotation, CS#connection_state.secure_renegotiation} of - {_, true} -> - ?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE); - {true, false} -> - ?ALERT_REC(?FATAL, ?NO_RENEGOTIATION); - {false, false} -> - {ok, ConnectionStates} - end. - -%% Update pending connection states with parameters exchanged via -%% hello messages -%% NOTE : Role is the role of the receiver of the hello message -%% currently being processed. -hello_pending_connection_states(Role, Version, CipherSuite, Random, Compression, - ConnectionStates) -> - ReadState = - tls_record:pending_connection_state(ConnectionStates, read), - WriteState = - tls_record:pending_connection_state(ConnectionStates, write), - - NewReadSecParams = - hello_security_parameters(Role, Version, ReadState, CipherSuite, - Random, Compression), - - NewWriteSecParams = - hello_security_parameters(Role, Version, WriteState, CipherSuite, - Random, Compression), - - tls_record:update_security_params(NewReadSecParams, - NewWriteSecParams, - ConnectionStates). - -hello_security_parameters(client, Version, ConnectionState, CipherSuite, Random, - Compression) -> - SecParams = ConnectionState#connection_state.security_parameters, - NewSecParams = ssl_cipher:security_parameters(Version, CipherSuite, SecParams), - NewSecParams#security_parameters{ - server_random = Random, - compression_algorithm = Compression - }; - -hello_security_parameters(server, Version, ConnectionState, CipherSuite, Random, - Compression) -> - SecParams = ConnectionState#connection_state.security_parameters, - NewSecParams = ssl_cipher:security_parameters(Version, CipherSuite, SecParams), - NewSecParams#security_parameters{ - client_random = Random, - compression_algorithm = Compression - }. - -select_version(ClientVersion, Versions) -> - ServerVersion = tls_record:highest_protocol_version(Versions), - tls_record:lowest_protocol_version(ClientVersion, ServerVersion). - -select_cipher_suite([], _) -> - no_suite; -select_cipher_suite([Suite | ClientSuites], SupportedSuites) -> - case is_member(Suite, SupportedSuites) of - true -> - Suite; - false -> - select_cipher_suite(ClientSuites, SupportedSuites) - end. - -is_member(Suite, SupportedSuites) -> - lists:member(Suite, SupportedSuites). - -select_compression(_CompressionMetodes) -> - ?NULL. - -master_secret(Version, MasterSecret, #security_parameters{ - client_random = ClientRandom, - server_random = ServerRandom, - hash_size = HashSize, - prf_algorithm = PrfAlgo, - key_material_length = KML, - expanded_key_material_length = EKML, - iv_size = IVS}, - ConnectionStates, Role) -> - {ClientWriteMacSecret, ServerWriteMacSecret, ClientWriteKey, - ServerWriteKey, ClientIV, ServerIV} = - setup_keys(Version, PrfAlgo, MasterSecret, ServerRandom, - ClientRandom, HashSize, KML, EKML, IVS), - - ConnStates1 = tls_record:set_master_secret(MasterSecret, ConnectionStates), - ConnStates2 = - tls_record:set_mac_secret(ClientWriteMacSecret, ServerWriteMacSecret, - Role, ConnStates1), - - ClientCipherState = #cipher_state{iv = ClientIV, key = ClientWriteKey}, - ServerCipherState = #cipher_state{iv = ServerIV, key = ServerWriteKey}, - {MasterSecret, - tls_record:set_pending_cipher_state(ConnStates2, ClientCipherState, - ServerCipherState, Role)}. - - -dec_hs(_, ?NEXT_PROTOCOL, <<?BYTE(SelectedProtocolLength), SelectedProtocol:SelectedProtocolLength/binary, - ?BYTE(PaddingLength), _Padding:PaddingLength/binary>>) -> - #next_protocol{selected_protocol = SelectedProtocol}; +%%-------------------------------------------------------------------- +%%% Internal functions +%%-------------------------------------------------------------------- -dec_hs(_, ?HELLO_REQUEST, <<>>) -> +decode_handshake(_, ?HELLO_REQUEST, <<>>) -> #hello_request{}; %% Client hello v2. %% The server must be able to receive such messages, from clients that %% are willing to use ssl v3 or higher, but have ssl v2 compatibility. -dec_hs(_Version, ?CLIENT_HELLO, <<?BYTE(Major), ?BYTE(Minor), +decode_handshake(_Version, ?CLIENT_HELLO, <<?BYTE(Major), ?BYTE(Minor), ?UINT16(CSLength), ?UINT16(0), ?UINT16(CDLength), CipherSuites:CSLength/binary, ChallengeData:CDLength/binary>>) -> #client_hello{client_version = {Major, Minor}, - random = ssl_ssl2:client_random(ChallengeData, CDLength), + random = ssl_v2:client_random(ChallengeData, CDLength), session_id = 0, - cipher_suites = from_3bytes(CipherSuites), + cipher_suites = ssl_handshake:decode_suites('3_bytes', CipherSuites), compression_methods = [?NULL], - renegotiation_info = undefined + extensions = #hello_extensions{} }; -dec_hs(_Version, ?CLIENT_HELLO, <<?BYTE(Major), ?BYTE(Minor), Random:32/binary, +decode_handshake(_Version, ?CLIENT_HELLO, <<?BYTE(Major), ?BYTE(Minor), Random:32/binary, ?BYTE(SID_length), Session_ID:SID_length/binary, ?UINT16(Cs_length), CipherSuites:Cs_length/binary, ?BYTE(Cm_length), Comp_methods:Cm_length/binary, Extensions/binary>>) -> - DecodedExtensions = dec_hello_extensions(Extensions), - RenegotiationInfo = proplists:get_value(renegotiation_info, DecodedExtensions, undefined), - SRP = proplists:get_value(srp, DecodedExtensions, undefined), - HashSigns = proplists:get_value(hash_signs, DecodedExtensions, undefined), - EllipticCurves = proplists:get_value(elliptic_curves, DecodedExtensions, - undefined), - NextProtocolNegotiation = proplists:get_value(next_protocol_negotiation, DecodedExtensions, undefined), + DecodedExtensions = ssl_handshake:decode_hello_extensions({client, Extensions}), #client_hello{ client_version = {Major,Minor}, random = Random, session_id = Session_ID, - cipher_suites = from_2bytes(CipherSuites), + cipher_suites = ssl_handshake:decode_suites('2_bytes', CipherSuites), compression_methods = Comp_methods, - renegotiation_info = RenegotiationInfo, - srp = SRP, - hash_signs = HashSigns, - elliptic_curves = EllipticCurves, - next_protocol_negotiation = NextProtocolNegotiation + extensions = DecodedExtensions }; -dec_hs(_Version, ?SERVER_HELLO, <<?BYTE(Major), ?BYTE(Minor), Random:32/binary, - ?BYTE(SID_length), Session_ID:SID_length/binary, - Cipher_suite:2/binary, ?BYTE(Comp_method)>>) -> - #server_hello{ - server_version = {Major,Minor}, - random = Random, - session_id = Session_ID, - cipher_suite = Cipher_suite, - compression_method = Comp_method, - renegotiation_info = undefined, - hash_signs = undefined, - elliptic_curves = undefined}; - -dec_hs(_Version, ?SERVER_HELLO, <<?BYTE(Major), ?BYTE(Minor), Random:32/binary, - ?BYTE(SID_length), Session_ID:SID_length/binary, - Cipher_suite:2/binary, ?BYTE(Comp_method), - ?UINT16(ExtLen), Extensions:ExtLen/binary>>) -> - - HelloExtensions = dec_hello_extensions(Extensions, []), - RenegotiationInfo = proplists:get_value(renegotiation_info, HelloExtensions, - undefined), - HashSigns = proplists:get_value(hash_signs, HelloExtensions, - undefined), - EllipticCurves = proplists:get_value(elliptic_curves, HelloExtensions, - undefined), - NextProtocolNegotiation = proplists:get_value(next_protocol_negotiation, HelloExtensions, undefined), - - #server_hello{ - server_version = {Major,Minor}, - random = Random, - session_id = Session_ID, - cipher_suite = Cipher_suite, - compression_method = Comp_method, - renegotiation_info = RenegotiationInfo, - hash_signs = HashSigns, - elliptic_curves = EllipticCurves, - next_protocol_negotiation = NextProtocolNegotiation}; -dec_hs(_Version, ?CERTIFICATE, <<?UINT24(ACLen), ASN1Certs:ACLen/binary>>) -> - #certificate{asn1_certificates = certs_to_list(ASN1Certs)}; -dec_hs(_Version, ?SERVER_KEY_EXCHANGE, Keys) -> - #server_key_exchange{exchange_keys = Keys}; -dec_hs({Major, Minor}, ?CERTIFICATE_REQUEST, - <<?BYTE(CertTypesLen), CertTypes:CertTypesLen/binary, - ?UINT16(HashSignsLen), HashSigns:HashSignsLen/binary, - ?UINT16(CertAuthsLen), CertAuths:CertAuthsLen/binary>>) - when Major == 3, Minor >= 3 -> - HashSignAlgos = [{ssl_cipher:hash_algorithm(Hash), ssl_cipher:sign_algorithm(Sign)} || - <<?BYTE(Hash), ?BYTE(Sign)>> <= HashSigns], - #certificate_request{certificate_types = CertTypes, - hashsign_algorithms = #hash_sign_algos{hash_sign_algos = HashSignAlgos}, - certificate_authorities = CertAuths}; -dec_hs(_Version, ?CERTIFICATE_REQUEST, - <<?BYTE(CertTypesLen), CertTypes:CertTypesLen/binary, - ?UINT16(CertAuthsLen), CertAuths:CertAuthsLen/binary>>) -> - #certificate_request{certificate_types = CertTypes, - certificate_authorities = CertAuths}; -dec_hs(_Version, ?SERVER_HELLO_DONE, <<>>) -> - #server_hello_done{}; -dec_hs({Major, Minor}, ?CERTIFICATE_VERIFY,<<HashSign:2/binary, ?UINT16(SignLen), Signature:SignLen/binary>>) - when Major == 3, Minor >= 3 -> - #certificate_verify{hashsign_algorithm = hashsign_dec(HashSign), signature = Signature}; -dec_hs(_Version, ?CERTIFICATE_VERIFY,<<?UINT16(SignLen), Signature:SignLen/binary>>)-> - #certificate_verify{signature = Signature}; -dec_hs(_Version, ?CLIENT_KEY_EXCHANGE, PKEPMS) -> - #client_key_exchange{exchange_keys = PKEPMS}; -dec_hs(_Version, ?FINISHED, VerifyData) -> - #finished{verify_data = VerifyData}; -dec_hs(_, _, _) -> - throw(?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE)). - -dec_client_key(PKEPMS, ?KEY_EXCHANGE_RSA, {3, 0}) -> - #encrypted_premaster_secret{premaster_secret = PKEPMS}; -dec_client_key(<<?UINT16(_), PKEPMS/binary>>, ?KEY_EXCHANGE_RSA, _) -> - #encrypted_premaster_secret{premaster_secret = PKEPMS}; -dec_client_key(<<>>, ?KEY_EXCHANGE_DIFFIE_HELLMAN, _) -> - throw(?ALERT_REC(?FATAL, ?UNSUPPORTED_CERTIFICATE)); -dec_client_key(<<?UINT16(DH_YLen), DH_Y:DH_YLen/binary>>, - ?KEY_EXCHANGE_DIFFIE_HELLMAN, _) -> - #client_diffie_hellman_public{dh_public = DH_Y}; -dec_client_key(<<>>, ?KEY_EXCHANGE_EC_DIFFIE_HELLMAN, _) -> - throw(?ALERT_REC(?FATAL, ?UNSUPPORTED_CERTIFICATE)); -dec_client_key(<<?BYTE(DH_YLen), DH_Y:DH_YLen/binary>>, - ?KEY_EXCHANGE_EC_DIFFIE_HELLMAN, _) -> - #client_ec_diffie_hellman_public{dh_public = DH_Y}; -dec_client_key(<<?UINT16(Len), Id:Len/binary>>, - ?KEY_EXCHANGE_PSK, _) -> - #client_psk_identity{identity = Id}; -dec_client_key(<<?UINT16(Len), Id:Len/binary, - ?UINT16(DH_YLen), DH_Y:DH_YLen/binary>>, - ?KEY_EXCHANGE_DHE_PSK, _) -> - #client_dhe_psk_identity{identity = Id, dh_public = DH_Y}; -dec_client_key(<<?UINT16(Len), Id:Len/binary, PKEPMS/binary>>, - ?KEY_EXCHANGE_RSA_PSK, {3, 0}) -> - #client_rsa_psk_identity{identity = Id, exchange_keys = #encrypted_premaster_secret{premaster_secret = PKEPMS}}; -dec_client_key(<<?UINT16(Len), Id:Len/binary, ?UINT16(_), PKEPMS/binary>>, - ?KEY_EXCHANGE_RSA_PSK, _) -> - #client_rsa_psk_identity{identity = Id, exchange_keys = #encrypted_premaster_secret{premaster_secret = PKEPMS}}; -dec_client_key(<<?UINT16(ALen), A:ALen/binary>>, - ?KEY_EXCHANGE_SRP, _) -> - #client_srp_public{srp_a = A}. - -dec_ske_params(Len, Keys, Version) -> - <<Params:Len/bytes, Signature/binary>> = Keys, - dec_ske_signature(Params, Signature, Version). - -dec_ske_signature(Params, <<?BYTE(HashAlgo), ?BYTE(SignAlgo), - ?UINT16(0)>>, {Major, Minor}) - when Major == 3, Minor >= 3 -> - HashSign = {ssl_cipher:hash_algorithm(HashAlgo), ssl_cipher:sign_algorithm(SignAlgo)}, - {Params, HashSign, <<>>}; -dec_ske_signature(Params, <<?BYTE(HashAlgo), ?BYTE(SignAlgo), - ?UINT16(Len), Signature:Len/binary>>, {Major, Minor}) - when Major == 3, Minor >= 3 -> - HashSign = {ssl_cipher:hash_algorithm(HashAlgo), ssl_cipher:sign_algorithm(SignAlgo)}, - {Params, HashSign, Signature}; -dec_ske_signature(Params, <<>>, _) -> - {Params, {null, anon}, <<>>}; -dec_ske_signature(Params, <<?UINT16(0)>>, _) -> - {Params, {null, anon}, <<>>}; -dec_ske_signature(Params, <<?UINT16(Len), Signature:Len/binary>>, _) -> - {Params, undefined, Signature}; -dec_ske_signature(_, _, _) -> - throw(?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE)). - -dec_server_key(<<?UINT16(PLen), P:PLen/binary, - ?UINT16(GLen), G:GLen/binary, - ?UINT16(YLen), Y:YLen/binary, _/binary>> = KeyStruct, - ?KEY_EXCHANGE_DIFFIE_HELLMAN, Version) -> - Params = #server_dh_params{dh_p = P, dh_g = G, dh_y = Y}, - {BinMsg, HashSign, Signature} = dec_ske_params(PLen + GLen + YLen + 6, KeyStruct, Version), - #server_key_params{params = Params, - params_bin = BinMsg, - hashsign = HashSign, - signature = Signature}; -%% ECParameters with named_curve -%% TODO: explicit curve -dec_server_key(<<?BYTE(?NAMED_CURVE), ?UINT16(CurveID), - ?BYTE(PointLen), ECPoint:PointLen/binary, - _/binary>> = KeyStruct, - ?KEY_EXCHANGE_EC_DIFFIE_HELLMAN, Version) -> - Params = #server_ecdh_params{curve = {namedCurve, ssl_tls1:enum_to_oid(CurveID)}, - public = ECPoint}, - {BinMsg, HashSign, Signature} = dec_ske_params(PointLen + 4, KeyStruct, Version), - #server_key_params{params = Params, - params_bin = BinMsg, - hashsign = HashSign, - signature = Signature}; -dec_server_key(<<?UINT16(Len), PskIdentityHint:Len/binary>> = KeyStruct, - KeyExchange, Version) - when KeyExchange == ?KEY_EXCHANGE_PSK; KeyExchange == ?KEY_EXCHANGE_RSA_PSK -> - Params = #server_psk_params{ - hint = PskIdentityHint}, - {BinMsg, HashSign, Signature} = dec_ske_params(Len + 2, KeyStruct, Version), - #server_key_params{params = Params, - params_bin = BinMsg, - hashsign = HashSign, - signature = Signature}; -dec_server_key(<<?UINT16(Len), IdentityHint:Len/binary, - ?UINT16(PLen), P:PLen/binary, - ?UINT16(GLen), G:GLen/binary, - ?UINT16(YLen), Y:YLen/binary, _/binary>> = KeyStruct, - ?KEY_EXCHANGE_DHE_PSK, Version) -> - DHParams = #server_dh_params{dh_p = P, dh_g = G, dh_y = Y}, - Params = #server_dhe_psk_params{ - hint = IdentityHint, - dh_params = DHParams}, - {BinMsg, HashSign, Signature} = dec_ske_params(Len + PLen + GLen + YLen + 8, KeyStruct, Version), - #server_key_params{params = Params, - params_bin = BinMsg, - hashsign = HashSign, - signature = Signature}; -dec_server_key(<<?UINT16(NLen), N:NLen/binary, - ?UINT16(GLen), G:GLen/binary, - ?BYTE(SLen), S:SLen/binary, - ?UINT16(BLen), B:BLen/binary, _/binary>> = KeyStruct, - ?KEY_EXCHANGE_SRP, Version) -> - Params = #server_srp_params{srp_n = N, srp_g = G, srp_s = S, srp_b = B}, - {BinMsg, HashSign, Signature} = dec_ske_params(NLen + GLen + SLen + BLen + 7, KeyStruct, Version), - #server_key_params{params = Params, - params_bin = BinMsg, - hashsign = HashSign, - signature = Signature}; -dec_server_key(_, _, _) -> - throw(?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE)). - -dec_hello_extensions(<<>>) -> - []; -dec_hello_extensions(<<?UINT16(ExtLen), Extensions:ExtLen/binary>>) -> - dec_hello_extensions(Extensions, []); -dec_hello_extensions(_) -> - []. - -dec_hello_extensions(<<>>, Acc) -> - Acc; -dec_hello_extensions(<<?UINT16(?NEXTPROTONEG_EXT), ?UINT16(Len), ExtensionData:Len/binary, Rest/binary>>, Acc) -> - Prop = {next_protocol_negotiation, #next_protocol_negotiation{extension_data = ExtensionData}}, - dec_hello_extensions(Rest, [Prop | Acc]); -dec_hello_extensions(<<?UINT16(?RENEGOTIATION_EXT), ?UINT16(Len), Info:Len/binary, Rest/binary>>, Acc) -> - RenegotiateInfo = case Len of - 1 -> % Initial handshake - Info; % should be <<0>> will be matched in handle_renegotiation_info - _ -> - VerifyLen = Len - 1, - <<?BYTE(VerifyLen), VerifyInfo/binary>> = Info, - VerifyInfo - end, - dec_hello_extensions(Rest, [{renegotiation_info, - #renegotiation_info{renegotiated_connection = RenegotiateInfo}} | Acc]); +decode_handshake(Version, Tag, Msg) -> + ssl_handshake:decode_handshake(Version, Tag, Msg). -dec_hello_extensions(<<?UINT16(?SRP_EXT), ?UINT16(Len), ?BYTE(SRPLen), SRP:SRPLen/binary, Rest/binary>>, Acc) - when Len == SRPLen + 2 -> - dec_hello_extensions(Rest, [{srp, - #srp{username = SRP}} | Acc]); - -dec_hello_extensions(<<?UINT16(?SIGNATURE_ALGORITHMS_EXT), ?UINT16(Len), - ExtData:Len/binary, Rest/binary>>, Acc) -> - SignAlgoListLen = Len - 2, - <<?UINT16(SignAlgoListLen), SignAlgoList/binary>> = ExtData, - HashSignAlgos = [{ssl_cipher:hash_algorithm(Hash), ssl_cipher:sign_algorithm(Sign)} || - <<?BYTE(Hash), ?BYTE(Sign)>> <= SignAlgoList], - dec_hello_extensions(Rest, [{hash_signs, - #hash_sign_algos{hash_sign_algos = HashSignAlgos}} | Acc]); - -dec_hello_extensions(<<?UINT16(?ELLIPTIC_CURVES_EXT), ?UINT16(Len), - ExtData:Len/binary, Rest/binary>>, Acc) -> - EllipticCurveListLen = Len - 2, - <<?UINT16(EllipticCurveListLen), EllipticCurveList/binary>> = ExtData, - EllipticCurves = [ssl_tls1:enum_to_oid(X) || <<X:16>> <= EllipticCurveList], - dec_hello_extensions(Rest, [{elliptic_curves, - #elliptic_curves{elliptic_curve_list = EllipticCurves}} | Acc]); - -dec_hello_extensions(<<?UINT16(?EC_POINT_FORMATS_EXT), ?UINT16(Len), - ExtData:Len/binary, Rest/binary>>, Acc) -> - ECPointFormatListLen = Len - 1, - <<?BYTE(ECPointFormatListLen), ECPointFormatList/binary>> = ExtData, - ECPointFormats = binary_to_list(ECPointFormatList), - dec_hello_extensions(Rest, [{ec_point_formats, - #ec_point_formats{ec_point_format_list = ECPointFormats}} | Acc]); - -%% Ignore data following the ClientHello (i.e., -%% extensions) if not understood. - -dec_hello_extensions(<<?UINT16(_), ?UINT16(Len), _Unknown:Len/binary, Rest/binary>>, Acc) -> - dec_hello_extensions(Rest, Acc); -%% This theoretically should not happen if the protocol is followed, but if it does it is ignored. -dec_hello_extensions(_, Acc) -> - Acc. - -encrypted_premaster_secret(Secret, RSAPublicKey) -> - try - PreMasterSecret = public_key:encrypt_public(Secret, RSAPublicKey, - [{rsa_pad, - rsa_pkcs1_padding}]), - #encrypted_premaster_secret{premaster_secret = PreMasterSecret} - catch - _:_-> - throw(?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE)) - end. - -%% encode/decode stream of certificate data to/from list of certificate data -certs_to_list(ASN1Certs) -> - certs_to_list(ASN1Certs, []). - -certs_to_list(<<?UINT24(CertLen), Cert:CertLen/binary, Rest/binary>>, Acc) -> - certs_to_list(Rest, [Cert | Acc]); -certs_to_list(<<>>, Acc) -> - lists:reverse(Acc, []). - -certs_from_list(ACList) -> - list_to_binary([begin - CertLen = byte_size(Cert), - <<?UINT24(CertLen), Cert/binary>> - end || Cert <- ACList]). - -enc_hs(#next_protocol{selected_protocol = SelectedProtocol}, _Version) -> - PaddingLength = 32 - ((byte_size(SelectedProtocol) + 2) rem 32), - - {?NEXT_PROTOCOL, <<?BYTE((byte_size(SelectedProtocol))), SelectedProtocol/binary, - ?BYTE(PaddingLength), 0:(PaddingLength * 8)>>}; -enc_hs(#hello_request{}, _Version) -> +enc_handshake(#hello_request{}, _Version) -> {?HELLO_REQUEST, <<>>}; -enc_hs(#client_hello{client_version = {Major, Minor}, +enc_handshake(#client_hello{client_version = {Major, Minor}, random = Random, session_id = SessionID, cipher_suites = CipherSuites, compression_methods = CompMethods, - renegotiation_info = RenegotiationInfo, - srp = SRP, - hash_signs = HashSigns, - ec_point_formats = EcPointFormats, - elliptic_curves = EllipticCurves, - next_protocol_negotiation = NextProtocolNegotiation}, _Version) -> + extensions = HelloExtensions}, _Version) -> SIDLength = byte_size(SessionID), BinCompMethods = list_to_binary(CompMethods), CmLength = byte_size(BinCompMethods), BinCipherSuites = list_to_binary(CipherSuites), CsLength = byte_size(BinCipherSuites), - Extensions0 = hello_extensions(RenegotiationInfo, SRP, NextProtocolNegotiation) - ++ ec_hello_extensions(lists:map(fun ssl_cipher:suite_definition/1, CipherSuites), EcPointFormats) - ++ ec_hello_extensions(lists:map(fun ssl_cipher:suite_definition/1, CipherSuites), EllipticCurves), - Extensions1 = if - Major == 3, Minor >=3 -> Extensions0 ++ hello_extensions(HashSigns); - true -> Extensions0 - end, - ExtensionsBin = enc_hello_extensions(Extensions1), - - {?CLIENT_HELLO, <<?BYTE(Major), ?BYTE(Minor), Random:32/binary, - ?BYTE(SIDLength), SessionID/binary, - ?UINT16(CsLength), BinCipherSuites/binary, - ?BYTE(CmLength), BinCompMethods/binary, ExtensionsBin/binary>>}; - -enc_hs(#server_hello{server_version = {Major, Minor}, - random = Random, - session_id = Session_ID, - cipher_suite = CipherSuite, - compression_method = Comp_method, - renegotiation_info = RenegotiationInfo, - ec_point_formats = EcPointFormats, - elliptic_curves = EllipticCurves, - next_protocol_negotiation = NextProtocolNegotiation}, _Version) -> - SID_length = byte_size(Session_ID), - CipherSuites = [ssl_cipher:suite_definition(CipherSuite)], - Extensions = hello_extensions(RenegotiationInfo, NextProtocolNegotiation) - ++ ec_hello_extensions(CipherSuites, EcPointFormats) - ++ ec_hello_extensions(CipherSuites, EllipticCurves), - ExtensionsBin = enc_hello_extensions(Extensions), - {?SERVER_HELLO, <<?BYTE(Major), ?BYTE(Minor), Random:32/binary, - ?BYTE(SID_length), Session_ID/binary, - CipherSuite/binary, ?BYTE(Comp_method), ExtensionsBin/binary>>}; -enc_hs(#certificate{asn1_certificates = ASN1CertList}, _Version) -> - ASN1Certs = certs_from_list(ASN1CertList), - ACLen = erlang:iolist_size(ASN1Certs), - {?CERTIFICATE, <<?UINT24(ACLen), ASN1Certs:ACLen/binary>>}; -enc_hs(#server_key_exchange{exchange_keys = Keys}, _Version) -> - {?SERVER_KEY_EXCHANGE, Keys}; -enc_hs(#server_key_params{params_bin = Keys, hashsign = HashSign, - signature = Signature}, Version) -> - EncSign = enc_sign(HashSign, Signature, Version), - {?SERVER_KEY_EXCHANGE, <<Keys/binary, EncSign/binary>>}; -enc_hs(#certificate_request{certificate_types = CertTypes, - hashsign_algorithms = #hash_sign_algos{hash_sign_algos = HashSignAlgos}, - certificate_authorities = CertAuths}, - {Major, Minor}) - when Major == 3, Minor >= 3 -> - HashSigns= << <<(ssl_cipher:hash_algorithm(Hash)):8, (ssl_cipher:sign_algorithm(Sign)):8>> || - {Hash, Sign} <- HashSignAlgos >>, - CertTypesLen = byte_size(CertTypes), - HashSignsLen = byte_size(HashSigns), - CertAuthsLen = byte_size(CertAuths), - {?CERTIFICATE_REQUEST, - <<?BYTE(CertTypesLen), CertTypes/binary, - ?UINT16(HashSignsLen), HashSigns/binary, - ?UINT16(CertAuthsLen), CertAuths/binary>> - }; -enc_hs(#certificate_request{certificate_types = CertTypes, - certificate_authorities = CertAuths}, - _Version) -> - CertTypesLen = byte_size(CertTypes), - CertAuthsLen = byte_size(CertAuths), - {?CERTIFICATE_REQUEST, - <<?BYTE(CertTypesLen), CertTypes/binary, - ?UINT16(CertAuthsLen), CertAuths/binary>> - }; -enc_hs(#server_hello_done{}, _Version) -> - {?SERVER_HELLO_DONE, <<>>}; -enc_hs(#client_key_exchange{exchange_keys = ExchangeKeys}, Version) -> - {?CLIENT_KEY_EXCHANGE, enc_cke(ExchangeKeys, Version)}; -enc_hs(#certificate_verify{signature = BinSig, hashsign_algorithm = HashSign}, Version) -> - EncSig = enc_sign(HashSign, BinSig, Version), - {?CERTIFICATE_VERIFY, EncSig}; -enc_hs(#finished{verify_data = VerifyData}, _Version) -> - {?FINISHED, VerifyData}. - -enc_cke(#encrypted_premaster_secret{premaster_secret = PKEPMS},{3, 0}) -> - PKEPMS; -enc_cke(#encrypted_premaster_secret{premaster_secret = PKEPMS}, _) -> - PKEPMSLen = byte_size(PKEPMS), - <<?UINT16(PKEPMSLen), PKEPMS/binary>>; -enc_cke(#client_diffie_hellman_public{dh_public = DHPublic}, _) -> - Len = byte_size(DHPublic), - <<?UINT16(Len), DHPublic/binary>>; -enc_cke(#client_ec_diffie_hellman_public{dh_public = DHPublic}, _) -> - Len = byte_size(DHPublic), - <<?BYTE(Len), DHPublic/binary>>; -enc_cke(#client_psk_identity{identity = undefined}, _) -> - Id = <<"psk_identity">>, - Len = byte_size(Id), - <<?UINT16(Len), Id/binary>>; -enc_cke(#client_psk_identity{identity = Id}, _) -> - Len = byte_size(Id), - <<?UINT16(Len), Id/binary>>; -enc_cke(Identity = #client_dhe_psk_identity{identity = undefined}, Version) -> - enc_cke(Identity#client_dhe_psk_identity{identity = <<"psk_identity">>}, Version); -enc_cke(#client_dhe_psk_identity{identity = Id, dh_public = DHPublic}, _) -> - Len = byte_size(Id), - DHLen = byte_size(DHPublic), - <<?UINT16(Len), Id/binary, ?UINT16(DHLen), DHPublic/binary>>; -enc_cke(Identity = #client_rsa_psk_identity{identity = undefined}, Version) -> - enc_cke(Identity#client_rsa_psk_identity{identity = <<"psk_identity">>}, Version); -enc_cke(#client_rsa_psk_identity{identity = Id, exchange_keys = ExchangeKeys}, Version) -> - EncPMS = enc_cke(ExchangeKeys, Version), - Len = byte_size(Id), - <<?UINT16(Len), Id/binary, EncPMS/binary>>; -enc_cke(#client_srp_public{srp_a = A}, _) -> - Len = byte_size(A), - <<?UINT16(Len), A/binary>>. - -enc_server_key(#server_dh_params{dh_p = P, dh_g = G, dh_y = Y}) -> - PLen = byte_size(P), - GLen = byte_size(G), - YLen = byte_size(Y), - <<?UINT16(PLen), P/binary, ?UINT16(GLen), G/binary, ?UINT16(YLen), Y/binary>>; -enc_server_key(#server_ecdh_params{curve = {namedCurve, ECCurve}, public = ECPubKey}) -> - %%TODO: support arbitrary keys - KLen = size(ECPubKey), - <<?BYTE(?NAMED_CURVE_TYPE), ?UINT16((ssl_tls1:oid_to_enum(ECCurve))), - ?BYTE(KLen), ECPubKey/binary>>; -enc_server_key(#server_psk_params{hint = PskIdentityHint}) -> - Len = byte_size(PskIdentityHint), - <<?UINT16(Len), PskIdentityHint/binary>>; -enc_server_key(Params = #server_dhe_psk_params{hint = undefined}) -> - enc_server_key(Params#server_dhe_psk_params{hint = <<>>}); -enc_server_key(#server_dhe_psk_params{ - hint = PskIdentityHint, - dh_params = #server_dh_params{dh_p = P, dh_g = G, dh_y = Y}}) -> - Len = byte_size(PskIdentityHint), - PLen = byte_size(P), - GLen = byte_size(G), - YLen = byte_size(Y), - <<?UINT16(Len), PskIdentityHint/binary, - ?UINT16(PLen), P/binary, ?UINT16(GLen), G/binary, ?UINT16(YLen), Y/binary>>; -enc_server_key(#server_srp_params{srp_n = N, srp_g = G, srp_s = S, srp_b = B}) -> - NLen = byte_size(N), - GLen = byte_size(G), - SLen = byte_size(S), - BLen = byte_size(B), - <<?UINT16(NLen), N/binary, ?UINT16(GLen), G/binary, - ?BYTE(SLen), S/binary, ?UINT16(BLen), B/binary>>. - -enc_sign({_, anon}, _Sign, _Version) -> - <<>>; -enc_sign({HashAlg, SignAlg}, Signature, _Version = {Major, Minor}) - when Major == 3, Minor >= 3-> - SignLen = byte_size(Signature), - HashSign = hashsign_enc(HashAlg, SignAlg), - <<HashSign/binary, ?UINT16(SignLen), Signature/binary>>; -enc_sign(_HashSign, Sign, _Version) -> - SignLen = byte_size(Sign), - <<?UINT16(SignLen), Sign/binary>>. - - -ec_hello_extensions(CipherSuites, #elliptic_curves{} = Info) -> - case advertises_ec_ciphers(CipherSuites) of - true -> - [Info]; - false -> - [] - end; -ec_hello_extensions(CipherSuites, #ec_point_formats{} = Info) -> - case advertises_ec_ciphers(CipherSuites) of - true -> - [Info]; - false -> - [] - end; -ec_hello_extensions(_, undefined) -> - []. - -hello_extensions(RenegotiationInfo, NextProtocolNegotiation) -> - hello_extensions(RenegotiationInfo) ++ next_protocol_extension(NextProtocolNegotiation). - -hello_extensions(RenegotiationInfo, SRP, NextProtocolNegotiation) -> - hello_extensions(RenegotiationInfo) - ++ hello_extensions(SRP) - ++ next_protocol_extension(NextProtocolNegotiation). - -advertises_ec_ciphers([]) -> - false; -advertises_ec_ciphers([{ecdh_ecdsa, _,_,_} | _]) -> - true; -advertises_ec_ciphers([{ecdhe_ecdsa, _,_,_} | _]) -> - true; -advertises_ec_ciphers([{ecdh_rsa, _,_,_} | _]) -> - true; -advertises_ec_ciphers([{ecdhe_rsa, _,_,_} | _]) -> - true; -advertises_ec_ciphers([{ecdh_anon, _,_,_} | _]) -> - true; -advertises_ec_ciphers([_| Rest]) -> - advertises_ec_ciphers(Rest). - -%% Renegotiation info -hello_extensions(#renegotiation_info{renegotiated_connection = undefined}) -> - []; -hello_extensions(#renegotiation_info{} = Info) -> - [Info]; -hello_extensions(#srp{} = Info) -> - [Info]; -hello_extensions(#hash_sign_algos{} = Info) -> - [Info]; -hello_extensions(undefined) -> - []. + ExtensionsBin = ssl_handshake:encode_hello_extensions(HelloExtensions), -next_protocol_extension(undefined) -> - []; -next_protocol_extension(#next_protocol_negotiation{} = Info) -> - [Info]. + {?CLIENT_HELLO, <<?BYTE(Major), ?BYTE(Minor), Random:32/binary, + ?BYTE(SIDLength), SessionID/binary, + ?UINT16(CsLength), BinCipherSuites/binary, + ?BYTE(CmLength), BinCompMethods/binary, ExtensionsBin/binary>>}; -enc_hello_extensions(Extensions) -> - enc_hello_extensions(Extensions, <<>>). -enc_hello_extensions([], <<>>) -> - <<>>; -enc_hello_extensions([], Acc) -> - Size = byte_size(Acc), - <<?UINT16(Size), Acc/binary>>; +enc_handshake(HandshakeMsg, Version) -> + ssl_handshake:encode_handshake(HandshakeMsg, Version). -enc_hello_extensions([#next_protocol_negotiation{extension_data = ExtensionData} | Rest], Acc) -> - Len = byte_size(ExtensionData), - enc_hello_extensions(Rest, <<?UINT16(?NEXTPROTONEG_EXT), ?UINT16(Len), ExtensionData/binary, Acc/binary>>); -enc_hello_extensions([#renegotiation_info{renegotiated_connection = ?byte(0) = Info} | Rest], Acc) -> - Len = byte_size(Info), - enc_hello_extensions(Rest, <<?UINT16(?RENEGOTIATION_EXT), ?UINT16(Len), Info/binary, Acc/binary>>); -enc_hello_extensions([#renegotiation_info{renegotiated_connection = Info} | Rest], Acc) -> - InfoLen = byte_size(Info), - Len = InfoLen +1, - enc_hello_extensions(Rest, <<?UINT16(?RENEGOTIATION_EXT), ?UINT16(Len), ?BYTE(InfoLen), Info/binary, Acc/binary>>); -enc_hello_extensions([#elliptic_curves{elliptic_curve_list = EllipticCurves} | Rest], Acc) -> - EllipticCurveList = << <<(ssl_tls1:oid_to_enum(X)):16>> || X <- EllipticCurves>>, - ListLen = byte_size(EllipticCurveList), - Len = ListLen + 2, - enc_hello_extensions(Rest, <<?UINT16(?ELLIPTIC_CURVES_EXT), - ?UINT16(Len), ?UINT16(ListLen), EllipticCurveList/binary, Acc/binary>>); -enc_hello_extensions([#ec_point_formats{ec_point_format_list = ECPointFormats} | Rest], Acc) -> - ECPointFormatList = list_to_binary(ECPointFormats), - ListLen = byte_size(ECPointFormatList), - Len = ListLen + 1, - enc_hello_extensions(Rest, <<?UINT16(?EC_POINT_FORMATS_EXT), - ?UINT16(Len), ?BYTE(ListLen), ECPointFormatList/binary, Acc/binary>>); -enc_hello_extensions([#srp{username = UserName} | Rest], Acc) -> - SRPLen = byte_size(UserName), - Len = SRPLen + 2, - enc_hello_extensions(Rest, <<?UINT16(?SRP_EXT), ?UINT16(Len), ?BYTE(SRPLen), UserName/binary, Acc/binary>>); -enc_hello_extensions([#hash_sign_algos{hash_sign_algos = HashSignAlgos} | Rest], Acc) -> - SignAlgoList = << <<(ssl_cipher:hash_algorithm(Hash)):8, (ssl_cipher:sign_algorithm(Sign)):8>> || - {Hash, Sign} <- HashSignAlgos >>, - ListLen = byte_size(SignAlgoList), - Len = ListLen + 2, - enc_hello_extensions(Rest, <<?UINT16(?SIGNATURE_ALGORITHMS_EXT), - ?UINT16(Len), ?UINT16(ListLen), SignAlgoList/binary, Acc/binary>>). - -encode_client_protocol_negotiation(undefined, _) -> - undefined; -encode_client_protocol_negotiation(_, false) -> - #next_protocol_negotiation{extension_data = <<>>}; -encode_client_protocol_negotiation(_, _) -> - undefined. - -from_3bytes(Bin3) -> - from_3bytes(Bin3, []). - -from_3bytes(<<>>, Acc) -> - lists:reverse(Acc); -from_3bytes(<<?UINT24(N), Rest/binary>>, Acc) -> - from_3bytes(Rest, [?uint16(N) | Acc]). - -from_2bytes(Bin2) -> - from_2bytes(Bin2, []). - -from_2bytes(<<>>, Acc) -> - lists:reverse(Acc); -from_2bytes(<<?UINT16(N), Rest/binary>>, Acc) -> - from_2bytes(Rest, [?uint16(N) | Acc]). - -certificate_types({KeyExchange, _, _, _}) - when KeyExchange == rsa; - KeyExchange == dhe_dss; - KeyExchange == dhe_rsa; - KeyExchange == ecdhe_rsa -> - <<?BYTE(?RSA_SIGN), ?BYTE(?DSS_SIGN)>>; - -certificate_types({KeyExchange, _, _, _}) - when KeyExchange == dh_ecdsa; - KeyExchange == dhe_ecdsa -> - <<?BYTE(?ECDSA_SIGN)>>; - -certificate_types(_) -> - <<?BYTE(?RSA_SIGN)>>. - -hashsign_dec(<<?BYTE(HashAlgo), ?BYTE(SignAlgo)>>) -> - {ssl_cipher:hash_algorithm(HashAlgo), ssl_cipher:sign_algorithm(SignAlgo)}. - -hashsign_enc(HashAlgo, SignAlgo) -> - Hash = ssl_cipher:hash_algorithm(HashAlgo), - Sign = ssl_cipher:sign_algorithm(SignAlgo), - <<?BYTE(Hash), ?BYTE(Sign)>>. - -certificate_authorities(CertDbHandle, CertDbRef) -> - Authorities = certificate_authorities_from_db(CertDbHandle, CertDbRef), - Enc = fun(#'OTPCertificate'{tbsCertificate=TBSCert}) -> - OTPSubj = TBSCert#'OTPTBSCertificate'.subject, - DNEncodedBin = public_key:pkix_encode('Name', OTPSubj, otp), - DNEncodedLen = byte_size(DNEncodedBin), - <<?UINT16(DNEncodedLen), DNEncodedBin/binary>> - end, - list_to_binary([Enc(Cert) || {_, Cert} <- Authorities]). - -certificate_authorities_from_db(CertDbHandle, CertDbRef) -> - ConnectionCerts = fun({{Ref, _, _}, Cert}, Acc) when Ref == CertDbRef -> - [Cert | Acc]; - (_, Acc) -> - Acc - end, - ssl_pkix_db:foldl(ConnectionCerts, [], CertDbHandle). - - -digitally_signed({3, Minor}, Hash, HashAlgo, Key) when Minor >= 3 -> - public_key:sign({digest, Hash}, HashAlgo, Key); -digitally_signed(_Version, Hash, HashAlgo, #'DSAPrivateKey'{} = Key) -> - public_key:sign({digest, Hash}, HashAlgo, Key); -digitally_signed(_Version, Hash, _HashAlgo, #'RSAPrivateKey'{} = Key) -> - public_key:encrypt_private(Hash, Key, - [{rsa_pad, rsa_pkcs1_padding}]); -digitally_signed(_Version, Hash, HashAlgo, Key) -> - public_key:sign({digest, Hash}, HashAlgo, Key). - -calc_master_secret({3,0}, _PrfAlgo, PremasterSecret, ClientRandom, ServerRandom) -> - ssl_ssl3:master_secret(PremasterSecret, ClientRandom, ServerRandom); - -calc_master_secret({3,_}, PrfAlgo, PremasterSecret, ClientRandom, ServerRandom) -> - ssl_tls1:master_secret(PrfAlgo, PremasterSecret, ClientRandom, ServerRandom). - -setup_keys({3,0}, _PrfAlgo, MasterSecret, - ServerRandom, ClientRandom, HashSize, KML, EKML, IVS) -> - ssl_ssl3:setup_keys(MasterSecret, ServerRandom, - ClientRandom, HashSize, KML, EKML, IVS); - -setup_keys({3,N}, PrfAlgo, MasterSecret, - ServerRandom, ClientRandom, HashSize, KML, _EKML, IVS) -> - ssl_tls1:setup_keys(N, PrfAlgo, MasterSecret, ServerRandom, ClientRandom, HashSize, - KML, IVS). - -calc_finished({3, 0}, Role, _PrfAlgo, MasterSecret, Handshake) -> - ssl_ssl3:finished(Role, MasterSecret, lists:reverse(Handshake)); -calc_finished({3, N}, Role, PrfAlgo, MasterSecret, Handshake) -> - ssl_tls1:finished(Role, N, PrfAlgo, MasterSecret, lists:reverse(Handshake)). - -calc_certificate_verify({3, 0}, HashAlgo, MasterSecret, Handshake) -> - ssl_ssl3:certificate_verify(HashAlgo, MasterSecret, lists:reverse(Handshake)); -calc_certificate_verify({3, N}, HashAlgo, _MasterSecret, Handshake) -> - ssl_tls1:certificate_verify(HashAlgo, N, lists:reverse(Handshake)). - -key_exchange_alg(rsa) -> - ?KEY_EXCHANGE_RSA; -key_exchange_alg(Alg) when Alg == dhe_rsa; Alg == dhe_dss; - Alg == dh_dss; Alg == dh_rsa; Alg == dh_anon -> - ?KEY_EXCHANGE_DIFFIE_HELLMAN; -key_exchange_alg(Alg) when Alg == ecdhe_rsa; Alg == ecdh_rsa; - Alg == ecdhe_ecdsa; Alg == ecdh_ecdsa; - Alg == ecdh_anon -> - ?KEY_EXCHANGE_EC_DIFFIE_HELLMAN; -key_exchange_alg(psk) -> - ?KEY_EXCHANGE_PSK; -key_exchange_alg(dhe_psk) -> - ?KEY_EXCHANGE_DHE_PSK; -key_exchange_alg(rsa_psk) -> - ?KEY_EXCHANGE_RSA_PSK; -key_exchange_alg(Alg) - when Alg == srp_rsa; Alg == srp_dss; Alg == srp_anon -> - ?KEY_EXCHANGE_SRP; -key_exchange_alg(_) -> - ?NULL. - -apply_user_fun(Fun, OtpCert, ExtensionOrError, UserState0, SslState) -> - case Fun(OtpCert, ExtensionOrError, UserState0) of - {valid, UserState} -> - {valid, {SslState, UserState}}; - {fail, _} = Fail -> - Fail; - {unknown, UserState} -> - {unknown, {SslState, UserState}} +handle_hello_extensions(Version, Type, Random, HelloExt, SslOpts, Session0, ConnectionStates0, Renegotiation) -> + try ssl_handshake:handle_client_hello_extensions(tls_record, Random, HelloExt, Version, SslOpts, + Session0, ConnectionStates0, Renegotiation) of + {Session, ConnectionStates, ServerHelloExt} -> + {Version, {Type, Session}, ConnectionStates, ServerHelloExt} + catch throw:Alert -> + Alert end. --define(TLSEXT_SIGALG_RSA(MD), {MD, rsa}). --define(TLSEXT_SIGALG_DSA(MD), {MD, dsa}). --define(TLSEXT_SIGALG_ECDSA(MD), {MD, ecdsa}). - --define(TLSEXT_SIGALG(MD), ?TLSEXT_SIGALG_ECDSA(MD), ?TLSEXT_SIGALG_RSA(MD)). -default_hash_signs() -> - HashSigns = [?TLSEXT_SIGALG(sha512), - ?TLSEXT_SIGALG(sha384), - ?TLSEXT_SIGALG(sha256), - ?TLSEXT_SIGALG(sha224), - ?TLSEXT_SIGALG(sha), - ?TLSEXT_SIGALG_DSA(sha), - ?TLSEXT_SIGALG_RSA(md5)], - CryptoSupport = proplists:get_value(public_keys, crypto:supports()), - HasECC = proplists:get_bool(ecdsa, CryptoSupport), - #hash_sign_algos{hash_sign_algos = - lists:filter(fun({_, ecdsa}) -> HasECC; - (_) -> true end, HashSigns)}. - -handle_hello_extensions(#client_hello{random = Random, - cipher_suites = CipherSuites, - renegotiation_info = Info, - srp = SRP, - ec_point_formats = EcPointFormats0, - elliptic_curves = EllipticCurves0} = Hello, Version, - #ssl_options{secure_renegotiate = SecureRenegotation} = Opts, - Session0, ConnectionStates0, Renegotiation) -> - Session = handle_srp_extension(SRP, Session0), - ConnectionStates = handle_renegotiation_extension(Version, Info, Random, Session, ConnectionStates0, - Renegotiation, SecureRenegotation, CipherSuites), - ProtocolsToAdvertise = handle_next_protocol_extension(Hello, Renegotiation, Opts), - {EcPointFormats, EllipticCurves} = handle_ecc_extensions(Version, EcPointFormats0, EllipticCurves0), - %%TODO make extensions compund data structure - {Session, ConnectionStates, ProtocolsToAdvertise, EcPointFormats, EllipticCurves}. - - -handle_renegotiation_extension(Version, Info, Random, #session{cipher_suite = CipherSuite, - compression_method = Compression}, - ConnectionStates0, Renegotiation, SecureRenegotation, CipherSuites) -> - case handle_renegotiation_info(server, Info, ConnectionStates0, - Renegotiation, SecureRenegotation, - CipherSuites) of - {ok, ConnectionStates1} -> - hello_pending_connection_states(server, - Version, - CipherSuite, - Random, - Compression, - ConnectionStates1); +handle_hello_extensions(Version, SessionId, Random, CipherSuite, + Compression, HelloExt, SslOpt, ConnectionStates0, Renegotiation) -> + case ssl_handshake:handle_server_hello_extensions(tls_record, Random, CipherSuite, + Compression, HelloExt, Version, + SslOpt, ConnectionStates0, Renegotiation) of #alert{} = Alert -> - throw(Alert) + Alert; + {ConnectionStates, Protocol} -> + {Version, SessionId, ConnectionStates, Protocol} end. -handle_next_protocol_extension(Hello, Renegotiation, SslOpts)-> - case handle_next_protocol_on_server(Hello, Renegotiation, SslOpts) of - #alert{} = Alert -> - throw(Alert); - ProtocolsToAdvertise -> - ProtocolsToAdvertise - end. - -handle_srp_extension(undefined, Session) -> - Session; -handle_srp_extension(#srp{username = Username}, Session) -> - Session#session{srp_username = Username}. - -int_to_bin(I) -> - L = (length(integer_to_list(I, 16)) + 1) div 2, - <<I:(L*8)>>. diff --git a/lib/ssl/src/tls_handshake.hrl b/lib/ssl/src/tls_handshake.hrl index abf1b5abb6..dbe930cb90 100644 --- a/lib/ssl/src/tls_handshake.hrl +++ b/lib/ssl/src/tls_handshake.hrl @@ -34,12 +34,9 @@ cipher_suites, % cipher_suites<2..2^16-1> compression_methods, % compression_methods<1..2^8-1>, %% Extensions - renegotiation_info, - hash_signs, % supported combinations of hashes/signature algos - next_protocol_negotiation = undefined, % [binary()] - srp, - ec_point_formats, - elliptic_curves + extensions }). +-type tls_handshake() :: #client_hello{} | ssl_handshake(). + -endif. % -ifdef(tls_handshake). diff --git a/lib/ssl/src/tls_record.erl b/lib/ssl/src/tls_record.erl index 1409a04763..54cf8d0b80 100644 --- a/lib/ssl/src/tls_record.erl +++ b/lib/ssl/src/tls_record.erl @@ -19,8 +19,7 @@ %% %%---------------------------------------------------------------------- -%% Purpose: Help functions for handling the SSL-Record protocol -%% +%% Purpose: Handle TLS/SSL record protocol. (Parts that are not shared with DTLS) %%---------------------------------------------------------------------- -module(tls_record). @@ -31,282 +30,27 @@ -include("tls_handshake.hrl"). -include("ssl_cipher.hrl"). -%% Connection state handling --export([init_connection_states/1, - current_connection_state/2, pending_connection_state/2, - update_security_params/3, - set_mac_secret/4, - set_master_secret/2, - activate_pending_connection_state/2, - set_pending_cipher_state/4, - set_renegotiation_flag/2, - set_client_verify_data/3, - set_server_verify_data/3]). - %% Handling of incoming data -export([get_tls_records/2]). -%% Encoding records --export([encode_handshake/3, encode_alert_record/3, - encode_change_cipher_spec/2, encode_data/3]). - %% Decoding -export([decode_cipher_text/2]). -%% Misc. +%% Encoding +-export([encode_plain_text/4]). + +%% Protocol version handling -export([protocol_version/1, lowest_protocol_version/2, highest_protocol_version/1, supported_protocol_versions/0, is_acceptable_version/1, is_acceptable_version/2]). --export([compressions/0]). - -compile(inline). --define(INITIAL_BYTES, 5). - %%==================================================================== %% Internal application API %%==================================================================== %%-------------------------------------------------------------------- --spec init_connection_states(client | server) -> #connection_states{}. -%% -%% Description: Creates a connection_states record with appropriate -%% values for the initial SSL connection setup. -%%-------------------------------------------------------------------- -init_connection_states(Role) -> - ConnectionEnd = record_protocol_role(Role), - Current = initial_connection_state(ConnectionEnd), - Pending = empty_connection_state(ConnectionEnd), - #connection_states{current_read = Current, - pending_read = Pending, - current_write = Current, - pending_write = Pending - }. - -%%-------------------------------------------------------------------- --spec current_connection_state(#connection_states{}, read | write) -> - #connection_state{}. -%% -%% Description: Returns the instance of the connection_state record -%% that is currently defined as the current conection state. -%%-------------------------------------------------------------------- -current_connection_state(#connection_states{current_read = Current}, - read) -> - Current; -current_connection_state(#connection_states{current_write = Current}, - write) -> - Current. - -%%-------------------------------------------------------------------- --spec pending_connection_state(#connection_states{}, read | write) -> - #connection_state{}. -%% -%% Description: Returns the instance of the connection_state record -%% that is currently defined as the pending conection state. -%%-------------------------------------------------------------------- -pending_connection_state(#connection_states{pending_read = Pending}, - read) -> - Pending; -pending_connection_state(#connection_states{pending_write = Pending}, - write) -> - Pending. - -%%-------------------------------------------------------------------- --spec update_security_params(#security_parameters{}, #security_parameters{}, - #connection_states{}) -> #connection_states{}. -%% -%% Description: Creates a new instance of the connection_states record -%% where the pending states gets its security parameters updated. -%%-------------------------------------------------------------------- -update_security_params(ReadParams, WriteParams, States = - #connection_states{pending_read = Read, - pending_write = Write}) -> - States#connection_states{pending_read = - Read#connection_state{security_parameters = - ReadParams}, - pending_write = - Write#connection_state{security_parameters = - WriteParams} - }. -%%-------------------------------------------------------------------- --spec set_mac_secret(binary(), binary(), client | server, - #connection_states{}) -> #connection_states{}. -%% -%% Description: update the mac_secret field in pending connection states -%%-------------------------------------------------------------------- -set_mac_secret(ClientWriteMacSecret, ServerWriteMacSecret, client, States) -> - set_mac_secret(ServerWriteMacSecret, ClientWriteMacSecret, States); -set_mac_secret(ClientWriteMacSecret, ServerWriteMacSecret, server, States) -> - set_mac_secret(ClientWriteMacSecret, ServerWriteMacSecret, States). - -set_mac_secret(ReadMacSecret, WriteMacSecret, - States = #connection_states{pending_read = Read, - pending_write = Write}) -> - States#connection_states{ - pending_read = Read#connection_state{mac_secret = ReadMacSecret}, - pending_write = Write#connection_state{mac_secret = WriteMacSecret} - }. - - -%%-------------------------------------------------------------------- --spec set_master_secret(binary(), #connection_states{}) -> #connection_states{}. -%% -%% Description: Set master_secret in pending connection states -%%-------------------------------------------------------------------- -set_master_secret(MasterSecret, - States = #connection_states{pending_read = Read, - pending_write = Write}) -> - ReadSecPar = Read#connection_state.security_parameters, - Read1 = Read#connection_state{ - security_parameters = ReadSecPar#security_parameters{ - master_secret = MasterSecret}}, - WriteSecPar = Write#connection_state.security_parameters, - Write1 = Write#connection_state{ - security_parameters = WriteSecPar#security_parameters{ - master_secret = MasterSecret}}, - States#connection_states{pending_read = Read1, pending_write = Write1}. - -%%-------------------------------------------------------------------- --spec set_renegotiation_flag(boolean(), #connection_states{}) -> #connection_states{}. -%% -%% Description: Set secure_renegotiation in pending connection states -%%-------------------------------------------------------------------- -set_renegotiation_flag(Flag, #connection_states{ - current_read = CurrentRead0, - current_write = CurrentWrite0, - pending_read = PendingRead0, - pending_write = PendingWrite0} - = ConnectionStates) -> - CurrentRead = CurrentRead0#connection_state{secure_renegotiation = Flag}, - CurrentWrite = CurrentWrite0#connection_state{secure_renegotiation = Flag}, - PendingRead = PendingRead0#connection_state{secure_renegotiation = Flag}, - PendingWrite = PendingWrite0#connection_state{secure_renegotiation = Flag}, - ConnectionStates#connection_states{current_read = CurrentRead, - current_write = CurrentWrite, - pending_read = PendingRead, - pending_write = PendingWrite}. - -%%-------------------------------------------------------------------- --spec set_client_verify_data(current_read | current_write | current_both, - binary(), #connection_states{})-> - #connection_states{}. -%% -%% Description: Set verify data in connection states. -%%-------------------------------------------------------------------- -set_client_verify_data(current_read, Data, - #connection_states{current_read = CurrentRead0, - pending_write = PendingWrite0} - = ConnectionStates) -> - CurrentRead = CurrentRead0#connection_state{client_verify_data = Data}, - PendingWrite = PendingWrite0#connection_state{client_verify_data = Data}, - ConnectionStates#connection_states{current_read = CurrentRead, - pending_write = PendingWrite}; -set_client_verify_data(current_write, Data, - #connection_states{pending_read = PendingRead0, - current_write = CurrentWrite0} - = ConnectionStates) -> - PendingRead = PendingRead0#connection_state{client_verify_data = Data}, - CurrentWrite = CurrentWrite0#connection_state{client_verify_data = Data}, - ConnectionStates#connection_states{pending_read = PendingRead, - current_write = CurrentWrite}; -set_client_verify_data(current_both, Data, - #connection_states{current_read = CurrentRead0, - current_write = CurrentWrite0} - = ConnectionStates) -> - CurrentRead = CurrentRead0#connection_state{client_verify_data = Data}, - CurrentWrite = CurrentWrite0#connection_state{client_verify_data = Data}, - ConnectionStates#connection_states{current_read = CurrentRead, - current_write = CurrentWrite}. -%%-------------------------------------------------------------------- --spec set_server_verify_data(current_read | current_write | current_both, - binary(), #connection_states{})-> - #connection_states{}. -%% -%% Description: Set verify data in pending connection states. -%%-------------------------------------------------------------------- -set_server_verify_data(current_write, Data, - #connection_states{pending_read = PendingRead0, - current_write = CurrentWrite0} - = ConnectionStates) -> - PendingRead = PendingRead0#connection_state{server_verify_data = Data}, - CurrentWrite = CurrentWrite0#connection_state{server_verify_data = Data}, - ConnectionStates#connection_states{pending_read = PendingRead, - current_write = CurrentWrite}; - -set_server_verify_data(current_read, Data, - #connection_states{current_read = CurrentRead0, - pending_write = PendingWrite0} - = ConnectionStates) -> - CurrentRead = CurrentRead0#connection_state{server_verify_data = Data}, - PendingWrite = PendingWrite0#connection_state{server_verify_data = Data}, - ConnectionStates#connection_states{current_read = CurrentRead, - pending_write = PendingWrite}; - -set_server_verify_data(current_both, Data, - #connection_states{current_read = CurrentRead0, - current_write = CurrentWrite0} - = ConnectionStates) -> - CurrentRead = CurrentRead0#connection_state{server_verify_data = Data}, - CurrentWrite = CurrentWrite0#connection_state{server_verify_data = Data}, - ConnectionStates#connection_states{current_read = CurrentRead, - current_write = CurrentWrite}. - -%%-------------------------------------------------------------------- --spec activate_pending_connection_state(#connection_states{}, read | write) -> - #connection_states{}. -%% -%% Description: Creates a new instance of the connection_states record -%% where the pending state of <Type> has been activated. -%%-------------------------------------------------------------------- -activate_pending_connection_state(States = - #connection_states{pending_read = Pending}, - read) -> - NewCurrent = Pending#connection_state{sequence_number = 0}, - SecParams = Pending#connection_state.security_parameters, - ConnectionEnd = SecParams#security_parameters.connection_end, - EmptyPending = empty_connection_state(ConnectionEnd), - SecureRenegotation = NewCurrent#connection_state.secure_renegotiation, - NewPending = EmptyPending#connection_state{secure_renegotiation = SecureRenegotation}, - States#connection_states{current_read = NewCurrent, - pending_read = NewPending - }; - -activate_pending_connection_state(States = - #connection_states{pending_write = Pending}, - write) -> - NewCurrent = Pending#connection_state{sequence_number = 0}, - SecParams = Pending#connection_state.security_parameters, - ConnectionEnd = SecParams#security_parameters.connection_end, - EmptyPending = empty_connection_state(ConnectionEnd), - SecureRenegotation = NewCurrent#connection_state.secure_renegotiation, - NewPending = EmptyPending#connection_state{secure_renegotiation = SecureRenegotation}, - States#connection_states{current_write = NewCurrent, - pending_write = NewPending - }. - -%%-------------------------------------------------------------------- --spec set_pending_cipher_state(#connection_states{}, #cipher_state{}, - #cipher_state{}, client | server) -> - #connection_states{}. -%% -%% Description: Set the cipher state in the specified pending connection state. -%%-------------------------------------------------------------------- -set_pending_cipher_state(#connection_states{pending_read = Read, - pending_write = Write} = States, - ClientState, ServerState, server) -> - States#connection_states{ - pending_read = Read#connection_state{cipher_state = ClientState}, - pending_write = Write#connection_state{cipher_state = ServerState}}; - -set_pending_cipher_state(#connection_states{pending_read = Read, - pending_write = Write} = States, - ClientState, ServerState, client) -> - States#connection_states{ - pending_read = Read#connection_state{cipher_state = ServerState}, - pending_write = Write#connection_state{cipher_state = ClientState}}. - -%%-------------------------------------------------------------------- -spec get_tls_records(binary(), binary()) -> {[binary()], binary()} | #alert{}. %% %% Description: Given old buffer and new data from TCP, packs up a records @@ -376,6 +120,43 @@ get_tls_records_aux(Data, Acc) -> false -> ?ALERT_REC(?FATAL, ?UNEXPECTED_MESSAGE) end. + +encode_plain_text(Type, Version, Data, ConnectionStates) -> + #connection_states{current_write=#connection_state{ + compression_state=CompS0, + security_parameters= + #security_parameters{compression_algorithm=CompAlg} + }=CS0} = ConnectionStates, + {Comp, CompS1} = ssl_record:compress(CompAlg, Data, CompS0), + CS1 = CS0#connection_state{compression_state = CompS1}, + {CipherFragment, CS2} = cipher(Type, Version, Comp, CS1), + CTBin = encode_tls_cipher_text(Type, Version, CipherFragment), + {CTBin, ConnectionStates#connection_states{current_write = CS2}}. + +%%-------------------------------------------------------------------- +-spec decode_cipher_text(#ssl_tls{}, #connection_states{}) -> + {#ssl_tls{}, #connection_states{}}| #alert{}. +%% +%% Description: Decode cipher text +%%-------------------------------------------------------------------- +decode_cipher_text(#ssl_tls{type = Type, version = Version, + fragment = CipherFragment} = CipherText, ConnnectionStates0) -> + ReadState0 = ConnnectionStates0#connection_states.current_read, + #connection_state{compression_state = CompressionS0, + security_parameters = SecParams} = ReadState0, + CompressAlg = SecParams#security_parameters.compression_algorithm, + case decipher(Type, Version, CipherFragment, ReadState0) of + {PlainFragment, ReadState1} -> + {Plain, CompressionS1} = ssl_record:uncompress(CompressAlg, + PlainFragment, CompressionS0), + ConnnectionStates = ConnnectionStates0#connection_states{ + current_read = ReadState1#connection_state{ + compression_state = CompressionS1}}, + {CipherText#ssl_tls{fragment = Plain}, ConnnectionStates}; + #alert{} = Alert -> + Alert + end. + %%-------------------------------------------------------------------- -spec protocol_version(tls_atom_version() | tls_version()) -> tls_version() | tls_atom_version(). @@ -493,183 +274,39 @@ is_acceptable_version(_,_) -> false. %%-------------------------------------------------------------------- --spec compressions() -> [binary()]. -%% -%% Description: return a list of compressions supported (currently none) -%%-------------------------------------------------------------------- -compressions() -> - [?byte(?NULL)]. - -%%-------------------------------------------------------------------- --spec decode_cipher_text(#ssl_tls{}, #connection_states{}) -> - {#ssl_tls{}, #connection_states{}}| #alert{}. -%% -%% Description: Decode cipher text -%%-------------------------------------------------------------------- -decode_cipher_text(CipherText, ConnnectionStates0) -> - ReadState0 = ConnnectionStates0#connection_states.current_read, - #connection_state{compression_state = CompressionS0, - security_parameters = SecParams} = ReadState0, - CompressAlg = SecParams#security_parameters.compression_algorithm, - case decipher(CipherText, ReadState0) of - {Compressed, ReadState1} -> - {Plain, CompressionS1} = uncompress(CompressAlg, - Compressed, CompressionS0), - ConnnectionStates = ConnnectionStates0#connection_states{ - current_read = ReadState1#connection_state{ - compression_state = CompressionS1}}, - {Plain, ConnnectionStates}; - #alert{} = Alert -> - Alert - end. -%%-------------------------------------------------------------------- --spec encode_data(binary(), tls_version(), #connection_states{}) -> - {iolist(), #connection_states{}}. -%% -%% Description: Encodes data to send on the ssl-socket. -%%-------------------------------------------------------------------- -encode_data(Frag, Version, - #connection_states{current_write = #connection_state{ - security_parameters = - #security_parameters{bulk_cipher_algorithm = BCA}}} = - ConnectionStates) -> - Data = split_bin(Frag, ?MAX_PLAIN_TEXT_LENGTH, Version, BCA), - encode_iolist(?APPLICATION_DATA, Data, Version, ConnectionStates). - -%%-------------------------------------------------------------------- --spec encode_handshake(iolist(), tls_version(), #connection_states{}) -> - {iolist(), #connection_states{}}. -%% -%% Description: Encodes a handshake message to send on the ssl-socket. -%%-------------------------------------------------------------------- -encode_handshake(Frag, Version, ConnectionStates) -> - encode_plain_text(?HANDSHAKE, Version, Frag, ConnectionStates). - -%%-------------------------------------------------------------------- --spec encode_alert_record(#alert{}, tls_version(), #connection_states{}) -> - {iolist(), #connection_states{}}. -%% -%% Description: Encodes an alert message to send on the ssl-socket. -%%-------------------------------------------------------------------- -encode_alert_record(#alert{level = Level, description = Description}, - Version, ConnectionStates) -> - encode_plain_text(?ALERT, Version, <<?BYTE(Level), ?BYTE(Description)>>, - ConnectionStates). - -%%-------------------------------------------------------------------- --spec encode_change_cipher_spec(tls_version(), #connection_states{}) -> - {iolist(), #connection_states{}}. -%% -%% Description: Encodes a change_cipher_spec-message to send on the ssl socket. -%%-------------------------------------------------------------------- -encode_change_cipher_spec(Version, ConnectionStates) -> - encode_plain_text(?CHANGE_CIPHER_SPEC, Version, <<1:8>>, ConnectionStates). - -%%-------------------------------------------------------------------- %%% Internal functions %%-------------------------------------------------------------------- -encode_iolist(Type, Data, Version, ConnectionStates0) -> - {ConnectionStates, EncodedMsg} = - lists:foldl(fun(Text, {CS0, Encoded}) -> - {Enc, CS1} = encode_plain_text(Type, Version, Text, CS0), - {CS1, [Enc | Encoded]} - end, {ConnectionStates0, []}, Data), - {lists:reverse(EncodedMsg), ConnectionStates}. - -highest_protocol_version() -> - highest_protocol_version(supported_protocol_versions()). - -initial_connection_state(ConnectionEnd) -> - #connection_state{security_parameters = - initial_security_params(ConnectionEnd), - sequence_number = 0 - }. - -initial_security_params(ConnectionEnd) -> - SecParams = #security_parameters{connection_end = ConnectionEnd, - compression_algorithm = ?NULL}, - ssl_cipher:security_parameters(highest_protocol_version(), ?TLS_NULL_WITH_NULL_NULL, - SecParams). - -empty_connection_state(ConnectionEnd) -> - SecParams = empty_security_params(ConnectionEnd), - #connection_state{security_parameters = SecParams}. - -empty_security_params(ConnectionEnd = ?CLIENT) -> - #security_parameters{connection_end = ConnectionEnd, - client_random = random()}; -empty_security_params(ConnectionEnd = ?SERVER) -> - #security_parameters{connection_end = ConnectionEnd, - server_random = random()}. -random() -> - Secs_since_1970 = calendar:datetime_to_gregorian_seconds( - calendar:universal_time()) - 62167219200, - Random_28_bytes = crypto:rand_bytes(28), - <<?UINT32(Secs_since_1970), Random_28_bytes/binary>>. - -record_protocol_role(client) -> - ?CLIENT; -record_protocol_role(server) -> - ?SERVER. - -%% 1/n-1 splitting countermeasure Rizzo/Duong-Beast, RC4 chiphers are not vulnerable to this attack. -split_bin(<<FirstByte:8, Rest/binary>>, ChunkSize, Version, BCA) when BCA =/= ?RC4 andalso ({3, 1} == Version orelse - {3, 0} == Version) -> - do_split_bin(Rest, ChunkSize, [[FirstByte]]); -split_bin(Bin, ChunkSize, _, _) -> - do_split_bin(Bin, ChunkSize, []). - -do_split_bin(<<>>, _, Acc) -> - lists:reverse(Acc); -do_split_bin(Bin, ChunkSize, Acc) -> - case Bin of - <<Chunk:ChunkSize/binary, Rest/binary>> -> - do_split_bin(Rest, ChunkSize, [Chunk | Acc]); - _ -> - lists:reverse(Acc, [Bin]) - end. - -encode_plain_text(Type, Version, Data, ConnectionStates) -> - #connection_states{current_write=#connection_state{ - compression_state=CompS0, - security_parameters= - #security_parameters{compression_algorithm=CompAlg} - }=CS0} = ConnectionStates, - {Comp, CompS1} = compress(CompAlg, Data, CompS0), - CS1 = CS0#connection_state{compression_state = CompS1}, - {CipherText, CS2} = cipher(Type, Version, Comp, CS1), - CTBin = encode_tls_cipher_text(Type, Version, CipherText), - {CTBin, ConnectionStates#connection_states{current_write = CS2}}. - encode_tls_cipher_text(Type, {MajVer, MinVer}, Fragment) -> Length = erlang:iolist_size(Fragment), [<<?BYTE(Type), ?BYTE(MajVer), ?BYTE(MinVer), ?UINT16(Length)>>, Fragment]. -cipher(Type, Version, Fragment, CS0) -> - Length = erlang:iolist_size(Fragment), - {MacHash, CS1=#connection_state{cipher_state = CipherS0, - security_parameters= - #security_parameters{bulk_cipher_algorithm = +cipher(Type, Version, Fragment, + #connection_state{cipher_state = CipherS0, + sequence_number = SeqNo, + security_parameters= + #security_parameters{bulk_cipher_algorithm = BCA} - }} = - hash_and_bump_seqno(CS0, Type, Version, Length, Fragment), - {Ciphered, CipherS1} = ssl_cipher:cipher(BCA, CipherS0, MacHash, Fragment, Version), - CS2 = CS1#connection_state{cipher_state=CipherS1}, - {Ciphered, CS2}. - -decipher(TLS=#ssl_tls{type=Type, version=Version, fragment=Fragment}, CS0) -> - SP = CS0#connection_state.security_parameters, + } = WriteState0) -> + MacHash = calc_mac_hash(Type, Version, Fragment, WriteState0), + {CipherFragment, CipherS1} = + ssl_cipher:cipher(BCA, CipherS0, MacHash, Fragment, Version), + WriteState = WriteState0#connection_state{cipher_state=CipherS1}, + {CipherFragment, WriteState#connection_state{sequence_number = SeqNo+1}}. + +decipher(Type, Version, CipherFragment, + #connection_state{sequence_number = SeqNo} = ReadState) -> + SP = ReadState#connection_state.security_parameters, BCA = SP#security_parameters.bulk_cipher_algorithm, HashSz = SP#security_parameters.hash_size, - CipherS0 = CS0#connection_state.cipher_state, - case ssl_cipher:decipher(BCA, HashSz, CipherS0, Fragment, Version) of - {T, Mac, CipherS1} -> - CS1 = CS0#connection_state{cipher_state = CipherS1}, - TLength = size(T), - {MacHash, CS2} = hash_and_bump_seqno(CS1, Type, Version, TLength, T), - case is_correct_mac(Mac, MacHash) of - true -> - {TLS#ssl_tls{fragment = T}, CS2}; + CipherS0 = ReadState#connection_state.cipher_state, + case ssl_cipher:decipher(BCA, HashSz, CipherS0, CipherFragment, Version) of + {PlainFragment, Mac, CipherS1} -> + CS1 = ReadState#connection_state{cipher_state = CipherS1}, + MacHash = calc_mac_hash(Type, Version, PlainFragment, ReadState), + case ssl_record:is_correct_mac(Mac, MacHash) of + true -> + {PlainFragment, + CS1#connection_state{sequence_number = SeqNo+1}}; false -> ?ALERT_REC(?FATAL, ?BAD_RECORD_MAC) end; @@ -677,40 +314,29 @@ decipher(TLS=#ssl_tls{type=Type, version=Version, fragment=Fragment}, CS0) -> Alert end. -uncompress(?NULL, Data = #ssl_tls{type = _Type, - version = _Version, - fragment = _Fragment}, CS) -> - {Data, CS}. - -compress(?NULL, Data, CS) -> - {Data, CS}. - -hash_and_bump_seqno(#connection_state{sequence_number = SeqNo, - mac_secret = MacSecret, - security_parameters = - SecPars} = CS0, - Type, Version, Length, Fragment) -> - Hash = mac_hash(Version, - SecPars#security_parameters.mac_algorithm, - MacSecret, SeqNo, Type, - Length, Fragment), - {Hash, CS0#connection_state{sequence_number = SeqNo+1}}. - -is_correct_mac(Mac, Mac) -> - true; -is_correct_mac(_M,_H) -> - false. - mac_hash({_,_}, ?NULL, _MacSecret, _SeqNo, _Type, _Length, _Fragment) -> <<>>; mac_hash({3, 0}, MacAlg, MacSecret, SeqNo, Type, Length, Fragment) -> - ssl_ssl3:mac_hash(MacAlg, MacSecret, SeqNo, Type, Length, Fragment); + ssl_v3:mac_hash(MacAlg, MacSecret, SeqNo, Type, Length, Fragment); mac_hash({3, N} = Version, MacAlg, MacSecret, SeqNo, Type, Length, Fragment) when N =:= 1; N =:= 2; N =:= 3 -> - ssl_tls1:mac_hash(MacAlg, MacSecret, SeqNo, Type, Version, + tls_v1:mac_hash(MacAlg, MacSecret, SeqNo, Type, Version, Length, Fragment). +highest_protocol_version() -> + highest_protocol_version(supported_protocol_versions()). + sufficient_tlsv1_2_crypto_support() -> CryptoSupport = crypto:supports(), proplists:get_bool(sha256, proplists:get_value(hashs, CryptoSupport)). + +calc_mac_hash(Type, Version, + PlainFragment, #connection_state{sequence_number = SeqNo, + mac_secret = MacSecret, + security_parameters = + SecPars}) -> + Length = erlang:iolist_size(PlainFragment), + mac_hash(Version, SecPars#security_parameters.mac_algorithm, + MacSecret, SeqNo, Type, + Length, PlainFragment). diff --git a/lib/ssl/src/tls_record.hrl b/lib/ssl/src/tls_record.hrl index c9350fa137..30d7343074 100644 --- a/lib/ssl/src/tls_record.hrl +++ b/lib/ssl/src/tls_record.hrl @@ -29,7 +29,6 @@ -include("ssl_record.hrl"). %% Common TLS and DTLS records and Constantes %% Used to handle tls_plain_text, tls_compressed and tls_cipher_text - -record(ssl_tls, { type, version, diff --git a/lib/ssl/src/ssl_tls1.erl b/lib/ssl/src/tls_v1.erl index 8ab66d0627..2395e98642 100644 --- a/lib/ssl/src/ssl_tls1.erl +++ b/lib/ssl/src/tls_v1.erl @@ -22,7 +22,7 @@ %% Purpose: Handles tls1 encryption. %%---------------------------------------------------------------------- --module(ssl_tls1). +-module(tls_v1). -include("ssl_cipher.hrl"). -include("ssl_internal.hrl"). @@ -86,7 +86,7 @@ certificate_verify(HashAlgo, _Version, Handshake) -> -spec setup_keys(integer(), integer(), binary(), binary(), binary(), integer(), integer(), integer()) -> {binary(), binary(), binary(), - binary(), binary(), binary()}. + binary(), binary(), binary()}. setup_keys(Version, _PrfAlgo, MasterSecret, ServerRandom, ClientRandom, HashSize, KeyMatLen, IVSize) @@ -106,7 +106,7 @@ setup_keys(Version, _PrfAlgo, MasterSecret, ServerRandom, ClientRandom, HashSize WantedLength = 2 * (HashSize + KeyMatLen + IVSize), KeyBlock = prf(?MD5SHA, MasterSecret, "key expansion", [ServerRandom, ClientRandom], WantedLength), - <<ClientWriteMacSecret:HashSize/binary, + <<ClientWriteMacSecret:HashSize/binary, ServerWriteMacSecret:HashSize/binary, ClientWriteKey:KeyMatLen/binary, ServerWriteKey:KeyMatLen/binary, ClientIV:IVSize/binary, ServerIV:IVSize/binary>> = KeyBlock, @@ -167,22 +167,22 @@ setup_keys(Version, PrfAlgo, MasterSecret, ServerRandom, ClientRandom, HashSize, ServerWriteKey, ClientIV, ServerIV}. -spec mac_hash(integer(), binary(), integer(), integer(), tls_version(), - integer(), binary()) -> binary(). + integer(), binary()) -> binary(). -mac_hash(Method, Mac_write_secret, Seq_num, Type, {Major, Minor}, +mac_hash(Method, Mac_write_secret, Seq_num, Type, {Major, Minor}, Length, Fragment) -> %% RFC 2246 & 4346 - 6.2.3.1. %% HMAC_hash(MAC_write_secret, seq_num + TLSCompressed.type + %% TLSCompressed.version + TLSCompressed.length + %% TLSCompressed.fragment)); - Mac = hmac_hash(Method, Mac_write_secret, - [<<?UINT64(Seq_num), ?BYTE(Type), - ?BYTE(Major), ?BYTE(Minor), ?UINT16(Length)>>, + Mac = hmac_hash(Method, Mac_write_secret, + [<<?UINT64(Seq_num), ?BYTE(Type), + ?BYTE(Major), ?BYTE(Minor), ?UINT16(Length)>>, Fragment]), Mac. -spec suites(1|2|3) -> [cipher_suite()]. - + suites(Minor) when Minor == 1; Minor == 2-> case sufficent_ec_support() of true -> @@ -199,8 +199,8 @@ suites(Minor) when Minor == 3 -> no_ec_suites(3) ++ no_ec_suites(2) end. -all_suites(Minor) when Minor == 1; Minor == 2-> - [ +all_suites(Minor) when Minor == 1; Minor == 2-> + [ ?TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, ?TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, ?TLS_DHE_RSA_WITH_AES_256_CBC_SHA, @@ -224,7 +224,7 @@ all_suites(Minor) when Minor == 1; Minor == 2-> ?TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, ?TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, ?TLS_RSA_WITH_AES_128_CBC_SHA, - + ?TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, ?TLS_ECDHE_RSA_WITH_RC4_128_SHA, ?TLS_RSA_WITH_RC4_128_SHA, @@ -232,32 +232,32 @@ all_suites(Minor) when Minor == 1; Minor == 2-> ?TLS_DHE_RSA_WITH_DES_CBC_SHA, ?TLS_ECDH_ECDSA_WITH_RC4_128_SHA, ?TLS_ECDH_RSA_WITH_RC4_128_SHA, - + ?TLS_RSA_WITH_DES_CBC_SHA ]; -all_suites(3) -> +all_suites(3) -> [ ?TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, ?TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, ?TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384, ?TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384, - + ?TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, ?TLS_DHE_DSS_WITH_AES_256_CBC_SHA256, ?TLS_RSA_WITH_AES_256_CBC_SHA256, - + ?TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, ?TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, ?TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256, ?TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256, - + ?TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, ?TLS_DHE_DSS_WITH_AES_128_CBC_SHA256, ?TLS_RSA_WITH_AES_128_CBC_SHA256 ]. -no_ec_suites(Minor) when Minor == 1; Minor == 2-> - [ +no_ec_suites(Minor) when Minor == 1; Minor == 2-> + [ ?TLS_DHE_RSA_WITH_AES_256_CBC_SHA, ?TLS_DHE_DSS_WITH_AES_256_CBC_SHA, ?TLS_RSA_WITH_AES_256_CBC_SHA, @@ -272,7 +272,7 @@ no_ec_suites(Minor) when Minor == 1; Minor == 2-> ?TLS_DHE_RSA_WITH_DES_CBC_SHA, ?TLS_RSA_WITH_DES_CBC_SHA ]; -no_ec_suites(3) -> +no_ec_suites(3) -> [ ?TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, ?TLS_DHE_DSS_WITH_AES_256_CBC_SHA256, @@ -323,7 +323,7 @@ p_hash(Secret, Seed, WantedLength, Method, N, Acc) -> %% ... Where A(0) = seed %% A(i) = HMAC_hash(secret, A(i-1)) -%% a(0, _Secret, Seed, _Method) -> +%% a(0, _Secret, Seed, _Method) -> %% Seed. %% a(N, Secret, Seed, Method) -> %% hmac_hash(Method, Secret, a(N-1, Secret, Seed, Method)). diff --git a/lib/ssl/test/Makefile b/lib/ssl/test/Makefile index 39aa22ffb4..cb919baf4e 100644 --- a/lib/ssl/test/Makefile +++ b/lib/ssl/test/Makefile @@ -47,6 +47,7 @@ MODULES = \ ssl_payload_SUITE \ ssl_session_cache_SUITE \ ssl_to_openssl_SUITE \ + ssl_ECC_SUITE \ make_certs\ erl_make_certs diff --git a/lib/ssl/test/ssl_ECC_SUITE.erl b/lib/ssl/test/ssl_ECC_SUITE.erl new file mode 100644 index 0000000000..608f2f11c3 --- /dev/null +++ b/lib/ssl/test/ssl_ECC_SUITE.erl @@ -0,0 +1,225 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2007-2013. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/.2 +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% + +%% + +-module(ssl_ECC_SUITE). + +%% Note: This directive should only be used in test suites. +-compile(export_all). + +-include_lib("common_test/include/ct.hrl"). +-include_lib("public_key/include/public_key.hrl"). + +%%-------------------------------------------------------------------- +%% Common Test interface functions ----------------------------------- +%%-------------------------------------------------------------------- + +suite() -> [{ct_hooks,[ts_install_cth]}]. + +all() -> + [ + {group, 'tlsv1.2'}, + {group, 'tlsv1.1'}, + {group, 'tlsv1'} + ]. + +groups() -> + [ + {'tlsv1.2', [], all_versions_groups()}, + {'tlsv1.1', [], all_versions_groups()}, + {'tlsv1', [], all_versions_groups()}, + {'erlang_server', [], key_cert_combinations()}, + {'erlang_client', [], key_cert_combinations()}, + {'erlang', [], key_cert_combinations()} + ]. + +all_versions_groups ()-> + [{group, 'erlang_server'}, + {group, 'erlang_client'}, + {group, 'erlang'} + ]. + +key_cert_combinations() -> + [client_ec_server_ec, + client_rsa_server_ec, + client_ec_server_rsa, + client_rsa_server_rsa]. + +%%-------------------------------------------------------------------- +init_per_suite(Config) -> + catch crypto:stop(), + try crypto:start() of + ok -> + ssl:start(), + Config + catch _:_ -> + {skip, "Crypto did not start"} + end. + +end_per_suite(_Config) -> + ssl:stop(), + application:stop(crypto). + +%%-------------------------------------------------------------------- +init_per_group(erlang_client, Config) -> + case ssl_test_lib:is_sane_ecc(openssl) of + true -> + common_init_per_group(erlang_client, [{server_type, openssl}, + {client_type, erlang} | Config]); + false -> + {skip, "Known ECC bug in openssl"} + end; + +init_per_group(erlang_server, Config) -> + case ssl_test_lib:is_sane_ecc(openssl) of + true -> + common_init_per_group(erlang_client, [{server_type, erlang}, + {client_type, openssl} | Config]); + false -> + {skip, "Known ECC bug in openssl"} + end; + +init_per_group(erlang = Group, Config) -> + case ssl_test_lib:sufficient_crypto_support(Group) of + true -> + common_init_per_group(erlang, [{server_type, erlang}, + {client_type, erlang} | Config]); + false -> + {skip, "Crypto does not support ECC"} + end; +init_per_group(Group, Config) -> + common_init_per_group(Group, Config). + +common_init_per_group(GroupName, Config) -> + case ssl_test_lib:is_tls_version(GroupName) of + true -> + ssl_test_lib:init_tls_version(GroupName), + [{tls_version, GroupName} | Config]; + _ -> + openssl_check(GroupName, Config) + end. + +end_per_group(_GroupName, Config) -> + Config. + +%%-------------------------------------------------------------------- + +init_per_testcase(_TestCase, Config) -> + ct:log("TLS/SSL version ~p~n ", [tls_record:supported_protocol_versions()]), + ct:log("Ciphers: ~p~n ", [ ssl:cipher_suites()]), + Config. + +end_per_testcase(_TestCase, Config) -> + Config. + +%%-------------------------------------------------------------------- +%% Test Cases -------------------------------------------------------- +%%-------------------------------------------------------------------- + +client_ec_server_ec(Config) when is_list(Config) -> + basic_test("ec1.crt", "ec1.key", "ec2.crt", "ec2.key", Config). + +client_ec_server_rsa(Config) when is_list(Config) -> + basic_test("ec1.crt", "ec1.key", "rsa1.crt", "rsa1.key", Config). + +client_rsa_server_ec(Config) when is_list(Config) -> + basic_test("rsa1.crt", "rsa1.key", "ec2.crt", "ec2.key", Config). + +client_rsa_server_rsa(Config) when is_list(Config) -> + basic_test("rsa1.crt", "rsa1.key", "rsa2.crt", "rsa2.key", Config). + +%%-------------------------------------------------------------------- +%% Internal functions ------------------------------------------------ +%%-------------------------------------------------------------------- +basic_test(ClientCert, ClientKey, ServerCert, ServerKey, Config) -> + DataDir = ?config(data_dir, Config), + SType = ?config(server_type, Config), + CType = ?config(client_type, Config), + {Server, Port} = start_server(SType, + filename:join(DataDir, "CA.pem"), + filename:join(DataDir, ServerCert), + filename:join(DataDir, ServerKey), + Config), + Client = start_client(CType, Port, filename:join(DataDir, "CA.pem"), + filename:join(DataDir, ClientCert), + filename:join(DataDir, ClientKey), Config), + check_result(Server, SType, Client, CType). + +start_client(openssl, Port, CA, Cert, Key, _) -> + Version = tls_record:protocol_version(tls_record:highest_protocol_version([])), + Cmd = "openssl s_client -port " ++ integer_to_list(Port) ++ ssl_test_lib:version_flag(Version) ++ + " -cert " ++ Cert ++ " -CAfile " ++ CA + ++ " -key " ++ Key ++ " -host localhost -msg", + OpenSslPort = open_port({spawn, Cmd}, [stderr_to_stdout]), + true = port_command(OpenSslPort, "Hello world"), + OpenSslPort; +start_client(erlang, Port, CA, Cert, Key, Config) -> + {ClientNode, _, Hostname} = ssl_test_lib:run_where(Config), + ssl_test_lib:start_client([{node, ClientNode}, {port, Port}, + {host, Hostname}, + {from, self()}, + {mfa, {ssl_test_lib, send_recv_result_active, []}}, + {options, [{verify, verify_peer}, {cacertfile, CA}, + {certfile, Cert}, {keyfile, Key}]}]). + +start_server(openssl, CA, Cert, Key, _) -> + Port = ssl_test_lib:inet_port(node()), + Version = tls_record:protocol_version(tls_record:highest_protocol_version([])), + Cmd = "openssl s_server -accept " ++ integer_to_list(Port) ++ ssl_test_lib:version_flag(Version) ++ + " -cert " ++ Cert ++ " -CAfile " ++ CA + ++ " -key " ++ Key ++ " -Verify 2 -msg", + OpenSslPort = open_port({spawn, Cmd}, [stderr_to_stdout]), + ssl_test_lib:wait_for_openssl_server(), + true = port_command(OpenSslPort, "Hello world"), + {OpenSslPort, Port}; + +start_server(erlang, CA, Cert, Key, Config) -> + {_, ServerNode, _} = ssl_test_lib:run_where(Config), + Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0}, + {from, self()}, + {mfa, {ssl_test_lib, + send_recv_result_active, + []}}, + {options, + [{verify, verify_peer}, {cacertfile, CA}, + {certfile, Cert}, {keyfile, Key}]}]), + {Server, ssl_test_lib:inet_port(Server)}. + +check_result(Server, erlang, Client, erlang) -> + ssl_test_lib:check_result(Server, ok, Client, ok); +check_result(Server, erlang, _, _) -> + ssl_test_lib:check_result(Server, ok); +check_result(_, _, Client, erlang) -> + ssl_test_lib:check_result(Client, ok); +check_result(_,openssl, _, openssl) -> + ok. + +openssl_check(erlang, Config) -> + Config; +openssl_check(_, Config) -> + TLSVersion = ?config(tls_version, Config), + case ssl_test_lib:check_sane_openssl_version(TLSVersion) of + true -> + ssl:start(), + Config; + false -> + {skip, "TLS version not supported by openssl"} + end. + diff --git a/lib/ssl/test/ssl_ECC_SUITE_data/CA.pem b/lib/ssl/test/ssl_ECC_SUITE_data/CA.pem new file mode 100644 index 0000000000..f82efdefc5 --- /dev/null +++ b/lib/ssl/test/ssl_ECC_SUITE_data/CA.pem @@ -0,0 +1,14 @@ +-----BEGIN CERTIFICATE----- +MIICGjCCAYegAwIBAgIQZIIqq4RXfpBKJXV69Jc4BjAJBgUrDgMCHQUAMB0xGzAZ +BgNVBAMTEklTQSBUZXN0IEF1dGhvcml0eTAeFw0xMjAzMjAxNzEzMjFaFw0zOTEy +MzEyMzU5NTlaMB0xGzAZBgNVBAMTEklTQSBUZXN0IEF1dGhvcml0eTCBnzANBgkq +hkiG9w0BAQEFAAOBjQAwgYkCgYEAqnt6FSyFQVSDyP7mY63IhCzgysTxBEg1qDb8 +nBHj9REReZA5UQ5iyEOdTbdLyOaSk2rJyA2wdTjYkNnLzK49nZFlpf89r3/bakAM +wZv69S3FJi9W2z9m4JPv/5+QCYnFNRSnnHw3maNElwoQyknx96I3W7EuVOvKtKhh +4DaD0WsCAwEAAaNjMGEwDwYDVR0TAQH/BAUwAwEB/zBOBgNVHQEERzBFgBBCHwn2 +8AmbN+cvJl1iJ1bsoR8wHTEbMBkGA1UEAxMSSVNBIFRlc3QgQXV0aG9yaXR5ghBk +giqrhFd+kEoldXr0lzgGMAkGBSsOAwIdBQADgYEAIlVecua5Cr1z/cdwQ8znlgOU +U+y/uzg0nupKkopzVnRYhwV4hxZt3izAz4C/SJZB7eL0bUKlg1ceGjbQsGEm0fzF +LEV3vym4G51bxv03Iecwo96G4NgjJ7+9/7ciBVzfxZyfuCpYG1M2LyrbOyuevtTy +2+vIueT0lv6UftgBfIE= +-----END CERTIFICATE----- diff --git a/lib/ssl/test/ssl_ECC_SUITE_data/ec1.crt b/lib/ssl/test/ssl_ECC_SUITE_data/ec1.crt new file mode 100644 index 0000000000..7d2b9cde9d --- /dev/null +++ b/lib/ssl/test/ssl_ECC_SUITE_data/ec1.crt @@ -0,0 +1,11 @@ +-----BEGIN CERTIFICATE----- +MIIBhjCB8AIBBjANBgkqhkiG9w0BAQUFADAdMRswGQYDVQQDExJJU0EgVGVzdCBB +dXRob3JpdHkwHhcNMTMwODA4MTAxNDI3WhcNMjMwODA2MTAxNDI3WjBFMQswCQYD +VQQGEwJVUzERMA8GA1UECBMIVmlyZ2luaWExFTATBgNVBAcTDEZvcnQgQmVsdm9p +cjEMMAoGA1UEAxMDZWMxMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEpiRIxUCESROR +P8IByg+vBv1fDdAg7yXfAh95GxFtvhBqZs6ATwaRKyLmZYgUm/4NUAyUeqmTBb7s +2msKo5mnNzANBgkqhkiG9w0BAQUFAAOBgQAmwzoB1DVO69FQOUdBVnyups4t0c1c +8h+1z/5P4EtPltk4o3mRn0AZogqdXCpNbuSGbSJh+dep5xW30VLxNHdc+tZSLK6j +pT7A3hymMk8qbi13hxeH/VpEP25y1EjHowow9Wmb6ebtT/v7qFQ9AAHD9ONcIM4I +FCC8vdFo7M5GgQ== +-----END CERTIFICATE----- diff --git a/lib/ssl/test/ssl_ECC_SUITE_data/ec1.key b/lib/ssl/test/ssl_ECC_SUITE_data/ec1.key new file mode 100644 index 0000000000..2dc9508b3c --- /dev/null +++ b/lib/ssl/test/ssl_ECC_SUITE_data/ec1.key @@ -0,0 +1,8 @@ +-----BEGIN EC PARAMETERS----- +BgUrgQQACg== +-----END EC PARAMETERS----- +-----BEGIN EC PRIVATE KEY----- +MHQCAQEEIOO0WK8znNzLyZIoGRIlaKnCNr2Wy8uk9i+GGFIhDGNAoAcGBSuBBAAK +oUQDQgAEpiRIxUCESRORP8IByg+vBv1fDdAg7yXfAh95GxFtvhBqZs6ATwaRKyLm +ZYgUm/4NUAyUeqmTBb7s2msKo5mnNw== +-----END EC PRIVATE KEY----- diff --git a/lib/ssl/test/ssl_ECC_SUITE_data/ec2.crt b/lib/ssl/test/ssl_ECC_SUITE_data/ec2.crt new file mode 100644 index 0000000000..b0558a0ebc --- /dev/null +++ b/lib/ssl/test/ssl_ECC_SUITE_data/ec2.crt @@ -0,0 +1,11 @@ +-----BEGIN CERTIFICATE----- +MIIBhjCB8AIBBzANBgkqhkiG9w0BAQUFADAdMRswGQYDVQQDExJJU0EgVGVzdCBB +dXRob3JpdHkwHhcNMTMwODA4MTAxNDM0WhcNMjMwODA2MTAxNDM0WjBFMQswCQYD +VQQGEwJVUzERMA8GA1UECBMIVmlyZ2luaWExFTATBgNVBAcTDEZvcnQgQmVsdm9p +cjEMMAoGA1UEAxMDZWMyMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEzXaYReUyvoYl +FwGOe0MJEXWCUncMfr2xG4GMjGYlfZsvLGEokefsJIvW+I+9jgUT2UFjxFXYNAvm +uD1A1iWVWjANBgkqhkiG9w0BAQUFAAOBgQBFa6iIlrT9DWptIdB8uSYvp7qwiHxN +hiVH5YhGIHHqjGZqtRHrSxqNEYMXXrgH9Hxc6gDbk9PsHZyVVoh/HgVWddqW1inh +tStZm420PAKCuH4T6Cfsk76GE2m7FRzJvw9TM1f2A5nIy9abyrpup8lZGcIL4Kmq +1Fix1LRtrmLNTA== +-----END CERTIFICATE----- diff --git a/lib/ssl/test/ssl_ECC_SUITE_data/ec2.key b/lib/ssl/test/ssl_ECC_SUITE_data/ec2.key new file mode 100644 index 0000000000..366d13648b --- /dev/null +++ b/lib/ssl/test/ssl_ECC_SUITE_data/ec2.key @@ -0,0 +1,8 @@ +-----BEGIN EC PARAMETERS----- +BgUrgQQACg== +-----END EC PARAMETERS----- +-----BEGIN EC PRIVATE KEY----- +MHQCAQEEIPR3ORUpAFMTQhUJ0jllN38LKWziG8yP2H54Y/9vh1PwoAcGBSuBBAAK +oUQDQgAEzXaYReUyvoYlFwGOe0MJEXWCUncMfr2xG4GMjGYlfZsvLGEokefsJIvW ++I+9jgUT2UFjxFXYNAvmuD1A1iWVWg== +-----END EC PRIVATE KEY----- diff --git a/lib/ssl/test/ssl_ECC_SUITE_data/rsa1.crt b/lib/ssl/test/ssl_ECC_SUITE_data/rsa1.crt new file mode 100644 index 0000000000..ed9beacf68 --- /dev/null +++ b/lib/ssl/test/ssl_ECC_SUITE_data/rsa1.crt @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDVjCCAr8CAQkwDQYJKoZIhvcNAQEFBQAwHTEbMBkGA1UEAxMSSVNBIFRlc3Qg +QXV0aG9yaXR5MB4XDTEzMDgwODEwMTUzNFoXDTQwMTIyNDEwMTUzNFowRjELMAkG +A1UEBhMCVVMxETAPBgNVBAgTCFZpcmdpbmlhMRUwEwYDVQQHEwxGb3J0IEJlbHZv +aXIxDTALBgNVBAMTBHJzYTEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC +AQC62v40w1AjV3oJuyYC2Fw6XhTOi1il6xZFnB9J1WhCmuxAB/VMhBcNypx38mNk +eQ7a/ERQ5ddhZey29DYeFYU8oqfDURgWx5USHufb90xBen9KPmX3VNuQ8ZFP2q8Q +b01/oRHBJQRBuaCtFHzpGIVBjC6dD5yeQgJsYaF4u+PBbonsIGROXMybcvUzXmjU +dwpy2NhjGQL5sWcOdIeRP43APSyRYvq4tuBUZk2XxWfBcvA8LpcoYPMlRTf6jGL1 +/fAAcCYJ9lh3h92w0NZ/7ZRa/ebTplxK6yqCftuSKui1KdL69m0WZqHl79AUSfs9 +lsOwx9lHkyYvJeMofyeDbZ+3OYLmVqEBG1fza2aV2XVh9zJ8fAwmXy/c2IDhw/oD +HAe/rSg/Sgt03ydIKqtZHbl3v0EexQQRlJRULIzdtON02dJMUd4EFUgQ9OUtEmC2 +Psj9Jdu1g5cevU7Mymu8Ot+fjHiGTcBUsXNuXFCbON3Gw7cIDl4+iv+cpDHHVC9L +HK3PMEq3vu3qOGXSz+LDOoqkfROcLG7BclBuN2zoVSsMHFkB4aJhwy7eHhGz0z2W +c6LTVd+GAApdY80kmjOjT//QxHEsX/n1useHza3OszQqZiArr4ub4rtq+l1DxAS/ +DWrZ/JGsbKL8cjWso6qBF94xTi8WhjkKuUYhsm+qLAbNOQIDAQABMA0GCSqGSIb3 +DQEBBQUAA4GBAIcuzqRkfypV/9Z85ZQCCoejPm5Urhv7dfg1/B3QtazogPBZLgL5 +e60fG1uAw5GmqTViHLvW06z73oQvJrFkrCLVvadDNtrKYKXnXqdkgVyk36F/B737 +A43HGnMfSxCfRhIOuKZB9clP5PiNlhw36yi3DratqT6TUvI69hg8a7jA +-----END CERTIFICATE----- diff --git a/lib/ssl/test/ssl_ECC_SUITE_data/rsa1.key b/lib/ssl/test/ssl_ECC_SUITE_data/rsa1.key new file mode 100644 index 0000000000..6e0d913d79 --- /dev/null +++ b/lib/ssl/test/ssl_ECC_SUITE_data/rsa1.key @@ -0,0 +1,51 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIJKAIBAAKCAgEAutr+NMNQI1d6CbsmAthcOl4UzotYpesWRZwfSdVoQprsQAf1 +TIQXDcqcd/JjZHkO2vxEUOXXYWXstvQ2HhWFPKKnw1EYFseVEh7n2/dMQXp/Sj5l +91TbkPGRT9qvEG9Nf6ERwSUEQbmgrRR86RiFQYwunQ+cnkICbGGheLvjwW6J7CBk +TlzMm3L1M15o1HcKctjYYxkC+bFnDnSHkT+NwD0skWL6uLbgVGZNl8VnwXLwPC6X +KGDzJUU3+oxi9f3wAHAmCfZYd4fdsNDWf+2UWv3m06ZcSusqgn7bkirotSnS+vZt +Fmah5e/QFEn7PZbDsMfZR5MmLyXjKH8ng22ftzmC5lahARtX82tmldl1YfcyfHwM +Jl8v3NiA4cP6AxwHv60oP0oLdN8nSCqrWR25d79BHsUEEZSUVCyM3bTjdNnSTFHe +BBVIEPTlLRJgtj7I/SXbtYOXHr1OzMprvDrfn4x4hk3AVLFzblxQmzjdxsO3CA5e +Por/nKQxx1QvSxytzzBKt77t6jhl0s/iwzqKpH0TnCxuwXJQbjds6FUrDBxZAeGi +YcMu3h4Rs9M9lnOi01XfhgAKXWPNJJozo0//0MRxLF/59brHh82tzrM0KmYgK6+L +m+K7avpdQ8QEvw1q2fyRrGyi/HI1rKOqgRfeMU4vFoY5CrlGIbJvqiwGzTkCAwEA +AQKCAgBkXyaWKSRvF5pSh9lPRfGk2MzMdkXUOofoNIkKHDy5KocljiDSTVIk8mVC +eU2ytuSn9UKtQgmEJEAXtu8rEdxUSftcC7+o3OTSqw9ZNWoc8jRWKVaUmVyoa1rn +Tk0jwuYaXOcwnTXAKHqK/qpqe+V45FhVvgEfcc3jcj5OoH8jdMFZubyn62ltRz83 +rMsa9icCskDqWpEil40IUshP2ZfHYBUEs+qCNpoiPCIKGNw3KgqqCUzhP9LcfmYn +jCnMge/eDGAikdXLv4vyYvwWFATRK/pGTuLcy542IvbHeY0vY5wVezH2CoOFBGD9 +xQ/UcZwE5hVtQToNsYhoRIVxL/3Of0qDk1M6W2Plh2MAstyejIHE3ct0pPfW3rsu +j/9Z/H0P9Q5ghSjarwOp2qGrrz6/4LVbbTDY8V1L928l4SqbUMtEQxcxTBN8YFoD +mPV3Jc3zls9wiiEX53RcH8MK5tjrcRwWqurTZvi/pkLfXlGDgKGCOaa3HgWVQyU+ +L6jVZM+u1nwN+jNXQYGeLEro/6tvG8WQbRMHQoxLG+rm4V3/SwH0DcfrVFDTg+i6 +3wMU1GC/aQEdTFWXvHAkpwrf4M9QWvjtheiaSxtBUoAY6l+ixCVHKrIk6glKLEjx +92HxmcJdopQScFETAyg8eVKV0kOGfVeFEpIqwq7hVedmTflpQQKCAQEA44h4dAta +cYeBqBr8eljWcgs79gmgwBEQxQUnwE/zuzLKn5NxAW324Kh25V/n/MupUzBlLPWn +91UHfw9PCXT8/HvgYQ4S5sXbKRbGmuPSsTmz4Rfe2ix6RggVNUOwORVNDyM7SQh7 +USdzZH5dMxKfF5L/b4Byx7eQZaoeKlfaXcqgikNZZ6pkhVCNxUKi9vvjS9r2wwCd +xtgu5MfTpdEci0zH1+uuRisVRcEbcRX9umUTCiZrmEeddZXNiwTAS3FtX7qGzuq9 +LKIeETwcOZrWj0E48UvbSfK4Axn7sf5J0n7/Qo7I089S5QQEI6ZDP501i71dNFhn +qfcY30c1k3TC7QKCAQEA0juuVHExKNLLNmQejNPfuHYoH0Uk2BH/8x96/Mkj6k6K +SUCHDS3iWOljXGw8YtpS8v5mGBGgMhJ+s/vCRM6R9eXYTc8u2ktY/kjyW0PgW8/Z +vb9VrQpn5svTNwj2Q8qYsTqXnQKO7YuL+hnQpQNAcID6FTeOASVLGObEf810qRfN +4y3RqCWUnYXXTyXj+cJdbXTxfF7HVZPIAQKqE7J5Qo9ynYILY62oSmUGC6m8VKyE +rrvDMK1IVi0X4w+Jx4HX0IC2+DBKxCaLWT69bE1IwjB06Q5zoTQPVi6c6qQp7K0H +kqSyLJ/ctwcEubu0DPNmvMlgWtAbAsoESA5GbIit/QKCAQEAxRzp9OYNAUM6AK74 +QOmLRZsT4+6tUxa1p2jy6fiZlnfG731kra9c630mG0n9iJPK6aWIUO20CGGiL+HM +P84YiIaseIgfucp4NV1kyrRJR31MptjuF6Xme5ru/IjaNmmMq2uDJZ7ybfi2T73k +8aTVLDANl8P4K6qLrnc00MvxAcXTVFRKNLN5h8CkQNqcoUjPvVxA3+g9xxBrd4jh +gsnoZ4kpq5WiEWmrcRV8t3gsqfh8CRQFrBOGhmIzgZapG/J0pTTLKqBTKEJ9t8KS +VRkdfVcshGWJ4MMjxJQS5zz7KR8Z9cgKlOwLzRiwmU2k/owr4hY3k2xuyeClrHBd +KpRBdQKCAQBvDk/dE55gbloi9WieBB6eluxC+IeqDHgkunCBsM9kKvEqGQg+kgqL +5V4zqImNvr8q1fCgrk7tpI+CDHBnYKgCOdS15cheUIdGbMp6I7UVSws/DR/5NRIF +/Y4p+HX/Abr/hHAq5PsTyS+8gn6RbNJRnBB/vMUrHcQ5902+JY6G9KgyZjXmmVOU +kutWSDHR8jbgZ3JZvMeYEWUKA5pMpW8hFh35zoStt0K7afpzlsqCAFBm7ZEC2cbo +nxGLRN4HojObVSNSoFAepi3eiyINYBYbXvWjV5sFgTbI0/7YhLgQ6qahdJcas6go +l3CLnPhUDxAqkkZwMpbSNl1kowXYt6sRAoIBAAOWnXgf9Bdb9OWKGgt42gVfC4cz +zj2JoLpbDTtbEdHNn8XQvPhGbpdtgnsuEMijIMy1UTlmv17jbFWdZTDeN31EUJrC +smgKX0OlVFKD90AI0BiIREK0hJUBV0pV4JoUjwnQBHGvranD06/wAtHEqgqF1Ipp +DCAKwxggM7qtB1R1vkrc/aLQej+mlwA8N6q92rnEsg+EnEbhtLDDZQcV/q5cSDCN +MMcnM+QdyjKwEeCVXHaqNfeSqKg/Ab2eZbS9VxA+XZD73+eUY/JeJsg7LfZrRz0T +ij5LCS7A+nVB5/B5tGkk4fcNhk2n356be6l46S98BEgtuwGLC9pqXf7zyp4= +-----END RSA PRIVATE KEY----- diff --git a/lib/ssl/test/ssl_ECC_SUITE_data/rsa2.crt b/lib/ssl/test/ssl_ECC_SUITE_data/rsa2.crt new file mode 100644 index 0000000000..06ca92dda3 --- /dev/null +++ b/lib/ssl/test/ssl_ECC_SUITE_data/rsa2.crt @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDVjCCAr8CAQowDQYJKoZIhvcNAQEFBQAwHTEbMBkGA1UEAxMSSVNBIFRlc3Qg +QXV0aG9yaXR5MB4XDTEzMDgwODEwMTYwMloXDTQwMTIyNDEwMTYwMlowRjELMAkG +A1UEBhMCVVMxETAPBgNVBAgTCFZpcmdpbmlhMRUwEwYDVQQHEwxGb3J0IEJlbHZv +aXIxDTALBgNVBAMTBHJzYTIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC +AQCjQUe0BGOpULjOAmLbXM4SSQzJvxJbCFi3tryyd+OARq6Fdp6/fslVhsr0PhWE +X8yRbAugIjseTpLwz+1OC6LavOGV1ixzGTI/9HDXGKbf8qoCrSdh28sqQJnmqGT4 +UCKLn6Rqjg2iyBBcSK3LrtKEPI4C7NaSOZUtANkppvziEMwm+0r16sgHh2Xx6mxd +22q01kq1lJqwEnIDPMSz3+ESUVQQ4T3ka7yFIhc9PYmILIXkZi0x7AiDeRkIILul +GQrduTWSPGY3prXeDAbmQNazxrHp8fcR2AfFSI6HYxMALq9jWxc4xDIkss6BO2Et +riJOIgXFpbyVsYCbkI1kXhEWFDt3uJBIcmtJKGzro4xv+XLG6BbUeTJgSHXMc7Cb +fX87+CBIFR5a/aqkEKh/mcvsDdaV+kpNKdr7q4wAuIQb8g7IyXEDuAm1VZjQs9WC +KFRGSq9sergEw9gna0iThRZjD+dzNzB17XmlAK4wa98a7MntwqpAt/GsCFOiPM8E +c+8gpuo8WqC0kP8OpImyw9cQhlZ3dca1qkr2cyKyAOGxUxyA67FgiHSsxJJ2Xhse +o49qeKTjMZd8zhSokM2TH6qEf7YfOePU51YRfAHUhzRmE31N/MExqDjFjklksEtM +iHhbPo+cOoxV8x1u13umdUvtTaAUSBA/DpvzWdnORvnaqQIDAQABMA0GCSqGSIb3 +DQEBBQUAA4GBAFD+O7h+5R5S1rIN9eC+oEGpvRhMG4v4G3pJp+c7bbtO7ifFx1WP +bta1b5YtiQYcKP0ORABm/3Kcvsb3VbaMH/zkxWEbASZsmIcBY3ml4f2kkn6WT2hD +Wc6VMIAR3N6Mj1b30yI1qYVIid+zIouiykMB+zqllm+Uar0SPNjKxDU/ +-----END CERTIFICATE----- diff --git a/lib/ssl/test/ssl_ECC_SUITE_data/rsa2.key b/lib/ssl/test/ssl_ECC_SUITE_data/rsa2.key new file mode 100644 index 0000000000..d415ef0391 --- /dev/null +++ b/lib/ssl/test/ssl_ECC_SUITE_data/rsa2.key @@ -0,0 +1,51 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIJJwIBAAKCAgEAo0FHtARjqVC4zgJi21zOEkkMyb8SWwhYt7a8snfjgEauhXae +v37JVYbK9D4VhF/MkWwLoCI7Hk6S8M/tTgui2rzhldYscxkyP/Rw1xim3/KqAq0n +YdvLKkCZ5qhk+FAii5+kao4NosgQXEity67ShDyOAuzWkjmVLQDZKab84hDMJvtK +9erIB4dl8epsXdtqtNZKtZSasBJyAzzEs9/hElFUEOE95Gu8hSIXPT2JiCyF5GYt +MewIg3kZCCC7pRkK3bk1kjxmN6a13gwG5kDWs8ax6fH3EdgHxUiOh2MTAC6vY1sX +OMQyJLLOgTthLa4iTiIFxaW8lbGAm5CNZF4RFhQ7d7iQSHJrSShs66OMb/lyxugW +1HkyYEh1zHOwm31/O/ggSBUeWv2qpBCof5nL7A3WlfpKTSna+6uMALiEG/IOyMlx +A7gJtVWY0LPVgihURkqvbHq4BMPYJ2tIk4UWYw/nczcwde15pQCuMGvfGuzJ7cKq +QLfxrAhTojzPBHPvIKbqPFqgtJD/DqSJssPXEIZWd3XGtapK9nMisgDhsVMcgOux +YIh0rMSSdl4bHqOPanik4zGXfM4UqJDNkx+qhH+2Hznj1OdWEXwB1Ic0ZhN9TfzB +Mag4xY5JZLBLTIh4Wz6PnDqMVfMdbtd7pnVL7U2gFEgQPw6b81nZzkb52qkCAwEA +AQKCAgBORLHXwHL3bdfsDIDQooG5ioQzBQQL2MiP63A0L/5GNZzeJ6ycKnDkLCeJ +SWqPeE5fOemo8EBfm1QfV9BxpmqBbCTK7U+KLv5EYzDmLs9ydqjDd7h11iZlL2uZ +hgpCckjdn7/3xfsLm9ccJ0wLZtlOxKlhBaMpn6nBVbLHoWOEDoGR/tBFbjZQRb2+ +aaFirhtOb56Jx6ER4QYAP1Ye1qrVWWBwZ0yBApXzThDOL36MZqwagFISqRK71YcG +uoq78HGhM3ZXkdV/wNFYj3OPWG6W6h/KBVNqnqO7FbofdoRZhghYHgfYE1fm+ELA ++nLwr5eK1gzmYTs0mVELRBZFlEOkCfYNOnuRgysFezEklS+ICp3HzIhYXza3kyTf +B2ZBwZZVCv/94MKyibyANErmv1a5ugY5Hsn9/WKC8qTto+qLYoyFCvBjzj0PSaVX +/3cty2DY0SK16K1Y4AOPtJMYTXYB3tVX8Akgjz1F6REBtZSOXrSQ3Vhy1ORl3Hzf +WCBYDqL8K0hJiBVgkvneIyIjmFHsdM60Nr7EldBEnJ/UrPzsl2VuWFPZlnasfUaW +x+vq1H4Dfz+bHt8coBRHDjKgUvwkfFeBQOBR5DG3vMrxguVRA1EYYMRR5C3yxk2m +ARAtdh4VxUQDQjjrmr7Dl/y1rU34aInXIrrFWpuvIhl8Ht09sQKCAQEA1pXKK5f0 +HkKfM/qk5xzF+WdHClBrPXi0XwLN6UQ+WWMMNhkGZ+FMPXl/6IJDT91s6DA3tPhr +OZF64n9ZFaGgHNBXNiB+Txjv5vZeSBMFt3hSonqt42aijx6gXfmLnkA+TYpa6Wex +YCeEgdH8LocJa7Gj2vzrYliPYk3deh6SnZZ6N8bI+ciwK3ZGF/pkWaTX83dIFq3w +YyZ+0dEpNGbA9812wNVourPg3OfqG3/CdnTfvY1M9KCC3JalpyzQL4Zm5soXF0wj +36C2yTxA02AyFz3TvUIBrvsN6i0gmGfE79+UIp29JYrFRsIgBDt+ze2vQWUz2MX5 +GeX6/yCBgiTXtwKCAQEAwsNf6k2m5Cw+WtuLzzUfBBJCN+t1lrnYJ6lF0HubW6TZ +vX1kBWyc+Rpo4ljr/+f4R9aC/gTEQOmV/hNVZy1RU2dAI8cH+r6JWG9lgif+8h// +5R81txE7gnuK1Na7PmvnQPPN661zsQZ5e1ENPXS3TJmUW/M01JxAMqEQjvAPa/II +H2KjL5NX28k9Hiw9rP6n+qXAfG/LEwXgoVCcehPwfANqQ1l95UgOdKDmjG94dipI +h2DEK70ZbrsgQbT60Wd8I5h0yhiQsik2/bVkqLmcG4SSg0/5cf2vZMApgoH/adUz +rJFdthm7iGPLhwS6fbhXew17Af96FvzfkifUV+cgnwKCAQBNUlYyFSQKz1jMgxFu +kciokNVhWw75bIgaAEmwNz38OZuJ1sSfI+iz8hbr8hxNJ+15UP6RwD3q1YghG2A/ +Uij+mPgD8ftxhvvTDo10jR4vOTUVhP0phq8mwRNqKWRs1ptcl3Egz5NzoWm22bJ0 +FYaIfs8bNq2el2i7NHGM8n1EOZe6h2+dyfno/0pMk5YbUzHZce7Q9UY8g/+InUSq +tCfuYuPaokuFkxGAqDSMSiIJSx3gEI1dTIU69TGlppkxts1XdhSR+YanqyKSKpr1 +T6FdDJNCjAlNQvuFmVM4d5PYF4kqXApu/60MTSD6RXHwxCe1ecEP6G5VLbCew9jG +y33LAoIBAGsWyC9pwQEm/qYwn4AwYjx32acrtX1J9HtiTLvkqzjJvNu/DXcaEHm7 +tr32TNVp9A9z+JS5hDt49Hs+oC/aMCRe2lqRvmZ1y8kvfy4A1eLGC4stDPj65bDK +QzziURRyejYxmCElPz6wI63VlCUdfwgEThn88SiSPY5ZF2SwxJoC+8peDwJCzwVP +cmabxtHPOAfOibciNRPhoHCyhUdunUVjD1O26k1ewGwKaJoBVMgMWdLuNw8hq9FB +3OukGmF3uD9OPbE9rpn3pX/89Dr9y8MpsvG20J6H8Z/BNVHILus/SmlxiIhvP7kv +viIgTHaCHL/RWrhvg+8N3dRcSBqJQFsCggEAFe2TMEq2AlnBn4gsuAOIuZPYKQCg +2a+tl1grQzmNth6AGGQcIqShadICD6SnVMIS64HHV/m18Cuz7GhJ06ZVjXJsHueG +UpTE9wAmI2LxnNkupkLJu+SVcW3N86PujWmQBFpHkd+IRPLS51xjD9W5zLJ7HL4/ +fnKO+B+ZK6Imxbe5C5vJezkGfeOSyQoVtt6MT/XtSKNEGPBX+M6fLKgUMMg2H2Mt +/SsD7DkOzFteKXzaEg/K8oOTpsOPkVDwNl2KErlEqbJv0k7yEVw50mYmsn/OLjh8 ++9EibISwCODbPxB+PhV6u2ue1IvGLRqtsN60lFOvbGn+kSewy9EUVHHQDQ== +-----END RSA PRIVATE KEY----- diff --git a/lib/ssl/test/ssl_basic_SUITE.erl b/lib/ssl/test/ssl_basic_SUITE.erl index b5cf6d1212..b8849d5cbd 100644 --- a/lib/ssl/test/ssl_basic_SUITE.erl +++ b/lib/ssl/test/ssl_basic_SUITE.erl @@ -212,21 +212,20 @@ end_per_suite(_Config) -> %%-------------------------------------------------------------------- init_per_group(GroupName, Config) -> - case ssl_test_lib:is_tls_version(GroupName) of + case ssl_test_lib:is_tls_version(GroupName) andalso ssl_test_lib:sufficient_crypto_support(GroupName) of true -> + ssl_test_lib:init_tls_version(GroupName), + Config; + _ -> case ssl_test_lib:sufficient_crypto_support(GroupName) of true -> - ssl_test_lib:init_tls_version(GroupName), + ssl:start(), Config; false -> {skip, "Missing crypto support"} - end; - _ -> - ssl:start(), - Config + end end. - end_per_group(_GroupName, Config) -> Config. diff --git a/lib/ssl/test/ssl_handshake_SUITE.erl b/lib/ssl/test/ssl_handshake_SUITE.erl index a40f07fd07..9695710230 100644 --- a/lib/ssl/test/ssl_handshake_SUITE.erl +++ b/lib/ssl/test/ssl_handshake_SUITE.erl @@ -32,43 +32,44 @@ %%-------------------------------------------------------------------- suite() -> [{ct_hooks,[ts_install_cth]}]. -all() -> [ - decode_hello_handshake, - decode_single_hello_extension_correctly, - decode_unknown_hello_extension_correctly]. +all() -> [decode_hello_handshake, + decode_single_hello_extension_correctly, + decode_unknown_hello_extension_correctly]. %%-------------------------------------------------------------------- %% Test Cases -------------------------------------------------------- %%-------------------------------------------------------------------- decode_hello_handshake(_Config) -> - HelloPacket = <<16#02, 16#00, 16#00, - 16#44, 16#03, 16#03, 16#4e, 16#7f, 16#c1, 16#03, 16#35, - 16#c2, 16#07, 16#b9, 16#4a, 16#58, 16#af, 16#34, 16#07, - 16#a6, 16#7e, 16#ef, 16#52, 16#cb, 16#e0, 16#ea, 16#b7, - 16#aa, 16#47, 16#c8, 16#c2, 16#2c, 16#66, 16#fa, 16#f8, - 16#09, 16#42, 16#cf, 16#00, 16#c0, 16#30, 16#00, 16#00, - 16#1c, - 16#00, 16#0b, 16#00, 16#04, 16#03, 16#00, 16#01, 16#02, % ec_point_formats - 16#ff, 16#01, 16#00, 16#01, 16#00, %% renegotiate - 16#00, 16#23, - 16#00, 16#00, 16#33, 16#74, 16#00, 16#07, 16#06, 16#73, - 16#70, 16#64, 16#79, 16#2f, 16#32>>, - - Version = {3, 0}, - {Records, _Buffer} = tls_handshake:get_tls_handshake(Version, HelloPacket, <<>>), - - {Hello, _Data} = hd(Records), - #renegotiation_info{renegotiated_connection = <<0>>} = Hello#server_hello.renegotiation_info. + HelloPacket = <<16#02, 16#00, 16#00, + 16#44, 16#03, 16#03, 16#4e, 16#7f, 16#c1, 16#03, 16#35, + 16#c2, 16#07, 16#b9, 16#4a, 16#58, 16#af, 16#34, 16#07, + 16#a6, 16#7e, 16#ef, 16#52, 16#cb, 16#e0, 16#ea, 16#b7, + 16#aa, 16#47, 16#c8, 16#c2, 16#2c, 16#66, 16#fa, 16#f8, + 16#09, 16#42, 16#cf, 16#00, 16#c0, 16#30, 16#00, 16#00, + 16#1c, + 16#00, 16#0b, 16#00, 16#04, 16#03, 16#00, 16#01, 16#02, % ec_point_formats + 16#ff, 16#01, 16#00, 16#01, 16#00, %% renegotiate + 16#00, 16#23, + 16#00, 16#00, 16#33, 16#74, 16#00, 16#07, 16#06, 16#73, + 16#70, 16#64, 16#79, 16#2f, 16#32>>, + Version = {3, 0}, + {Records, _Buffer} = tls_handshake:get_tls_handshake(Version, HelloPacket, <<>>), + + {Hello, _Data} = hd(Records), + #renegotiation_info{renegotiated_connection = <<0>>} + = (Hello#server_hello.extensions)#hello_extensions.renegotiation_info. + decode_single_hello_extension_correctly(_Config) -> - Renegotiation = <<?UINT16(?RENEGOTIATION_EXT), ?UINT16(1), 0>>, - Extensions = tls_handshake:dec_hello_extensions(Renegotiation, []), - [{renegotiation_info,#renegotiation_info{renegotiated_connection = <<0>>}}] = Extensions. - + Renegotiation = <<?UINT16(?RENEGOTIATION_EXT), ?UINT16(1), 0>>, + Extensions = ssl_handshake:decode_hello_extensions(Renegotiation), + #renegotiation_info{renegotiated_connection = <<0>>} + = Extensions#hello_extensions.renegotiation_info. + decode_unknown_hello_extension_correctly(_Config) -> - FourByteUnknown = <<16#CA,16#FE, ?UINT16(4), 3, 0, 1, 2>>, - Renegotiation = <<?UINT16(?RENEGOTIATION_EXT), ?UINT16(1), 0>>, - Extensions = tls_handshake:dec_hello_extensions(<<FourByteUnknown/binary, Renegotiation/binary>>, []), - [{renegotiation_info,#renegotiation_info{renegotiated_connection = <<0>>}}] = Extensions. - + FourByteUnknown = <<16#CA,16#FE, ?UINT16(4), 3, 0, 1, 2>>, + Renegotiation = <<?UINT16(?RENEGOTIATION_EXT), ?UINT16(1), 0>>, + Extensions = ssl_handshake:decode_hello_extensions(<<FourByteUnknown/binary, Renegotiation/binary>>), + #renegotiation_info{renegotiated_connection = <<0>>} + = Extensions#hello_extensions.renegotiation_info. diff --git a/lib/ssl/test/ssl_npn_hello_SUITE.erl b/lib/ssl/test/ssl_npn_hello_SUITE.erl index ef5a02abef..27e1090114 100644 --- a/lib/ssl/test/ssl_npn_hello_SUITE.erl +++ b/lib/ssl/test/ssl_npn_hello_SUITE.erl @@ -52,7 +52,7 @@ encode_and_decode_client_hello_test(_Config) -> Version = tls_record:protocol_version(tls_record:highest_protocol_version([])), {[{DecodedHandshakeMessage, _Raw}], _} = tls_handshake:get_tls_handshake(Version, list_to_binary(HandShakeData), <<>>), - NextProtocolNegotiation = DecodedHandshakeMessage#client_hello.next_protocol_negotiation, + NextProtocolNegotiation = (DecodedHandshakeMessage#client_hello.extensions)#hello_extensions.next_protocol_negotiation, NextProtocolNegotiation = undefined. %%-------------------------------------------------------------------- encode_and_decode_npn_client_hello_test(_Config) -> @@ -60,7 +60,7 @@ encode_and_decode_npn_client_hello_test(_Config) -> Version = tls_record:protocol_version(tls_record:highest_protocol_version([])), {[{DecodedHandshakeMessage, _Raw}], _} = tls_handshake:get_tls_handshake(Version, list_to_binary(HandShakeData), <<>>), - NextProtocolNegotiation = DecodedHandshakeMessage#client_hello.next_protocol_negotiation, + NextProtocolNegotiation = (DecodedHandshakeMessage#client_hello.extensions)#hello_extensions.next_protocol_negotiation, NextProtocolNegotiation = #next_protocol_negotiation{extension_data = <<>>}. %%-------------------------------------------------------------------- encode_and_decode_server_hello_test(_Config) -> @@ -68,7 +68,7 @@ encode_and_decode_server_hello_test(_Config) -> Version = tls_record:protocol_version(tls_record:highest_protocol_version([])), {[{DecodedHandshakeMessage, _Raw}], _} = tls_handshake:get_tls_handshake(Version, list_to_binary(HandShakeData), <<>>), - NextProtocolNegotiation = DecodedHandshakeMessage#server_hello.next_protocol_negotiation, + NextProtocolNegotiation = (DecodedHandshakeMessage#server_hello.extensions)#hello_extensions.next_protocol_negotiation, NextProtocolNegotiation = undefined. %%-------------------------------------------------------------------- encode_and_decode_npn_server_hello_test(_Config) -> @@ -76,56 +76,59 @@ encode_and_decode_npn_server_hello_test(_Config) -> Version = tls_record:protocol_version(tls_record:highest_protocol_version([])), {[{DecodedHandshakeMessage, _Raw}], _} = tls_handshake:get_tls_handshake(Version, list_to_binary(HandShakeData), <<>>), - NextProtocolNegotiation = DecodedHandshakeMessage#server_hello.next_protocol_negotiation, + NextProtocolNegotiation = (DecodedHandshakeMessage#server_hello.extensions)#hello_extensions.next_protocol_negotiation, ct:log("~p ~n", [NextProtocolNegotiation]), NextProtocolNegotiation = #next_protocol_negotiation{extension_data = <<6, "spdy/2">>}. %%-------------------------------------------------------------------- create_server_hello_with_no_advertised_protocols_test(_Config) -> - Hello = tls_handshake:server_hello(<<>>, {3, 0}, create_connection_states(), false, undefined, undefined, undefined), - undefined = Hello#server_hello.next_protocol_negotiation. + Hello = tls_handshake:server_hello(<<>>, {3, 0}, create_connection_states(), #hello_extensions{}), + undefined = (Hello#server_hello.extensions)#hello_extensions.next_protocol_negotiation. %%-------------------------------------------------------------------- create_server_hello_with_advertised_protocols_test(_Config) -> Hello = tls_handshake:server_hello(<<>>, {3, 0}, create_connection_states(), - false, [<<"spdy/1">>, <<"http/1.0">>, <<"http/1.1">>], undefined, undefined), - #next_protocol_negotiation{extension_data = <<6, "spdy/1", 8, "http/1.0", 8, "http/1.1">>} = - Hello#server_hello.next_protocol_negotiation. + #hello_extensions{next_protocol_negotiation = [<<"spdy/1">>, <<"http/1.0">>, <<"http/1.1">>]}), + [<<"spdy/1">>, <<"http/1.0">>, <<"http/1.1">>] = + (Hello#server_hello.extensions)#hello_extensions.next_protocol_negotiation. %%-------------------------------------------------------------------- %% Internal functions ------------------------------------------------ %%-------------------------------------------------------------------- create_client_handshake(Npn) -> + Vsn = {1, 2}, tls_handshake:encode_handshake(#client_hello{ - client_version = {1, 2}, - random = <<1:256>>, - session_id = <<>>, - cipher_suites = [?TLS_DHE_DSS_WITH_DES_CBC_SHA], - compression_methods = "", - next_protocol_negotiation = Npn, - renegotiation_info = #renegotiation_info{} - }, vsn). + client_version = Vsn, + random = <<1:256>>, + session_id = <<>>, + cipher_suites = [?TLS_DHE_DSS_WITH_DES_CBC_SHA], + compression_methods = "", + extensions = #hello_extensions{ + next_protocol_negotiation = Npn, + renegotiation_info = #renegotiation_info{}} + }, Vsn). create_server_handshake(Npn) -> + Vsn = {1, 2}, tls_handshake:encode_handshake(#server_hello{ - server_version = {1, 2}, - random = <<1:256>>, - session_id = <<>>, - cipher_suite = ?TLS_DHE_DSS_WITH_DES_CBC_SHA, - compression_method = 1, - next_protocol_negotiation = Npn, - renegotiation_info = #renegotiation_info{} - }, vsn). + server_version = Vsn, + random = <<1:256>>, + session_id = <<>>, + cipher_suite = ?TLS_DHE_DSS_WITH_DES_CBC_SHA, + compression_method = 1, + extensions = #hello_extensions{ + next_protocol_negotiation = Npn, + renegotiation_info = #renegotiation_info{}} + }, Vsn). create_connection_states() -> #connection_states{ - pending_read = #connection_state{ - security_parameters = #security_parameters{ - server_random = <<1:256>>, - compression_algorithm = 1, - cipher_suite = ?TLS_DHE_DSS_WITH_DES_CBC_SHA - } - }, - - current_read = #connection_state { - secure_renegotiation = false - } - }. + pending_read = #connection_state{ + security_parameters = #security_parameters{ + server_random = <<1:256>>, + compression_algorithm = 1, + cipher_suite = ?TLS_DHE_DSS_WITH_DES_CBC_SHA + } + }, + current_read = #connection_state { + secure_renegotiation = false + } + }. diff --git a/lib/ssl/test/ssl_test_lib.erl b/lib/ssl/test/ssl_test_lib.erl index 34c52b10b3..74fadc0cc7 100644 --- a/lib/ssl/test/ssl_test_lib.erl +++ b/lib/ssl/test/ssl_test_lib.erl @@ -27,6 +27,7 @@ -compile(export_all). -record(sslsocket, { fd = nil, pid = nil}). +-define(SLEEP, 1000). %% For now always run locally run_where(_) -> @@ -949,7 +950,10 @@ init_tls_version(Version) -> sufficient_crypto_support('tlsv1.2') -> CryptoSupport = crypto:supports(), proplists:get_bool(sha256, proplists:get_value(hashs, CryptoSupport)); -sufficient_crypto_support(ciphers_ec) -> +sufficient_crypto_support(Group) when Group == ciphers_ec; %% From ssl_basic_SUITE + Group == erlang_server; %% From ssl_ECC_SUITE + Group == erlang_client; %% From ssl_ECC_SUITE + Group == erlang -> %% From ssl_ECC_SUITE CryptoSupport = crypto:supports(), proplists:get_bool(ecdh, proplists:get_value(public_keys, CryptoSupport)); sufficient_crypto_support(_) -> @@ -1026,3 +1030,39 @@ cipher_restriction(Config0) -> true -> Config0 end. + +check_sane_openssl_version(Version) -> + case {Version, os:cmd("openssl version")} of + {_, "OpenSSL 1.0.1" ++ _} -> + true; + {'tlsv1.2', "OpenSSL 1.0" ++ _} -> + false; + {'tlsv1.1', "OpenSSL 1.0" ++ _} -> + false; + {'tlsv1.2', "OpenSSL 0" ++ _} -> + false; + {'tlsv1.1', "OpenSSL 0" ++ _} -> + false; + {_, _} -> + true + end. + +wait_for_openssl_server() -> + receive + {Port, {data, Debug}} when is_port(Port) -> + ct:log("openssl ~s~n",[Debug]), + %% openssl has started make sure + %% it will be in accept. Parsing + %% output is too error prone. (Even + %% more so than sleep!) + ct:sleep(?SLEEP) + end. + +version_flag(tlsv1) -> + " -tls1 "; +version_flag('tlsv1.1') -> + " -tls1_1 "; +version_flag('tlsv1.2') -> + " -tls1_2 "; +version_flag(sslv3) -> + " -ssl3 ". diff --git a/lib/ssl/test/ssl_to_openssl_SUITE.erl b/lib/ssl/test/ssl_to_openssl_SUITE.erl index 019ed58b1b..b576b8f70d 100644 --- a/lib/ssl/test/ssl_to_openssl_SUITE.erl +++ b/lib/ssl/test/ssl_to_openssl_SUITE.erl @@ -120,7 +120,7 @@ end_per_suite(_Config) -> init_per_group(GroupName, Config) -> case ssl_test_lib:is_tls_version(GroupName) of true -> - case check_sane_openssl_version(GroupName) of + case ssl_test_lib:check_sane_openssl_version(GroupName) of true -> ssl_test_lib:init_tls_version(GroupName), Config; @@ -204,7 +204,7 @@ basic_erlang_client_openssl_server(Config) when is_list(Config) -> OpensslPort = open_port({spawn, Cmd}, [stderr_to_stdout]), - wait_for_openssl_server(), + ssl_test_lib:wait_for_openssl_server(), Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port}, {host, Hostname}, @@ -269,14 +269,14 @@ erlang_client_openssl_server(Config) when is_list(Config) -> CertFile = proplists:get_value(certfile, ServerOpts), KeyFile = proplists:get_value(keyfile, ServerOpts), Version = tls_record:protocol_version(tls_record:highest_protocol_version([])), - Cmd = "openssl s_server -accept " ++ integer_to_list(Port) ++ version_flag(Version) ++ + Cmd = "openssl s_server -accept " ++ integer_to_list(Port) ++ ssl_test_lib:version_flag(Version) ++ " -cert " ++ CertFile ++ " -key " ++ KeyFile, ct:log("openssl cmd: ~p~n", [Cmd]), OpensslPort = open_port({spawn, Cmd}, [stderr_to_stdout]), - wait_for_openssl_server(), + ssl_test_lib:wait_for_openssl_server(), Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port}, {host, Hostname}, @@ -311,7 +311,7 @@ erlang_server_openssl_client(Config) when is_list(Config) -> Port = ssl_test_lib:inet_port(Server), Version = tls_record:protocol_version(tls_record:highest_protocol_version([])), - Cmd = "openssl s_client -port " ++ integer_to_list(Port) ++ version_flag(Version) ++ + Cmd = "openssl s_client -port " ++ integer_to_list(Port) ++ ssl_test_lib:version_flag(Version) ++ " -host localhost", ct:log("openssl cmd: ~p~n", [Cmd]), @@ -345,7 +345,7 @@ erlang_client_openssl_server_dsa_cert(Config) when is_list(Config) -> KeyFile = proplists:get_value(keyfile, ServerOpts), Version = tls_record:protocol_version(tls_record:highest_protocol_version([])), - Cmd = "openssl s_server -accept " ++ integer_to_list(Port) ++ version_flag(Version) ++ + Cmd = "openssl s_server -accept " ++ integer_to_list(Port) ++ ssl_test_lib:version_flag(Version) ++ " -cert " ++ CertFile ++ " -CAfile " ++ CaCertFile ++ " -key " ++ KeyFile ++ " -Verify 2 -msg", @@ -353,7 +353,7 @@ erlang_client_openssl_server_dsa_cert(Config) when is_list(Config) -> OpensslPort = open_port({spawn, Cmd}, [stderr_to_stdout]), - wait_for_openssl_server(), + ssl_test_lib:wait_for_openssl_server(), Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port}, {host, Hostname}, @@ -392,7 +392,7 @@ erlang_server_openssl_client_dsa_cert(Config) when is_list(Config) -> {options, ServerOpts}]), Port = ssl_test_lib:inet_port(Server), Version = tls_record:protocol_version(tls_record:highest_protocol_version([])), - Cmd = "openssl s_client -port " ++ integer_to_list(Port) ++ version_flag(Version) ++ + Cmd = "openssl s_client -port " ++ integer_to_list(Port) ++ ssl_test_lib:version_flag(Version) ++ " -host localhost " ++ " -cert " ++ CertFile ++ " -CAfile " ++ CaCertFile ++ " -key " ++ KeyFile ++ " -msg", @@ -428,7 +428,7 @@ erlang_server_openssl_client_reuse_session(Config) when is_list(Config) -> {options, ServerOpts}]), Port = ssl_test_lib:inet_port(Server), Version = tls_record:protocol_version(tls_record:highest_protocol_version([])), - Cmd = "openssl s_client -port " ++ integer_to_list(Port) ++ version_flag(Version) ++ + Cmd = "openssl s_client -port " ++ integer_to_list(Port) ++ ssl_test_lib:version_flag(Version) ++ " -host localhost -reconnect", ct:log("openssl cmd: ~p~n", [Cmd]), @@ -464,14 +464,14 @@ erlang_client_openssl_server_renegotiate(Config) when is_list(Config) -> KeyFile = proplists:get_value(keyfile, ServerOpts), Version = tls_record:protocol_version(tls_record:highest_protocol_version([])), - Cmd = "openssl s_server -accept " ++ integer_to_list(Port) ++ version_flag(Version) ++ + Cmd = "openssl s_server -accept " ++ integer_to_list(Port) ++ ssl_test_lib:version_flag(Version) ++ " -cert " ++ CertFile ++ " -key " ++ KeyFile ++ " -msg", ct:log("openssl cmd: ~p~n", [Cmd]), OpensslPort = open_port({spawn, Cmd}, [stderr_to_stdout]), - wait_for_openssl_server(), + ssl_test_lib:wait_for_openssl_server(), Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port}, {host, Hostname}, @@ -513,14 +513,14 @@ erlang_client_openssl_server_nowrap_seqnum(Config) when is_list(Config) -> CertFile = proplists:get_value(certfile, ServerOpts), KeyFile = proplists:get_value(keyfile, ServerOpts), Version = tls_record:protocol_version(tls_record:highest_protocol_version([])), - Cmd = "openssl s_server -accept " ++ integer_to_list(Port) ++ version_flag(Version) ++ + Cmd = "openssl s_server -accept " ++ integer_to_list(Port) ++ ssl_test_lib:version_flag(Version) ++ " -cert " ++ CertFile ++ " -key " ++ KeyFile ++ " -msg", ct:log("openssl cmd: ~p~n", [Cmd]), OpensslPort = open_port({spawn, Cmd}, [stderr_to_stdout]), - wait_for_openssl_server(), + ssl_test_lib:wait_for_openssl_server(), Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port}, {host, Hostname}, @@ -559,7 +559,7 @@ erlang_server_openssl_client_nowrap_seqnum(Config) when is_list(Config) -> {options, [{renegotiate_at, N}, {reuse_sessions, false} | ServerOpts]}]), Port = ssl_test_lib:inet_port(Server), Version = tls_record:protocol_version(tls_record:highest_protocol_version([])), - Cmd = "openssl s_client -port " ++ integer_to_list(Port) ++ version_flag(Version) ++ + Cmd = "openssl s_client -port " ++ integer_to_list(Port) ++ ssl_test_lib:version_flag(Version) ++ " -host localhost -msg", ct:log("openssl cmd: ~p~n", [Cmd]), @@ -594,14 +594,14 @@ erlang_client_openssl_server_no_server_ca_cert(Config) when is_list(Config) -> CertFile = proplists:get_value(certfile, ServerOpts), KeyFile = proplists:get_value(keyfile, ServerOpts), Version = tls_record:protocol_version(tls_record:highest_protocol_version([])), - Cmd = "openssl s_server -accept " ++ integer_to_list(Port) ++ version_flag(Version) ++ + Cmd = "openssl s_server -accept " ++ integer_to_list(Port) ++ ssl_test_lib:version_flag(Version) ++ " -cert " ++ CertFile ++ " -key " ++ KeyFile ++ " -msg", ct:log("openssl cmd: ~p~n", [Cmd]), OpensslPort = open_port({spawn, Cmd}, [stderr_to_stdout]), - wait_for_openssl_server(), + ssl_test_lib:wait_for_openssl_server(), Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port}, {host, Hostname}, @@ -636,7 +636,7 @@ erlang_client_openssl_server_client_cert(Config) when is_list(Config) -> CaCertFile = proplists:get_value(cacertfile, ServerOpts), KeyFile = proplists:get_value(keyfile, ServerOpts), Version = tls_record:protocol_version(tls_record:highest_protocol_version([])), - Cmd = "openssl s_server -accept " ++ integer_to_list(Port) ++ version_flag(Version) ++ + Cmd = "openssl s_server -accept " ++ integer_to_list(Port) ++ ssl_test_lib:version_flag(Version) ++ " -cert " ++ CertFile ++ " -CAfile " ++ CaCertFile ++ " -key " ++ KeyFile ++ " -Verify 2", @@ -644,7 +644,7 @@ erlang_client_openssl_server_client_cert(Config) when is_list(Config) -> OpensslPort = open_port({spawn, Cmd}, [stderr_to_stdout]), - wait_for_openssl_server(), + ssl_test_lib:wait_for_openssl_server(), Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port}, {host, Hostname}, @@ -688,7 +688,7 @@ erlang_server_openssl_client_client_cert(Config) when is_list(Config) -> KeyFile = proplists:get_value(keyfile, ClientOpts), Version = tls_record:protocol_version(tls_record:highest_protocol_version([])), Cmd = "openssl s_client -cert " ++ CertFile ++ " -CAfile " ++ CaCertFile - ++ " -key " ++ KeyFile ++ " -port " ++ integer_to_list(Port) ++ version_flag(Version) ++ + ++ " -key " ++ KeyFile ++ " -port " ++ integer_to_list(Port) ++ ssl_test_lib:version_flag(Version) ++ " -host localhost", ct:log("openssl cmd: ~p~n", [Cmd]), @@ -776,14 +776,14 @@ erlang_client_bad_openssl_server(Config) when is_list(Config) -> CertFile = proplists:get_value(certfile, ServerOpts), KeyFile = proplists:get_value(keyfile, ServerOpts), Version = tls_record:protocol_version(tls_record:highest_protocol_version([])), - Cmd = "openssl s_server -accept " ++ integer_to_list(Port) ++ version_flag(Version) ++ + Cmd = "openssl s_server -accept " ++ integer_to_list(Port) ++ ssl_test_lib:version_flag(Version) ++ " -cert " ++ CertFile ++ " -key " ++ KeyFile ++ "", ct:log("openssl cmd: ~p~n", [Cmd]), OpensslPort = open_port({spawn, Cmd}, [stderr_to_stdout]), - wait_for_openssl_server(), + ssl_test_lib:wait_for_openssl_server(), Client0 = ssl_test_lib:start_client([{node, ClientNode}, {port, Port}, {host, Hostname}, @@ -839,7 +839,7 @@ expired_session(Config) when is_list(Config) -> OpensslPort = open_port({spawn, Cmd}, [stderr_to_stdout]), - wait_for_openssl_server(), + ssl_test_lib:wait_for_openssl_server(), Client0 = ssl_test_lib:start_client([{node, ClientNode}, @@ -1033,14 +1033,14 @@ cipher(CipherSuite, Version, Config, ClientOpts, ServerOpts) -> CertFile = proplists:get_value(certfile, ServerOpts), KeyFile = proplists:get_value(keyfile, ServerOpts), - Cmd = "openssl s_server -accept " ++ integer_to_list(Port) ++ version_flag(Version) ++ + Cmd = "openssl s_server -accept " ++ integer_to_list(Port) ++ ssl_test_lib:version_flag(Version) ++ " -cert " ++ CertFile ++ " -key " ++ KeyFile ++ "", ct:log("openssl cmd: ~p~n", [Cmd]), OpenSslPort = open_port({spawn, Cmd}, [stderr_to_stdout]), - wait_for_openssl_server(), + ssl_test_lib:wait_for_openssl_server(), ConnectionInfo = {ok, {Version, CipherSuite}}, @@ -1097,14 +1097,14 @@ start_erlang_client_and_openssl_server_with_opts(Config, ErlangClientOpts, Opens Version = tls_record:protocol_version(tls_record:highest_protocol_version([])), Cmd = "openssl s_server " ++ OpensslServerOpts ++ " -accept " ++ - integer_to_list(Port) ++ version_flag(Version) ++ + integer_to_list(Port) ++ ssl_test_lib:version_flag(Version) ++ " -cert " ++ CertFile ++ " -key " ++ KeyFile, ct:log("openssl cmd: ~p~n", [Cmd]), OpensslPort = open_port({spawn, Cmd}, [stderr_to_stdout]), - wait_for_openssl_server(), + ssl_test_lib:wait_for_openssl_server(), Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port}, {host, Hostname}, @@ -1136,14 +1136,14 @@ start_erlang_client_and_openssl_server_for_npn_negotiation(Config, Data, Callbac KeyFile = proplists:get_value(keyfile, ServerOpts), Version = tls_record:protocol_version(tls_record:highest_protocol_version([])), - Cmd = "openssl s_server -msg -nextprotoneg http/1.1,spdy/2 -accept " ++ integer_to_list(Port) ++ version_flag(Version) ++ + Cmd = "openssl s_server -msg -nextprotoneg http/1.1,spdy/2 -accept " ++ integer_to_list(Port) ++ ssl_test_lib:version_flag(Version) ++ " -cert " ++ CertFile ++ " -key " ++ KeyFile, ct:log("openssl cmd: ~p~n", [Cmd]), OpensslPort = open_port({spawn, Cmd}, [stderr_to_stdout]), - wait_for_openssl_server(), + ssl_test_lib:wait_for_openssl_server(), Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port}, {host, Hostname}, @@ -1174,7 +1174,7 @@ start_erlang_server_and_openssl_client_for_npn_negotiation(Config, Data, Callbac {options, ServerOpts}]), Port = ssl_test_lib:inet_port(Server), Version = tls_record:protocol_version(tls_record:highest_protocol_version([])), - Cmd = "openssl s_client -nextprotoneg http/1.0,spdy/2 -msg -port " ++ integer_to_list(Port) ++ version_flag(Version) ++ + Cmd = "openssl s_client -nextprotoneg http/1.0,spdy/2 -msg -port " ++ integer_to_list(Port) ++ ssl_test_lib:version_flag(Version) ++ " -host localhost", ct:log("openssl cmd: ~p~n", [Cmd]), @@ -1203,7 +1203,7 @@ start_erlang_server_and_openssl_client_with_opts(Config, ErlangServerOpts, OpenS {options, ServerOpts}]), Port = ssl_test_lib:inet_port(Server), Version = tls_record:protocol_version(tls_record:highest_protocol_version([])), - Cmd = "openssl s_client " ++ OpenSSLClientOpts ++ " -msg -port " ++ integer_to_list(Port) ++ version_flag(Version) ++ + Cmd = "openssl s_client " ++ OpenSSLClientOpts ++ " -msg -port " ++ integer_to_list(Port) ++ ssl_test_lib:version_flag(Version) ++ " -host localhost", ct:log("openssl cmd: ~p~n", [Cmd]), @@ -1302,25 +1302,6 @@ server_sent_garbage(Socket) -> end. -wait_for_openssl_server() -> - receive - {Port, {data, Debug}} when is_port(Port) -> - ct:log("openssl ~s~n",[Debug]), - %% openssl has started make sure - %% it will be in accept. Parsing - %% output is too error prone. (Even - %% more so than sleep!) - ct:sleep(?SLEEP) - end. - -version_flag(tlsv1) -> - " -tls1 "; -version_flag('tlsv1.1') -> - " -tls1_1 "; -version_flag('tlsv1.2') -> - " -tls1_2 "; -version_flag(sslv3) -> - " -ssl3 ". check_openssl_npn_support(Config) -> HelpText = os:cmd("openssl s_client --help"), @@ -1365,18 +1346,3 @@ supports_sslv2(Port) -> true end. -check_sane_openssl_version(Version) -> - case {Version, os:cmd("openssl version")} of - {_, "OpenSSL 1.0.1" ++ _} -> - true; - {'tlsv1.2', "OpenSSL 1.0" ++ _} -> - false; - {'tlsv1.1', "OpenSSL 1.0" ++ _} -> - false; - {'tlsv1.2', "OpenSSL 0" ++ _} -> - false; - {'tlsv1.1', "OpenSSL 0" ++ _} -> - false; - {_, _} -> - true - end. diff --git a/lib/ssl/vsn.mk b/lib/ssl/vsn.mk index 9dd151553c..78424ee578 100644 --- a/lib/ssl/vsn.mk +++ b/lib/ssl/vsn.mk @@ -1 +1 @@ -SSL_VSN = 5.3 +SSL_VSN = 5.3.1 diff --git a/lib/stdlib/doc/src/notes.xml b/lib/stdlib/doc/src/notes.xml index 2c1daf10ba..2f404523dd 100644 --- a/lib/stdlib/doc/src/notes.xml +++ b/lib/stdlib/doc/src/notes.xml @@ -30,6 +30,86 @@ </header> <p>This document describes the changes made to the STDLIB application.</p> +<section><title>STDLIB 1.19.3</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> The functions <c>dets:foldl/3</c>, + <c>dets:foldr/3</c>, and <c>dets:traverse/2</c> did not + release the table after having traversed the table to the + end. The bug was introduced in R16B. (Thanks to Manuel + Duran Aguete.) </p> + <p> + Own Id: OTP-11245</p> + </item> + <item> + <p> If the <c>fun M:F/A</c> construct was used + erroneously the linter could crash. (Thanks to Mikhail + Sobolev.) </p> + <p> + Own Id: OTP-11254</p> + </item> + <item> + <p> The specifications of <c>io_lib:fread/2,3</c> have + been corrected. (Thanks to Chris King and Kostis Sagonas + for pinpointing the bug.) </p> + <p> + Own Id: OTP-11261</p> + </item> + </list> + </section> + + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Fixed type typo in gen_server.</p> + <p> + Own Id: OTP-11200</p> + </item> + <item> + <p> + Update type specs in filelib and io_prompt. Thanks to + Jose Valim.</p> + <p> + Own Id: OTP-11208</p> + </item> + <item> + <p> + Fix typo in abcast() function comment. Thanks to Johannes + Weissl.</p> + <p> + Own Id: OTP-11219</p> + </item> + <item> + <p> + Make edlin understand a few important control keys. + Thanks to Stefan Zegenhagen.</p> + <p> + Own Id: OTP-11251</p> + </item> + <item> + <p> + Export the edge/0 type from the digraph module. Thanks to + Alex Ronne Petersen.</p> + <p> + Own Id: OTP-11266</p> + </item> + <item> + <p> + Fix variable usage tracking in erl_lint and fixed unsafe + variable tracking in try expressions. Thanks to Anthony + Ramine.</p> + <p> + Own Id: OTP-11268</p> + </item> + </list> + </section> + +</section> + <section><title>STDLIB 1.19.2</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/stdlib/src/dict.erl b/lib/stdlib/src/dict.erl index e3bfb6c2e2..32a7878da4 100644 --- a/lib/stdlib/src/dict.erl +++ b/lib/stdlib/src/dict.erl @@ -386,7 +386,7 @@ merge(F, D1, D2) -> update(K, fun (V1) -> F(K, V1, V2) end, V2, D) end, D1, D2). - + %% get_slot(Hashdb, Key) -> Slot. %% Get the slot. First hash on the new range, if we hit a bucket %% which has not been split use the unsplit buddy bucket. diff --git a/lib/stdlib/src/erl_compile.erl b/lib/stdlib/src/erl_compile.erl index 8c3d59467b..ed8fea5d78 100644 --- a/lib/stdlib/src/erl_compile.erl +++ b/lib/stdlib/src/erl_compile.erl @@ -21,10 +21,12 @@ -include("erl_compile.hrl"). -include("file.hrl"). --export([compile_cmdline/1]). +-export([compile_cmdline/0]). -export_type([cmd_line_arg/0]). +-define(STDERR, standard_error). %Macro to avoid misspellings. + %% Mapping from extension to {M,F} to run the correct compiler. compiler(".erl") -> {compile, compile}; @@ -47,9 +49,10 @@ compiler(_) -> no. -type cmd_line_arg() :: atom() | string(). --spec compile_cmdline([cmd_line_arg()]) -> no_return(). +-spec compile_cmdline() -> no_return(). -compile_cmdline(List) -> +compile_cmdline() -> + List = init:get_plain_arguments(), case compile(List) of ok -> my_halt(0); error -> my_halt(1); @@ -67,8 +70,12 @@ compile(List) -> receive {'EXIT', Pid, {compiler_result, Result}} -> Result; + {'EXIT', Pid, {compiler_error, Error}} -> + io:put_chars(?STDERR, Error), + io:nl(?STDERR), + error; {'EXIT', Pid, Reason} -> - io:format("Runtime error: ~tp~n", [Reason]), + io:format(?STDERR, "Runtime error: ~tp~n", [Reason]), error end. @@ -83,66 +90,178 @@ compiler_runner(List) -> %% Parses the first part of the option list. -compile1(['@cwd', Cwd|Rest]) -> - CwdL = atom_to_list(Cwd), - compile1(Rest, CwdL, #options{outdir=CwdL, cwd=CwdL}); compile1(Args) -> - %% From R13B02, the @cwd argument is optional. {ok, Cwd} = file:get_cwd(), - compile1(Args, Cwd, #options{outdir=Cwd, cwd=Cwd}). + compile1(Args, #options{outdir=Cwd,cwd=Cwd}). %% Parses all options. -compile1(['@i', Dir|Rest], Cwd, Opts) -> +compile1(["--"|Files], Opts) -> + compile2(Files, Opts); +compile1(["-"++Option|T], Opts) -> + parse_generic_option(Option, T, Opts); +compile1(["+"++Option|Rest], Opts) -> + Term = make_term(Option), + Specific = Opts#options.specific, + compile1(Rest, Opts#options{specific=[Term|Specific]}); +compile1(Files, Opts) -> + compile2(Files, Opts). + +parse_generic_option("b"++Opt, T0, Opts) -> + {OutputType,T} = get_option("b", Opt, T0), + compile1(T, Opts#options{output_type=list_to_atom(OutputType)}); +parse_generic_option("D"++Opt, T0, #options{defines=Defs}=Opts) -> + {Val0,T} = get_option("D", Opt, T0), + {Key0,Val1} = split_at_equals(Val0, []), + Key = list_to_atom(Key0), + case Val1 of + [] -> + compile1(T, Opts#options{defines=[Key|Defs]}); + Val2 -> + Val = make_term(Val2), + compile1(T, Opts#options{defines=[{Key,Val}|Defs]}) + end; +parse_generic_option("help", _, _Opts) -> + usage(); +parse_generic_option("I"++Opt, T0, #options{cwd=Cwd}=Opts) -> + {Dir,T} = get_option("I", Opt, T0), AbsDir = filename:absname(Dir, Cwd), - compile1(Rest, Cwd, Opts#options{includes=[AbsDir|Opts#options.includes]}); -compile1(['@outdir', Dir|Rest], Cwd, Opts) -> + compile1(T, Opts#options{includes=[AbsDir|Opts#options.includes]}); +parse_generic_option("M"++Opt, T0, #options{specific=Spec}=Opts) -> + case parse_dep_option(Opt, T0) of + error -> + error; + {SpecOpts,T} -> + compile1(T, Opts#options{specific=SpecOpts++Spec}) + end; +parse_generic_option("o"++Opt, T0, #options{cwd=Cwd}=Opts) -> + {Dir,T} = get_option("o", Opt, T0), AbsName = filename:absname(Dir, Cwd), case file_or_directory(AbsName) of file -> - compile1(Rest, Cwd, Opts#options{outfile=AbsName}); + compile1(T, Opts#options{outfile=AbsName}); directory -> - compile1(Rest, Cwd, Opts#options{outdir=AbsName}) + compile1(T, Opts#options{outdir=AbsName}) end; -compile1(['@d', Name|Rest], Cwd, Opts) -> - Defines = Opts#options.defines, - compile1(Rest, Cwd, Opts#options{defines=[Name|Defines]}); -compile1(['@dv', Name, Term|Rest], Cwd, Opts) -> - Defines = Opts#options.defines, - Value = make_term(atom_to_list(Term)), - compile1(Rest, Cwd, Opts#options{defines=[{Name, Value}|Defines]}); -compile1(['@warn', Level0|Rest], Cwd, Opts) -> - case catch list_to_integer(atom_to_list(Level0)) of - Level when is_integer(Level) -> - compile1(Rest, Cwd, Opts#options{warning=Level}); +parse_generic_option("O"++Opt, T, Opts) -> + case Opt of + "" -> + compile1(T, Opts#options{optimize=1}); _ -> - compile1(Rest, Cwd, Opts) + Term = make_term(Opt), + compile1(T, Opts#options{optimize=Term}) end; -compile1(['@verbose', false|Rest], Cwd, Opts) -> - compile1(Rest, Cwd, Opts#options{verbose=false}); -compile1(['@verbose', true|Rest], Cwd, Opts) -> - compile1(Rest, Cwd, Opts#options{verbose=true}); -compile1(['@optimize', Atom|Rest], Cwd, Opts) -> - Term = make_term(atom_to_list(Atom)), - compile1(Rest, Cwd, Opts#options{optimize=Term}); -compile1(['@option', Atom|Rest], Cwd, Opts) -> - Term = make_term(atom_to_list(Atom)), - Specific = Opts#options.specific, - compile1(Rest, Cwd, Opts#options{specific=[Term|Specific]}); -compile1(['@output_type', OutputType|Rest], Cwd, Opts) -> - compile1(Rest, Cwd, Opts#options{output_type=OutputType}); -compile1(['@files'|Rest], Cwd, Opts) -> - Includes = lists:reverse(Opts#options.includes), - compile2(Rest, Cwd, Opts#options{includes=Includes}). - -compile2(Files, Cwd, Opts) -> - case {Opts#options.outfile, length(Files)} of +parse_generic_option("v", T, Opts) -> + compile1(T, Opts#options{verbose=true}); +parse_generic_option("W"++Warn, T, #options{specific=Spec}=Opts) -> + case Warn of + "all" -> + compile1(T, Opts#options{warning=999}); + "error" -> + compile1(T, Opts#options{specific=[warnings_as_errors|Spec]}); + "" -> + compile1(T, Opts#options{warning=1}); + _ -> + try list_to_integer(Warn) of + Level -> + compile1(T, Opts#options{warning=Level}) + catch + error:badarg -> + usage() + end + end; +parse_generic_option("E", T, #options{specific=Spec}=Opts) -> + compile1(T, Opts#options{specific=['E'|Spec]}); +parse_generic_option("P", T, #options{specific=Spec}=Opts) -> + compile1(T, Opts#options{specific=['P'|Spec]}); +parse_generic_option("S", T, #options{specific=Spec}=Opts) -> + compile1(T, Opts#options{specific=['S'|Spec]}); +parse_generic_option(Option, _T, _Opts) -> + io:format(?STDERR, "Unknown option: -~s\n", [Option]), + usage(). + +parse_dep_option("", T) -> + {[makedep,{makedep_output,standard_io}],T}; +parse_dep_option("D", T) -> + {[makedep],T}; +parse_dep_option("F"++Opt, T0) -> + {File,T} = get_option("MF", Opt, T0), + {[makedep,{makedep_output,File}],T}; +parse_dep_option("G", T) -> + {[makedep_add_missing],T}; +parse_dep_option("P", T) -> + {[makedep_phony],T}; +parse_dep_option("Q"++Opt, T0) -> + {Target,T} = get_option("MT", Opt, T0), + {[makedep_quote_target,{makedep_target,Target}],T}; +parse_dep_option("T"++Opt, T0) -> + {Target,T} = get_option("MT", Opt, T0), + {[{makedep_target,Target}],T}; +parse_dep_option(Opt, _T) -> + io:format(?STDERR, "Unknown option: -M~s\n", [Opt]), + usage(). + +usage() -> + H = [{"-b type","type of output file (e.g. beam)"}, + {"-d","turn on debugging of erlc itself"}, + {"-Dname","define name"}, + {"-Dname=value","define name to have value"}, + {"-help","shows this help text"}, + {"-I path","where to search for include files"}, + {"-M","generate a rule for make(1) describing the dependencies"}, + {"-MF file","write the dependencies to 'file'"}, + {"-MT target","change the target of the rule emitted by dependency " + "generation"}, + {"-MQ target","same as -MT but quote characters special to make(1)"}, + {"-MG","consider missing headers as generated files and add them to " + "the dependencies"}, + {"-MP","add a phony target for each dependency"}, + {"-MD","same as -M -MT file (with default 'file')"}, + {"-o name","name output directory or file"}, + {"-pa path","add path to the front of Erlang's code path"}, + {"-pz path","add path to the end of Erlang's code path"}, + {"-smp","compile using SMP emulator"}, + {"-v","verbose compiler output"}, + {"-Werror","make all warnings into errors"}, + {"-W0","disable warnings"}, + {"-Wnumber","set warning level to number"}, + {"-Wall","enable all warnings"}, + {"-W","enable warnings (default; same as -W1)"}, + {"-E","generate listing of expanded code (Erlang compiler)"}, + {"-S","generate assembly listing (Erlang compiler)"}, + {"-P","generate listing of preprocessed code (Erlang compiler)"}, + {"+term","pass the Erlang term unchanged to the compiler"}], + io:put_chars(?STDERR, + ["Usage: erlc [Options] file.ext ...\n", + "Options:\n", + [io_lib:format("~-14s ~s\n", [K,D]) || {K,D} <- H]]), + error. + +get_option(_Name, [], [[C|_]=Option|T]) when C =/= $- -> + {Option,T}; +get_option(_Name, [_|_]=Option, T) -> + {Option,T}; +get_option(Name, _, _) -> + exit({compiler_error,"No value given to -"++Name++" option"}). + +split_at_equals([$=|T], Acc) -> + {lists:reverse(Acc),T}; +split_at_equals([H|T], Acc) -> + split_at_equals(T, [H|Acc]); +split_at_equals([], Acc) -> + {lists:reverse(Acc),[]}. + +compile2(Files, #options{cwd=Cwd,includes=Incl,outfile=Outfile}=Opts0) -> + Opts = Opts0#options{includes=lists:reverse(Incl)}, + case {Outfile,length(Files)} of {"", _} -> compile3(Files, Cwd, Opts); {[_|_], 1} -> compile3(Files, Cwd, Opts); {[_|_], _N} -> - io:format("Output file name given, but more than one input file.~n"), + io:put_chars(?STDERR, + "Output file name given, " + "but more than one input file.\n"), error end. @@ -170,23 +289,25 @@ compile3([], _Cwd, _Options) -> ok. %% Invokes the appropriate compiler, depending on the file extension. compile_file("", Input, _Output, _Options) -> - io:format("File has no extension: ~ts~n", [Input]), + io:format(?STDERR, "File has no extension: ~ts~n", [Input]), error; compile_file(Ext, Input, Output, Options) -> case compiler(Ext) of no -> - io:format("Unknown extension: '~ts'\n", [Ext]), + io:format(?STDERR, "Unknown extension: '~ts'\n", [Ext]), error; {M, F} -> case catch M:F(Input, Output, Options) of ok -> ok; error -> error; {'EXIT',Reason} -> - io:format("Compiler function ~w:~w/3 failed:\n~p~n", + io:format(?STDERR, + "Compiler function ~w:~w/3 failed:\n~p~n", [M,F,Reason]), error; Other -> - io:format("Compiler function ~w:~w/3 returned:\n~p~n", + io:format(?STDERR, + "Compiler function ~w:~w/3 returned:\n~p~n", [M,F,Other]), error end @@ -215,10 +336,10 @@ make_term(Str) -> case erl_parse:parse_term(Tokens ++ [{dot, 1}]) of {ok, Term} -> Term; {error, {_,_,Reason}} -> - io:format("~ts: ~ts~n", [Reason, Str]), + io:format(?STDERR, "~ts: ~ts~n", [Reason, Str]), throw(error) end; {error, {_,_,Reason}, _} -> - io:format("~ts: ~ts~n", [Reason, Str]), + io:format(?STDERR, "~ts: ~ts~n", [Reason, Str]), throw(error) end. diff --git a/lib/stdlib/src/erl_eval.erl b/lib/stdlib/src/erl_eval.erl index 73b8da335a..ca6a4b5c58 100644 --- a/lib/stdlib/src/erl_eval.erl +++ b/lib/stdlib/src/erl_eval.erl @@ -912,7 +912,7 @@ type_test(binary) -> is_binary; type_test(record) -> is_record; type_test(Test) -> Test. - + %% match(Pattern, Term, Bindings) -> %% {match,NewBindings} | nomatch %% or erlang:error({illegal_pattern, Pattern}). @@ -1051,7 +1051,7 @@ match_list([], [], Bs, _BBs) -> {match,Bs}; match_list(_, _, _Bs, _BBs) -> nomatch. - + %% new_bindings() %% bindings(Bindings) %% binding(Name, Bindings) diff --git a/lib/stdlib/src/erl_lint.erl b/lib/stdlib/src/erl_lint.erl index b6ab39251a..bcf3ccef3b 100644 --- a/lib/stdlib/src/erl_lint.erl +++ b/lib/stdlib/src/erl_lint.erl @@ -1955,12 +1955,10 @@ expr({string,_Line,_S}, _Vt, St) -> {[],St}; expr({nil,_Line}, _Vt, St) -> {[],St}; expr({cons,_Line,H,T}, Vt, St) -> expr_list([H,T], Vt, St); -expr({lc,_Line,E,Qs}, Vt0, St0) -> - {Vt,St} = handle_comprehension(E, Qs, Vt0, St0), - {vtold(Vt, Vt0),St}; %Don't export local variables -expr({bc,_Line,E,Qs}, Vt0, St0) -> - {Vt,St} = handle_comprehension(E, Qs, Vt0, St0), - {vtold(Vt,Vt0),St}; %Don't export local variables +expr({lc,_Line,E,Qs}, Vt, St) -> + handle_comprehension(E, Qs, Vt, St); +expr({bc,_Line,E,Qs}, Vt, St) -> + handle_comprehension(E, Qs, Vt, St); expr({tuple,_Line,Es}, Vt, St) -> expr_list(Es, Vt, St); expr({record_index,Line,Name,Field}, _Vt, St) -> @@ -2014,8 +2012,7 @@ expr({'fun',Line,Body}, Vt, St) -> %%No one can think funs export! case Body of {clauses,Cs} -> - {Bvt, St1} = fun_clauses(Cs, Vt, St), - {vtupdate(Bvt, Vt), St1}; + fun_clauses(Cs, Vt, St); {function,F,A} -> %% BifClash - Fun expression %% N.B. Only allows BIFs here as well, NO IMPORTS!! @@ -2113,12 +2110,12 @@ expr({'try',Line,Es,Scs,Ccs,As}, Vt, St0) -> {Evt0,St1} = exprs(Es, Vt, St0), TryLine = {'try',Line}, Uvt = vtunsafe(vtnames(vtnew(Evt0, Vt)), TryLine, []), - Evt1 = vtupdate(Uvt, vtupdate(Evt0, Vt)), - {Sccs,St2} = icrt_clauses(Scs++Ccs, TryLine, Evt1, St1), + Evt1 = vtupdate(Uvt, vtsubtract(Evt0, Uvt)), + {Sccs,St2} = icrt_clauses(Scs++Ccs, TryLine, vtupdate(Evt1, Vt), St1), Rvt0 = Sccs, Rvt1 = vtupdate(vtunsafe(vtnames(vtnew(Rvt0, Vt)), TryLine, []), Rvt0), Evt2 = vtmerge(Evt1, Rvt1), - {Avt0,St} = exprs(As, Evt2, St2), + {Avt0,St} = exprs(As, vtupdate(Evt2, Vt), St2), Avt1 = vtupdate(vtunsafe(vtnames(vtnew(Avt0, Vt)), TryLine, []), Avt0), Avt = vtmerge(Evt2, Avt1), {Avt,St}; @@ -2152,10 +2149,11 @@ expr({remote,Line,_M,_F}, _Vt, St) -> %% {UsedVarTable,State} expr_list(Es, Vt, St) -> - foldl(fun (E, {Esvt,St0}) -> - {Evt,St1} = expr(E, Vt, St0), - {vtmerge(Evt, Esvt),St1} - end, {[],St}, Es). + {Vt1,St1} = foldl(fun (E, {Esvt,St0}) -> + {Evt,St1} = expr(E, Vt, St0), + {vtmerge_pat(Evt, Esvt),St1} + end, {[],St}, Es), + {vtmerge(vtnew(Vt1, Vt), vtold(Vt1, Vt)),St1}. record_expr(Line, Rec, Vt, St0) -> St1 = warn_invalid_record(Line, Rec, St0), @@ -2312,7 +2310,7 @@ check_fields(Fs, Name, Fields, Vt, St0, CheckFun) -> check_field({record_field,Lf,{atom,La,F},Val}, Name, Fields, Vt, St, Sfs, CheckFun) -> case member(F, Sfs) of - true -> {Sfs,{Vt,add_error(Lf, {redefine_field,Name,F}, St)}}; + true -> {Sfs,{[],add_error(Lf, {redefine_field,Name,F}, St)}}; false -> {[F|Sfs], case find_field(F, Fields) of @@ -2845,7 +2843,9 @@ icrt_export(Csvt, Vt, In, St) -> Uvt = vtmerge(Evt, Unused), %% Make exported and unsafe unused variables unused in subsequent code: Vt2 = vtmerge(Uvt, vtsubtract(Vt1, Uvt)), - {Vt2,St}. + %% Forget about old variables which were not used: + Vt3 = vtmerge(vtnew(Vt2, Vt), vt_no_unused(vtold(Vt2, Vt))), + {Vt3,St}. handle_comprehension(E, Qs, Vt0, St0) -> {Vt1, Uvt, St1} = lc_quals(Qs, Vt0, St0), @@ -2858,7 +2858,11 @@ handle_comprehension(E, Qs, Vt0, St0) -> %% Local variables that have not been shadowed. {_,St} = check_unused_vars(Vt2, Vt0, St4), Vt3 = vtmerge(vtsubtract(Vt2, Uvt), Uvt), - {Vt3,St}. + %% Don't export local variables. + Vt4 = vtold(Vt3, Vt0), + %% Forget about old variables which were not used. + Vt5 = vt_no_unused(Vt4), + {Vt5,St}. %% lc_quals(Qualifiers, ImportVarTable, State) -> %% {VarTable,ShadowedVarTable,State} @@ -2939,7 +2943,7 @@ fun_clauses(Cs, Vt, St) -> {Cvt,St1} = fun_clause(C, Vt, St0), {vtmerge(Cvt, Bvt0),St1} end, {[],St#lint{recdef_top = false}}, Cs), - {Bvt,St2#lint{recdef_top = OldRecDef}}. + {vt_no_unused(vtold(Bvt, Vt)),St2#lint{recdef_top = OldRecDef}}. fun_clause({clause,_Line,H,G,B}, Vt0, St0) -> {Hvt,Binvt,St1} = head(H, Vt0, [], St0), % No imported pattern variables @@ -3200,6 +3204,8 @@ vt_no_unsafe(Vt) -> [V || {_,{S,_U,_L}}=V <- Vt, _ -> true end]. +vt_no_unused(Vt) -> [V || {_,{_,U,_L}}=V <- Vt, U =/= unused]. + %% vunion(VarTable1, VarTable2) -> [VarName]. %% vunion([VarTable]) -> [VarName]. %% vintersection(VarTable1, VarTable2) -> [VarName]. diff --git a/lib/stdlib/src/erl_tar.erl b/lib/stdlib/src/erl_tar.erl index f49c2a64f4..40b48d7999 100644 --- a/lib/stdlib/src/erl_tar.erl +++ b/lib/stdlib/src/erl_tar.erl @@ -219,7 +219,7 @@ format_error(Atom) when is_atom(Atom) -> format_error(Term) -> lists:flatten(io_lib:format("~tp", [Term])). - + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% %%% Useful definitions (also start of implementation). @@ -409,7 +409,7 @@ split_filename([Comp|Rest], Prefix, Suffix, Len) -> split_filename([], Prefix, Suffix, _) -> {filename:join(Prefix),filename:join(Suffix)}. - + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% %%% Retrieving files from a tape archive. diff --git a/lib/stdlib/src/filelib.erl b/lib/stdlib/src/filelib.erl index 5b7bc0ab21..a266daa084 100644 --- a/lib/stdlib/src/filelib.erl +++ b/lib/stdlib/src/filelib.erl @@ -248,7 +248,7 @@ ensure_dir(F) -> end end. - + %%% %%% Pattern matching using a compiled wildcard. %%% @@ -360,7 +360,7 @@ do_alt([], _File) -> do_list_dir(Dir, Mod) -> eval_list_dir(Dir, Mod). - + %%% Compiling a wildcard. %% Only for debugging. diff --git a/lib/stdlib/src/gen_server.erl b/lib/stdlib/src/gen_server.erl index 6776f3deaa..5f14e48b0a 100644 --- a/lib/stdlib/src/gen_server.erl +++ b/lib/stdlib/src/gen_server.erl @@ -393,7 +393,7 @@ decode_msg(Msg, Parent, Name, State, Mod, Time, Debug, Hib) -> end. %%% --------------------------------------------------- -%%% Send/recive functions +%%% Send/receive functions %%% --------------------------------------------------- do_send(Dest, Msg) -> case catch erlang:send(Dest, Msg, [noconnect]) of diff --git a/lib/stdlib/src/io_lib.erl b/lib/stdlib/src/io_lib.erl index 53781e97f1..375d05f359 100644 --- a/lib/stdlib/src/io_lib.erl +++ b/lib/stdlib/src/io_lib.erl @@ -582,7 +582,7 @@ printable_unicode_list(_) -> false. %Everything else is false nl() -> "\n". - + %% %% Utilities for collecting characters in input files %% diff --git a/lib/stdlib/src/lists.erl b/lib/stdlib/src/lists.erl index b5577165f4..d6a9f4645d 100644 --- a/lib/stdlib/src/lists.erl +++ b/lib/stdlib/src/lists.erl @@ -630,7 +630,7 @@ flatlength([H|T], L) when is_list(H) -> flatlength([_|T], L) -> flatlength(T, L + 1); flatlength([], L) -> L. - + %% keymember(Key, Index, [Tuple]) Now a BIF! %% keyfind(Key, Index, [Tuple]) A BIF! %% keysearch(Key, Index, [Tuple]) Now a BIF! @@ -1163,7 +1163,7 @@ rumerge(T1, []) -> T1; rumerge(T1, [H2 | T2]) -> lists:reverse(rumerge2_1(T1, T2, [], H2), []). - + %% all(Predicate, List) %% any(Predicate, List) %% map(Function, List) diff --git a/lib/stdlib/src/string.erl b/lib/stdlib/src/string.erl index 0675afb877..f9b083a56d 100644 --- a/lib/stdlib/src/string.erl +++ b/lib/stdlib/src/string.erl @@ -256,7 +256,7 @@ chars(C, N, Tail) when N > 0 -> chars(C, N-1, [C|Tail]); chars(C, 0, Tail) when is_integer(C) -> Tail. - + %% Torbjörn's bit. %%% COPIES %%% @@ -460,7 +460,7 @@ sub_string(String, Start) -> substr(String, Start). Stop :: pos_integer(). sub_string(String, Start, Stop) -> substr(String, Start, Stop - Start + 1). - + %% ISO/IEC 8859-1 (latin1) letters are converted, others are ignored %% diff --git a/lib/stdlib/test/binary_module_SUITE.erl b/lib/stdlib/test/binary_module_SUITE.erl index d6886ba1e5..d5a0fe21b4 100644 --- a/lib/stdlib/test/binary_module_SUITE.erl +++ b/lib/stdlib/test/binary_module_SUITE.erl @@ -248,6 +248,10 @@ badargs(Config) when is_list(Config) -> binary:matches(<<1,2,3>>, {ac,ets:match_spec_compile([{'_',[],['$_']}])}, [{scope,{0,1}}])), + %% OTP-11350 + badarg = ?MASK_ERROR( + binary:matches(<<"foo">>, + [<<>>, <<"f">>])), ?line badarg = ?MASK_ERROR(binary:longest_common_prefix( [<<0:10000,1,2,4,1:3>>, diff --git a/lib/stdlib/test/erl_lint_SUITE.erl b/lib/stdlib/test/erl_lint_SUITE.erl index fdaab2ee30..6bf87adf14 100644 --- a/lib/stdlib/test/erl_lint_SUITE.erl +++ b/lib/stdlib/test/erl_lint_SUITE.erl @@ -153,7 +153,16 @@ unused_vars_warn_basic(Config) when is_list(Config) -> {22,erl_lint,{unused_var,'N'}}, {23,erl_lint,{shadowed_var,'N','fun'}}, {28,erl_lint,{unused_var,'B'}}, - {29,erl_lint,{unused_var,'B'}}]}}], + {29,erl_lint,{unused_var,'B'}}]}}, + {basic2, + <<"-record(r, {x,y}). + f({X,Y}) -> {Z=X,Z=Y}; + f([H|T]) -> [Z=H|Z=T]; + f(#r{x=X,y=Y}) -> #r{x=A=X,y=A=Y}. + g({M, F}) -> (Z=M):(Z=F)(); + g({M, F, Arg}) -> (Z=M):F(Z=Arg). + h(X, Y) -> (Z=X) + (Z=Y).">>, + [warn_unused_vars], []}], ?line [] = run(Config, Ts), ok. @@ -539,7 +548,29 @@ unused_vars_warn_rec(Config) when is_list(Config) -> end. ">>, [warn_unused_vars], - {warnings,[{22,erl_lint,{unused_var,'Same'}}]}}], + {warnings,[{22,erl_lint,{unused_var,'Same'}}]}}, + {rec2, + <<"-record(r, {a,b}). + f(X, Y) -> #r{a=[K || K <- Y], b=[K || K <- Y]}. + g(X, Y) -> #r{a=lists:map(fun (K) -> K end, Y), + b=lists:map(fun (K) -> K end, Y)}. + h(X, Y) -> #r{a=case Y of _ when is_list(Y) -> Y end, + b=case Y of _ when is_list(Y) -> Y end}. + i(X, Y) -> #r{a=if is_list(Y) -> Y end, b=if is_list(Y) -> Y end}. + ">>, + [warn_unused_vars], + {warnings,[{2,erl_lint,{unused_var,'X'}}, + {3,erl_lint,{unused_var,'X'}}, + {5,erl_lint,{unused_var,'X'}}, + {7,erl_lint,{unused_var,'X'}}]}}, + {rec3, + <<"-record(r, {a}). + t() -> X = 1, #r{a=foo, a=bar, a=qux}. + ">>, + [warn_unused_vars], + {error,[{2,erl_lint,{redefine_field,r,a}}, + {2,erl_lint,{redefine_field,r,a}}], + [{2,erl_lint,{unused_var,'X'}}]}}], ?line [] = run(Config, Ts), ok. @@ -1077,7 +1108,24 @@ unsafe_vars_try(Config) when is_list(Config) -> {10,erl_lint,{unsafe_var,'Ra',{'try',3}}}, {10,erl_lint,{unsafe_var,'Rc',{'try',3}}}, {10,erl_lint,{unsafe_var,'Ro',{'try',3}}}], - []}}], + []}}, + {unsafe_try5, + <<"bang() -> + case 1 of + nil -> + Acc = 2; + _ -> + try + Acc = 3, + Acc + catch _:_ -> + ok + end + end, + Acc. + ">>, + [], + {errors,[{13,erl_lint,{unsafe_var,'Acc',{'try',6}}}],[]}}], ?line [] = run(Config, Ts), ok. diff --git a/lib/stdlib/test/slave_SUITE.erl b/lib/stdlib/test/slave_SUITE.erl index 37fc694083..1d6a3ac90d 100644 --- a/lib/stdlib/test/slave_SUITE.erl +++ b/lib/stdlib/test/slave_SUITE.erl @@ -230,7 +230,7 @@ rsh_test(ResultTo) -> link(ResultTo), ?line {error, no_rsh} = slave:start(super, slave3). - + %%% Utilities. diff --git a/lib/test_server/doc/src/notes.xml b/lib/test_server/doc/src/notes.xml index f3d4bc201a..bc83231950 100644 --- a/lib/test_server/doc/src/notes.xml +++ b/lib/test_server/doc/src/notes.xml @@ -32,6 +32,62 @@ <file>notes.xml</file> </header> +<section><title>Test_Server 3.6.3</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Test Server installed an error handler (test_server_h) + only to be able to write the name of the current test + case to stdout whenever it received an error- or progress + report. This functionality was not useful and has been + removed. The built-in Common Test hook, cth_log_redirect, + has instead been improved to now also tag all error- and + progress reports in the log with suite-, group-, and/or + test case name.</p> + <p> + Own Id: OTP-11263 Aux Id: seq12251 </p> + </item> + </list> + </section> + + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + A new log, the "Pre- and Post Test I/O Log", has been + introduced, which makes it possible to capture error- and + progress reports, as well as printouts made with ct:log/2 + and ct:pal/2, before and after a test run. (Some minor + improvements of the logging system have been made at the + same time). Links to the new log are found on the Common + Test Framework Log page. The Common Test User's Guide has + been updated with information about the new log and also + with a new section on how to synchronize external + applications with Common Test by means of the CT Hook + init and terminate functions.</p> + <p> + Own Id: OTP-11272</p> + </item> + </list> + </section> + + + <section><title>Known Bugs and Problems</title> + <list> + <item> + <p> + Test Server: Report auto_skipped in major log.</p> + <p> + Own Id: OTP-11297</p> + </item> + </list> + </section> + +</section> + <section><title>Test_Server 3.6.2</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/test_server/src/Makefile b/lib/test_server/src/Makefile index ebc5f5b71b..ab4dd4d95d 100644 --- a/lib/test_server/src/Makefile +++ b/lib/test_server/src/Makefile @@ -45,7 +45,6 @@ MODULES= test_server_ctrl \ test_server_node \ test_server \ test_server_sup \ - test_server_h \ erl2html2 TS_MODULES= \ diff --git a/lib/test_server/src/test_server.app.src b/lib/test_server/src/test_server.app.src index 163f370a47..42e78ed279 100644 --- a/lib/test_server/src/test_server.app.src +++ b/lib/test_server/src/test_server.app.src @@ -23,7 +23,6 @@ erl2html2, test_server_ctrl, test_server, - test_server_h, test_server_io, test_server_node, test_server_sup diff --git a/lib/test_server/src/test_server.erl b/lib/test_server/src/test_server.erl index c350f758ce..6ddb2b615f 100644 --- a/lib/test_server/src/test_server.erl +++ b/lib/test_server/src/test_server.erl @@ -389,7 +389,6 @@ run_test_case_apply({CaseNum,Mod,Func,Args,Name, os:putenv("VALGRIND_LOGFILE_INFIX",atom_to_list(Mod)++"."++ atom_to_list(Func)++"-") end, - test_server_h:testcase({Mod,Func,1}), ProcBef = erlang:system_info(process_count), Result = run_test_case_apply(Mod, Func, Args, Name, RunInit, TimetrapData), diff --git a/lib/test_server/src/test_server_ctrl.erl b/lib/test_server/src/test_server_ctrl.erl index ffa21d054c..d0f31af198 100644 --- a/lib/test_server/src/test_server_ctrl.erl +++ b/lib/test_server/src/test_server_ctrl.erl @@ -479,12 +479,6 @@ init([]) -> test_server_sup:call_trace(TraceSpec) end, process_flag(trap_exit, true), - case lists:keysearch(sasl, 1, application:which_applications()) of - {value,_} -> - test_server_h:install(); - false -> - ok - end, %% copy format_exception setting from init arg to application environment case init:get_argument(test_server_format_exception) of {ok,[[TSFE]]} -> @@ -1067,12 +1061,6 @@ terminate(_Reason, State) -> end, kill_all_jobs(State#state.jobs), test_server_node:kill_nodes(), - case lists:keysearch(sasl, 1, application:which_applications()) of - {value,_} -> - test_server_h:restore(); - _ -> - ok - end, ok. kill_all_jobs([{_Name,JobPid}|Jobs]) -> @@ -1183,7 +1171,13 @@ init_tester(Mod, Func, Args, Dir, Name, {_,_,MinLev}=Levels, "<td>~.3fs</td><td><b>~ts</b></td><td>~w Ok, ~w Failed~ts of ~w</td></tr>\n" "</tfoot>\n", [Time,SuccessStr,OkN,FailedN,SkipStr,OkN+FailedN+SkippedN]), - test_server_io:stop([major,html,unexpected_io]). + + test_server_io:stop([major,html,unexpected_io]), + {UnexpectedIoName,UnexpectedIoFooter} = get(test_server_unexpected_footer), + {ok,UnexpectedIoFd} = open_html_file(UnexpectedIoName, [append]), + io:put_chars(UnexpectedIoFd, "\n</pre>\n"++UnexpectedIoFooter), + file:close(UnexpectedIoFd), + ok. report_severe_error(Reason) -> test_server_sup:framework_call(report, [severe_error,Reason]). @@ -1642,15 +1636,13 @@ start_log_file() -> FilenameMode), ok = write_file(?last_file, TestDir1 ++ "\n", FilenameMode), put(test_server_log_dir_base,TestDir1), + MajorName = filename:join(TestDir1, ?suitelog_name), HtmlName = MajorName ++ ?html_ext, UnexpectedName = filename:join(TestDir1, ?unexpected_io_log), + {ok,Major} = open_utf8_file(MajorName), {ok,Html} = open_html_file(HtmlName), - {ok,Unexpected} = open_html_file(UnexpectedName), - test_server_io:set_fd(major, Major), - test_server_io:set_fd(html, Html), - test_server_io:set_fd(unexpected_io, Unexpected), {UnexpHeader,UnexpFooter} = case test_server_sup:framework_call(get_html_wrapper, @@ -1663,8 +1655,17 @@ start_log_file() -> {xhtml,UH,UF} -> {UH,UF} end, - io:put_chars(Unexpected, UnexpHeader++"\n<pre>\n"), - put(test_server_unexpected_footer,UnexpFooter), + + {ok,Unexpected} = open_html_file(UnexpectedName), + io:put_chars(Unexpected, [UnexpHeader, + xhtml("<br>\n<h2>Unexpected I/O</h2>", + "<br />\n<h3>Unexpected I/O</h3>"), + "\n<pre>\n"]), + put(test_server_unexpected_footer,{UnexpectedName,UnexpFooter}), + + test_server_io:set_fd(major, Major), + test_server_io:set_fd(html, Html), + test_server_io:set_fd(unexpected_io, Unexpected), make_html_link(filename:absname(?last_test ++ ?html_ext), HtmlName, filename:basename(Dir)), @@ -5299,6 +5300,9 @@ html_header(Title) -> open_html_file(File) -> open_utf8_file(File). +open_html_file(File,Opts) -> + open_utf8_file(File,Opts). + write_html_file(File,Content) -> write_file(File,Content,utf8). @@ -5307,6 +5311,9 @@ write_html_file(File,Content) -> open_utf8_file(File) -> file:open(File,[write,{encoding,utf8}]). +open_utf8_file(File,Opts) -> + file:open(File,[{encoding,utf8}|Opts]). + %% Write a file with specified encoding write_file(File,Content,latin1) -> file:write_file(File,Content); diff --git a/lib/test_server/src/test_server_h.erl b/lib/test_server/src/test_server_h.erl deleted file mode 100644 index 24063ddb10..0000000000 --- a/lib/test_server/src/test_server_h.erl +++ /dev/null @@ -1,148 +0,0 @@ -%% -%% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2005-2013. All Rights Reserved. -%% -%% The contents of this file are subject to the Erlang Public License, -%% Version 1.1, (the "License"); you may not use this file except in -%% compliance with the License. You should have received a copy of the -%% Erlang Public License along with this software. If not, it can be -%% retrieved online at http://www.erlang.org/. -%% -%% Software distributed under the License is distributed on an "AS IS" -%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See -%% the License for the specific language governing rights and limitations -%% under the License. -%% -%% %CopyrightEnd% -%% - --module(test_server_h). --behaviour(gen_event). - -%% API --export([install/0, restore/0]). --export([testcase/1]). - -%% gen_event callbacks --export([init/1, handle_event/2, handle_call/2, - handle_info/2, terminate/2, code_change/3]). - --record(state, {kernel, sasl, testcase}). - -%%==================================================================== -%% API -%%==================================================================== - -install() -> - case gen_event:add_handler(error_logger, ?MODULE, []) of - ok -> - error_logger:delete_report_handler(sasl_report_tty_h), - gen_event:delete_handler(error_logger, error_logger_tty_h, []), - ok; - Error -> - Error - end. - -restore() -> - gen_event:add_handler(error_logger, error_logger_tty_h, []), - error_logger:add_report_handler(sasl_report_tty_h, all), - gen_event:delete_handler(error_logger, ?MODULE, []). - -testcase(Testcase) -> - gen_event:call(error_logger, ?MODULE, {set_testcase, Testcase}, 10*60*1000). - -%%==================================================================== -%% gen_event callbacks -%%==================================================================== - -init([]) -> - - %% error_logger_tty_h initialization - User = set_group_leader(), - - %% sasl_report_tty_h initialization - Type = all, - - {ok, #state{kernel={User, []}, sasl=Type}}. - -set_group_leader() -> - case whereis(user) of - User when is_pid(User) -> - link(User), - group_leader(User, self()), - User; - _ -> - false - end. - -handle_event({_Type, GL, _Msg}, State) when node(GL)/=node() -> - {ok, State}; -handle_event({Tag, _GL, {_Pid, Type, _Report}} = Event, State) -> - SASL = lists:keyfind(sasl, 1, application:which_applications()), - case report_receiver(Tag, Type) of - sasl when SASL /= false -> - {ok,ErrLogType} = application:get_env(sasl, errlog_type), - SReport = sasl_report:format_report(group_leader(), ErrLogType, - tag_event(Event)), - if is_list(SReport) -> - tag(State#state.testcase), - sasl_report_tty_h:handle_event(Event, - State#state.sasl); - true -> %% Report is an atom if no logging is to be done - ignore - end; - sasl -> %% SASL not running - ignore; - kernel -> - tag(State#state.testcase), - error_logger_tty_h:handle_event(Event, State#state.kernel); - none -> - ignore - end, - {ok, State}; -handle_event(_Event, State) -> - {ok, State}. - -handle_call({set_testcase, Testcase}, State) -> - {ok, ok, State#state{testcase=Testcase}}; -handle_call(_Query, _State) -> - {error, bad_query}. - -handle_info({emulator,GL,_Chars}=Event, State) when node(GL)==node() -> - tag(State#state.testcase), - error_logger_tty_h:handle_info(Event, State#state.kernel), - {ok, State}; -handle_info(_Msg, State) -> - {ok, State}. - -terminate(_Reason, _State) -> - ok. - -code_change(_OldVsn, State, _Extra) -> - {ok, State}. - -report_receiver(error_report, supervisor_report) -> sasl; -report_receiver(error_report, crash_report) -> sasl; -report_receiver(info_report, progress) -> sasl; -report_receiver(error, _) -> kernel; -report_receiver(error_report, _) -> kernel; -report_receiver(warning_msg, _) -> kernel; -report_receiver(warning_report, _) -> kernel; -report_receiver(info, _) -> kernel; -report_receiver(info_msg, _) -> kernel; -report_receiver(info_report,Tuple) - when is_tuple(Tuple) andalso - (element(1,Tuple)==ct_connection orelse - element(1,Tuple)==conn_log) -> - none; -report_receiver(info_report, _) -> kernel; -report_receiver(_, _) -> none. - -tag({M,F,A}) when is_atom(M), is_atom(F), is_integer(A) -> - io:format(user, "~n=TESTCASE: ~w:~w/~w", [M,F,A]); -tag(Testcase) -> - io:format(user, "~n=TESTCASE: ~p", [Testcase]). - -tag_event(Event) -> - {calendar:local_time(), Event}. diff --git a/lib/test_server/src/test_server_io.erl b/lib/test_server/src/test_server_io.erl index 73d4468bda..62af3d5b28 100644 --- a/lib/test_server/src/test_server_io.erl +++ b/lib/test_server/src/test_server_io.erl @@ -32,27 +32,39 @@ -export([start_link/0,stop/1,get_gl/1,set_fd/2, start_transaction/0,end_transaction/0, print_buffered/1,print/3,print_unexpected/1, - set_footer/1,set_job_name/1,set_gl_props/1]). + set_footer/1,set_job_name/1,set_gl_props/1, + reset_state/0,finish/0]). -export([init/1,handle_call/3,handle_info/2,terminate/2]). --record(st, {fds, %Singleton fds (gb_tree) - shared_gl :: pid(), %Shared group leader - gls, %Group leaders (gb_set) - io_buffering=false, %I/O buffering - buffered, %Buffered I/O requests - html_footer, %HTML footer - job_name, %Name of current job. - gl_props, %Properties for GL. - stopping +-record(st, {fds, % Singleton fds (gb_tree) + tags=[], % Known tag types + shared_gl :: pid(), % Shared group leader + gls, % Group leaders (gb_set) + io_buffering=false, % I/O buffering + buffered, % Buffered I/O requests + html_footer, % HTML footer + job_name, % Name of current job. + gl_props, % Properties for GL + phase, % Indicates current mode + offline_buffer, % Buffer I/O during startup + stopping, % Reply to when process stopped + pending_ops % Perform when process idle }). start_link() -> - case gen_server:start_link({local,?MODULE}, ?MODULE, [], []) of - {ok,Pid} -> - {ok,Pid}; - Other -> - Other + case whereis(?MODULE) of + undefined -> + case gen_server:start_link({local,?MODULE}, ?MODULE, [], []) of + {ok,Pid} -> + {ok,Pid}; + Other -> + Other + end; + Pid -> + %% already running, reset the state + reset_state(), + {ok,Pid} end. stop(FilesToClose) -> @@ -62,6 +74,9 @@ stop(FilesToClose) -> group_leader(OldGL, self()), ok. +finish() -> + req(finish). + %% get_gl(Shared) -> Pid %% Shared = boolean() %% Pid = pid() @@ -142,19 +157,27 @@ set_footer(Footer) -> req({set_footer,Footer}). %% set_job_name(Name) +%% %% Set a name for the currently running job. The name will be used %% when printing to 'stdout'. %% + set_job_name(Name) -> req({set_job_name,Name}). %% set_gl_props(PropList) +%% %% Set properties for group leader processes. When a group_leader process %% is created, test_server_gl:set_props(PropList) will be called. set_gl_props(PropList) -> req({set_gl_props,PropList}). +%% reset_state +%% +%% Reset the initial state +reset_state() -> + req(reset_state). %%% Internal functions. @@ -167,7 +190,10 @@ init([]) -> buffered=Empty, html_footer="</body>\n</html>\n", job_name="<name not set>", - gl_props=[]}}. + gl_props=[], + phase=starting, + offline_buffer=[], + pending_ops=[]}}. req(Req) -> gen_server:call(?MODULE, Req, infinity). @@ -178,9 +204,24 @@ handle_call({get_gl,false}, _From, #st{gls=Gls,gl_props=Props}=St) -> {reply,Pid,St#st{gls=gb_sets:insert(Pid, Gls)}}; handle_call({get_gl,true}, _From, #st{shared_gl=Shared}=St) -> {reply,Shared,St}; -handle_call({set_fd,Tag,Fd}, _From, #st{fds=Fds0}=St) -> +handle_call({set_fd,Tag,Fd}, _From, #st{fds=Fds0,tags=Tags0, + offline_buffer=OfflineBuff}=St) -> Fds = gb_trees:enter(Tag, Fd, Fds0), - {reply,ok,St#st{fds=Fds}}; + St1 = St#st{fds=Fds,tags=[Tag|lists:delete(Tag, Tags0)]}, + OfflineBuff1 = + if OfflineBuff == [] -> + []; + true -> + %% Fd ready, print anything buffered for associated Tag + lists:filtermap(fun({T,From,Str}) when T == Tag -> + output(From, Tag, Str, St1), + false; + (_) -> + true + end, lists:reverse(OfflineBuff)) + end, + {reply,ok,St1#st{phase=started, + offline_buffer=lists:reverse(OfflineBuff1)}}; handle_call({start_transaction,Pid}, _From, #st{io_buffering=Buffer0, buffered=Buf0}=St) -> Buf = case gb_trees:is_defined(Pid, Buf0) of @@ -213,12 +254,15 @@ handle_call({set_job_name,Name}, _From, St) -> handle_call({set_gl_props,Props}, _From, #st{shared_gl=Shared}=St) -> test_server_gl:set_props(Shared, Props), {reply,ok,St#st{gl_props=Props}}; -handle_call({stop,FdTags}, From, #st{fds=Fds,shared_gl=SGL,gls=Gls0}=St0) -> - St = St0#st{gls=gb_sets:insert(SGL, Gls0),stopping=From}, - gc(St), - %% Give the users of the surviving group leaders some - %% time to finish. - erlang:send_after(2000, self(), stop_group_leaders), +handle_call(reset_state, From, #st{phase=stopping,pending_ops=Ops}=St) -> + %% can't reset during stopping phase, save op for later + Op = fun(NewSt) -> + {_,Result,NewSt1} = handle_call(reset_state, From, NewSt), + {Result,NewSt1} + end, + {noreply,St#st{pending_ops=[{From,Op}|Ops]}}; +handle_call(reset_state, _From, #st{fds=Fds,tags=Tags,gls=Gls, + offline_buffer=OfflineBuff}) -> %% close open log files lists:foreach(fun(Tag) -> case gb_trees:lookup(Tag, Fds) of @@ -227,8 +271,50 @@ handle_call({stop,FdTags}, From, #st{fds=Fds,shared_gl=SGL,gls=Gls0}=St0) -> {value,Fd} -> file:close(Fd) end - end, FdTags), - {noreply,St}. + end, Tags), + GlList = gb_sets:to_list(Gls), + [test_server_gl:stop(GL) || GL <- GlList], + timer:sleep(100), + case lists:filter(fun(GlPid) -> is_process_alive(GlPid) end, GlList) of + [] -> + ok; + _ -> + timer:sleep(2000), + [exit(GL, kill) || GL <- GlList] + end, + Empty = gb_trees:empty(), + {ok,Shared} = test_server_gl:start_link(), + {reply,ok,#st{fds=Empty,shared_gl=Shared,gls=gb_sets:empty(), + io_buffering=gb_sets:empty(), + buffered=Empty, + html_footer="</body>\n</html>\n", + job_name="<name not set>", + gl_props=[], + phase=starting, + offline_buffer=OfflineBuff, + pending_ops=[]}}; +handle_call({stop,FdTags}, From, #st{fds=Fds0,tags=Tags0, + shared_gl=SGL,gls=Gls0}=St0) -> + St = St0#st{gls=gb_sets:insert(SGL, Gls0),phase=stopping,stopping=From}, + gc(St), + %% close open log files + {Fds1,Tags1} = lists:foldl(fun(Tag, {Fds,Tags}) -> + case gb_trees:lookup(Tag, Fds) of + none -> + {Fds,Tags}; + {value,Fd} -> + file:close(Fd), + {gb_trees:delete(Tag, Fds), + lists:delete(Tag, Tags)} + end + end, {Fds0,Tags0}, FdTags), + %% Give the users of the surviving group leaders some + %% time to finish. + erlang:send_after(1000, self(), stop_group_leaders), + {noreply,St#st{fds=Fds1,tags=Tags1}}; +handle_call(finish, From, St) -> + gen_server:reply(From, ok), + {stop,normal,St}. handle_info({'EXIT',Pid,normal}, #st{gls=Gls0,stopping=From}=St) -> Gls = gb_sets:delete_any(Pid, Gls0), @@ -236,22 +322,40 @@ handle_info({'EXIT',Pid,normal}, #st{gls=Gls0,stopping=From}=St) -> true -> %% No more group leaders left. gen_server:reply(From, ok), - {stop,normal,St#st{gls=Gls,stopping=undefined}}; + {noreply,St#st{gls=Gls,phase=stopping,stopping=undefined}}; false -> %% Wait for more group leaders to finish. - {noreply,St#st{gls=Gls}} + {noreply,St#st{gls=Gls,phase=stopping}} end; handle_info({'EXIT',_Pid,Reason}, _St) -> exit(Reason); handle_info(stop_group_leaders, #st{gls=Gls}=St) -> %% Stop the remaining group leaders. - [test_server_gl:stop(GL) || GL <- gb_sets:to_list(Gls)], - erlang:send_after(2000, self(), kill_group_leaders), + GlPids = gb_sets:to_list(Gls), + [test_server_gl:stop(GL) || GL <- GlPids], + timer:sleep(100), + Wait = + case lists:filter(fun(GlPid) -> is_process_alive(GlPid) end, GlPids) of + [] -> 0; + _ -> 2000 + end, + erlang:send_after(Wait, self(), kill_group_leaders), {noreply,St}; -handle_info(kill_group_leaders, #st{gls=Gls,stopping=From}=St) -> +handle_info(kill_group_leaders, #st{gls=Gls,stopping=From, + pending_ops=Ops}=St) -> [exit(GL, kill) || GL <- gb_sets:to_list(Gls)], - gen_server:reply(From, ok), - {stop,normal,St}; + if From /= undefined -> + gen_server:reply(From, ok); + true -> % reply has been sent already + ok + end, + %% we're idle, check if any ops are pending + St1 = lists:foldr(fun({ReplyTo,Op},NewSt) -> + {Result,NewSt1} = Op(NewSt), + gen_server:reply(ReplyTo, Result), + NewSt1 + end, St#st{phase=idle,pending_ops=[]}, Ops), + {noreply,St1}; handle_info(Other, St) -> io:format("Ignoring: ~p\n", [Other]), {noreply,St}. @@ -259,11 +363,19 @@ handle_info(Other, St) -> terminate(_, _) -> ok. -output(From, Tag, Str, #st{io_buffering=Buffered,buffered=Buf0}=St) -> +output(From, Tag, Str, #st{io_buffering=Buffered,buffered=Buf0, + phase=Phase,offline_buffer=OfflineBuff}=St) -> case gb_sets:is_member(From, Buffered) of false -> - do_output(Tag, Str, St), - St; + case do_output(Tag, Str, Phase, St) of + buffer when length(OfflineBuff)>500 -> + %% something's wrong, clear buffer + St#st{offline_buffer=[]}; + buffer -> + St#st{offline_buffer=[{Tag,From,Str}|OfflineBuff]}; + _ -> + St + end; true -> Q0 = gb_trees:get(From, Buf0), Q = queue:in({Tag,Str}, Q0), @@ -271,17 +383,19 @@ output(From, Tag, Str, #st{io_buffering=Buffered,buffered=Buf0}=St) -> St#st{buffered=Buf} end. -do_output(stdout, Str, #st{job_name=undefined}) -> +do_output(stdout, Str, _, #st{job_name=undefined}) -> io:put_chars(Str); -do_output(stdout, Str0, #st{job_name=Name}) -> +do_output(stdout, Str0, _, #st{job_name=Name}) -> Str = io_lib:format("Testing ~ts: ~ts\n", [Name,Str0]), io:put_chars(Str); -do_output(Tag, Str, #st{fds=Fds}=St) -> +do_output(Tag, Str, Phase, #st{fds=Fds}=St) -> case gb_trees:lookup(Tag, Fds) of + none when Phase /= started -> + buffer; none -> S = io_lib:format("\n*** ERROR: ~w, line ~w: No known '~p' log file\n", [?MODULE,?LINE,Tag]), - do_output(stdout, [S,Str], St); + do_output(stdout, [S,Str], Phase, St); {value,Fd} -> try io:put_chars(Fd, Str), @@ -293,14 +407,14 @@ do_output(Tag, Str, #st{fds=Fds}=St) -> S = io_lib:format("\n*** ERROR: ~w, line ~w: Error writing to " "log file '~p': ~p\n", [?MODULE,?LINE,Tag,Error]), - do_output(stdout, [S,Str], St) + do_output(stdout, [S,Str], Phase, St) end end. finalise_table(Fd, #st{html_footer=Footer}) -> case file:position(Fd, {cur,0}) of {ok,Pos} -> - %% We are writing to a seekable file. Finalise so + %% We are writing to a seekable file. Finalise so %% we get complete valid (and viewable) HTML code. %% Then rewind to overwrite the finalising code. io:put_chars(Fd, ["\n</table>\n",Footer]), @@ -319,7 +433,7 @@ do_print_buffered(Q0, St) -> eot -> Q; {Tag,Str} -> - do_output(Tag, Str, St), + do_output(Tag, Str, undefined, St), do_print_buffered(Q, St) end. diff --git a/lib/test_server/src/ts.erl b/lib/test_server/src/ts.erl index 8e71c69d35..189a71a8ce 100644 --- a/lib/test_server/src/ts.erl +++ b/lib/test_server/src/ts.erl @@ -622,7 +622,7 @@ run_test(File, Args, Options) -> run_test(File, Args, Options, Vars) -> ts_run:run(File, Args, Options, Vars). - + %% This module provides some convenient shortcuts to running %% the test server from within a started Erlang shell. %% (This are here for backwards compatibility.) diff --git a/lib/test_server/vsn.mk b/lib/test_server/vsn.mk index 1753bbb913..0e37512dc2 100644 --- a/lib/test_server/vsn.mk +++ b/lib/test_server/vsn.mk @@ -1 +1 @@ -TEST_SERVER_VSN = 3.6.2 +TEST_SERVER_VSN = 3.6.3 diff --git a/lib/tools/doc/src/notes.xml b/lib/tools/doc/src/notes.xml index 422d4538a6..d8239460b3 100644 --- a/lib/tools/doc/src/notes.xml +++ b/lib/tools/doc/src/notes.xml @@ -30,6 +30,37 @@ </header> <p>This document describes the changes made to the Tools application.</p> +<section><title>Tools 2.6.12</title> + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Remove trailing spaces in Emacs templates. Thanks to + Roberto Aloi.</p> + <p> + Own Id: OTP-11198</p> + </item> + <item> + <p> + Fixed the Emacs erlang-mode to accommodate the coding + style where lists written across several lines have each + line starting with a comma. Thanks to Magnus Henoch.</p> + <p> + Own Id: OTP-11242</p> + </item> + <item> + <p> + Make the Emacs Erlang mode TRAMP-aware when compiling. + Thanks to Tomas Abrahamsson.</p> + <p> + Own Id: OTP-11270</p> + </item> + </list> + </section> + +</section> + <section><title>Tools 2.6.11</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/tools/emacs/erlang-start.el b/lib/tools/emacs/erlang-start.el index e1dc86621e..76e0575e68 100644 --- a/lib/tools/emacs/erlang-start.el +++ b/lib/tools/emacs/erlang-start.el @@ -52,7 +52,7 @@ ;; ;; To set the variable you can use the following command: ;; M-x set-variable RET debug-on-error RET t RET - + ;;; Code: ;; diff --git a/lib/tools/emacs/erlang.el b/lib/tools/emacs/erlang.el index 624042204c..b8699a616d 100644 --- a/lib/tools/emacs/erlang.el +++ b/lib/tools/emacs/erlang.el @@ -1025,7 +1025,7 @@ behaviour.") (defvar erlang-mode-syntax-table nil "Syntax table in use in Erlang-mode buffers.") - + (defvar erlang-skel-file "erlang-skels" "The type of erlang-skeletons that should be used, default @@ -1272,7 +1272,7 @@ Unfortunately, XEmacs hasn't got support for a special Font Lock syntax table. The effect is that `apply' in the atom `foo_apply' will be highlighted as a bif.") - + ;;; Avoid errors while compiling this file. ;; `eval-when-compile' is not defined in Emacs 18. We define it as a @@ -1321,7 +1321,7 @@ Lock syntax table. The effect is that `apply' in the atom (require 'tempo) (require 'compile)))) - + (defun erlang-version () "Return the current version of Erlang mode." (interactive) @@ -1516,7 +1516,7 @@ Other commands: (set (make-local-variable 'outline-level) (lambda () 1)) (set (make-local-variable 'add-log-current-defun-function) 'erlang-current-defun)) - + (defun erlang-font-lock-init () "Initialize Font Lock for Erlang mode." (or erlang-font-lock-syntax-table @@ -1686,7 +1686,7 @@ plus variables, macros and records." (font-lock-mode 1) (funcall (symbol-function 'font-lock-fontify-buffer))) - + (defun erlang-menu-init () "Init menus for Erlang mode. @@ -1905,7 +1905,7 @@ Example: The new menu is returned. No guarantee is given that the original menu is left unchanged." (delq entry items)) - + ;; Man code: (defun erlang-man-init () @@ -2228,7 +2228,7 @@ For example: After installing the line, kill and restart Emacs, or restart Erlang mode with the command `M-x erlang-mode RET'."))) - + ;; Skeleton code: ;; This code is based on the package `tempo' which is part of modern @@ -2349,7 +2349,7 @@ The first character of DD is space if the value is less than 10." (erlang-string-to-int (substring date 8 10)) (substring date 4 7) (substring date -4)))) - + ;; Indentation code: (defun erlang-indent-command (&optional whole-exp) @@ -3132,7 +3132,7 @@ commands." (skip-chars-backward " \t") (max (if (bolp) 0 (1+ (current-column))) comment-column))))) - + ;;; Erlang movement commands ;; All commands below work as movement commands. I.e. if the point is @@ -3336,7 +3336,7 @@ With negative argument go towards the beginning of the buffer." (forward-sexp 1) (buffer-substring start (point))))) - + ;;; Miscellaneous (defun erlang-fill-paragraph (&optional justify) @@ -3445,7 +3445,7 @@ at the end." (error "Can't clone argument list")) (insert args) (set-mark p))) - + ;;; Information retrieval functions. (defun erlang-buffer-substring (beg end) @@ -3772,7 +3772,7 @@ exported function." (store-match-data old-match-data) (member (cons name arity) exports)))) - + ;;; Check module name ;; The function `write-file', bound to C-x C-w, calls @@ -3835,7 +3835,7 @@ This function is normally placed in the hook `local-write-file-hooks'." ;; Must return nil since it is added to `local-write-file-hook'. nil) - + ;;; Electric functions. (defun erlang-electric-semicolon (&optional arg) @@ -4229,7 +4229,7 @@ This function is designed to be a member of a criteria list." (erlang-skip-blank) (looking-at "end[^_a-zA-Z0-9]"))) - + ;; Erlang tags support which is aware of erlang modules. ;; ;; Not yet implemented under XEmacs. (Hint: The Emacs 19 etags @@ -4539,7 +4539,7 @@ Tags can be given on the forms `tag', `module:', `module:tag'." (or default (error "There is no default tag")) spec))))) - + ;; Search tag functions which are aware of Erlang modules. The tactic ;; is to store new search functions into the local variables of the ;; TAGS buffers. The variables are restored directly after the @@ -4715,7 +4715,7 @@ for a tag on the form `module:tag'." (string= mod (erlang-get-module-from-file-name (file-of-tag))))))) - + ;;; Tags completion, Emacs 19 `etags' specific. ;;; ;;; The basic idea is to create a second completion table `erlang-tags- @@ -4834,7 +4834,7 @@ about Erlang modules." ;; Only the first one will be stored in the table. (intern (concat module ":") table)))))) table)) - + ;;; ;;; Prepare for other methods to run an Erlang slave process. ;;; @@ -4916,7 +4916,7 @@ future, a new shell on an already running host will be started." (call-interactively erlang-next-error-function)) - + ;;; ;;; Erlang Shell Mode -- Major mode used for Erlang shells. ;;; @@ -5052,7 +5052,7 @@ Selects Comint or Compilation mode command as appropriate." (define-key map "\M-\C-m" 'compile-goto-error) (unless inferior-erlang-use-cmm (define-key map "\C-x`" 'erlang-next-error))) - + ;;; ;;; Inferior Erlang -- Run an Erlang shell as a subprocess. ;;; diff --git a/lib/tools/src/tags.erl b/lib/tools/src/tags.erl index 1c72ef8db5..e3cc51cdb2 100644 --- a/lib/tools/src/tags.erl +++ b/lib/tools/src/tags.erl @@ -292,7 +292,7 @@ word_char(C) when C >= $0, C =< $9 -> true; word_char($_) -> true; word_char(_) -> false. - + %%% Output routines %% Check the options `outfile' and `outdir'. @@ -323,7 +323,7 @@ genout(Os, Name, Entries) -> io:put_chars(Os, lists:reverse(Entries)). - + %%% help routines %% Flatten and reverse a nested list. diff --git a/lib/tools/test/eprof_SUITE_data/eed.erl b/lib/tools/test/eprof_SUITE_data/eed.erl index 520c5f3dd1..5f2a21aa60 100644 --- a/lib/tools/test/eprof_SUITE_data/eed.erl +++ b/lib/tools/test/eprof_SUITE_data/eed.erl @@ -146,7 +146,7 @@ format_error({'EXIT', {Code, {Mod, Func, Args}}}) -> [{Code, {Mod, Func, length(Args)}}])); format_error(A) -> atom_to_list(A). - + %%% Parsing commands. @@ -327,7 +327,7 @@ when 0 =< Num1, Num1 =< Num2, Num2 =< State#state.lines -> check_lines(_, _, _, _) -> error(bad_linenum). - + %%% Executing commands. %% ($)= - print line number @@ -657,7 +657,7 @@ undo_command(_, _, _) -> write_command(_Cmd, [_First, _Last], _St) -> error(not_implemented). - + %%% Primitive buffer operations. print_current(St) -> @@ -717,7 +717,7 @@ wrap_next_line(State) when State#state.dot == State#state.lines -> wrap_next_line(State) -> next_line(State). - + %%% Utilities. get_pattern(End, Cmd, State) -> diff --git a/lib/tools/vsn.mk b/lib/tools/vsn.mk index a30b16fc49..c51b833dd0 100644 --- a/lib/tools/vsn.mk +++ b/lib/tools/vsn.mk @@ -1 +1 @@ -TOOLS_VSN = 2.6.11 +TOOLS_VSN = 2.6.12 diff --git a/lib/wx/api_gen/wx_extra/bugs.h b/lib/wx/api_gen/wx_extra/bugs.h index e3a4fa200b..0563a8901f 100644 --- a/lib/wx/api_gen/wx_extra/bugs.h +++ b/lib/wx/api_gen/wx_extra/bugs.h @@ -39,4 +39,12 @@ class WXDLLIMPEXP_ADV wxTreeCtrlBase : public wxControl { public: static bool IsTreeItemIdOk(wxTreeItemId id); -} +}; + + +// Enable lost macro functionality +class WXDLLEXPORT wxPanel : public wxWindow +{ + public: + void SetFocusIgnoringChildren(); +}; diff --git a/lib/wx/api_gen/wx_gen.erl b/lib/wx/api_gen/wx_gen.erl index 2eb9d9d33d..3ca8cd7d14 100644 --- a/lib/wx/api_gen/wx_gen.erl +++ b/lib/wx/api_gen/wx_gen.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2012. All Rights Reserved. +%% Copyright Ericsson AB 2008-2013. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -1350,7 +1350,11 @@ extract_enum3([#xmlElement{name=name,content=[#xmlText{value=Name}]}|R], Id, Acc end; extract_enum3([#xmlElement{name=initializer,content=Cs}|_],_Id,[{Name,_}|Acc]) -> - String = extract_def2(Cs), + String = case extract_def2(Cs) of + "= " ++ Str0 -> Str0; %% Doxygen 1.8.3.1 keeps the '=' sign + "=" ++ Str0 -> Str0; %% Doxygen 1.8.3.1 keeps the '=' sign + Str0 -> Str0 + end, Val0 = gen_util:tokens(String,"<& "), try case Val0 of diff --git a/lib/wx/api_gen/wxapi.conf b/lib/wx/api_gen/wxapi.conf index 81f2a389ab..21f9f1b44d 100644 --- a/lib/wx/api_gen/wxapi.conf +++ b/lib/wx/api_gen/wxapi.conf @@ -190,8 +190,9 @@ {class, wxPanel, wxWindow, [], ['wxPanel','~wxPanel',%'Create', %%'GetDefaultItem', - 'InitDialog'%, - %%'OnSysColourChanged', %'SetDefaultItem','SetFocus','SetFocusIgnoringChildren' + 'InitDialog', + %%'OnSysColourChanged', %'SetDefaultItem','SetFocus', + 'SetFocusIgnoringChildren' ]}. {class, wxScrolledWindow, wxPanel, [], @@ -504,7 +505,8 @@ [{'wxStatusBar',[{"size", skip_member}]}, '~wxStatusBar', {'Create',[{"size", skip_member}]}, - 'GetFieldRect','GetFieldsCount','GetStatusText','PopStatusText', + {'GetFieldRect', [{"rect", out}]}, + 'GetFieldsCount','GetStatusText','PopStatusText', 'PushStatusText', {'SetFieldsCount', [{"number", {def,none}}, {"widths", [{single, array}, {def, "(int *) NULL"}]}]}, @@ -1741,6 +1743,12 @@ 'Get' ]}. +{class, wxClipboardTextEvent, wxCommandEvent, + [{event, [wxEVT_COMMAND_TEXT_COPY, + wxEVT_COMMAND_TEXT_CUT, + wxEVT_COMMAND_TEXT_PASTE]}], + []}. + {class, wxSpinEvent, wxNotifyEvent, [{acc, [{m_commandInt, "GetPosition()"}]}, {event, [wxEVT_COMMAND_SPINCTRL_UPDATED, diff --git a/lib/wx/c_src/gen/wxe_events.cpp b/lib/wx/c_src/gen/wxe_events.cpp index c9cdee3160..a6a37cb37f 100644 --- a/lib/wx/c_src/gen/wxe_events.cpp +++ b/lib/wx/c_src/gen/wxe_events.cpp @@ -243,57 +243,60 @@ void initEventTable() {wxEVT_COMMAND_TREE_ITEM_MENU, 208, "command_tree_item_menu"}, {wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED, 209, "command_notebook_page_changed"}, {wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGING, 209, "command_notebook_page_changing"}, - {wxEVT_COMMAND_SPINCTRL_UPDATED, 215, "command_spinctrl_updated"}, + {wxEVT_COMMAND_TEXT_COPY, 215, "command_text_copy"}, + {wxEVT_COMMAND_TEXT_CUT, 215, "command_text_cut"}, + {wxEVT_COMMAND_TEXT_PASTE, 215, "command_text_paste"}, + {wxEVT_COMMAND_SPINCTRL_UPDATED, 216, "command_spinctrl_updated"}, {wxEVT_SCROLL_LINEUP + wxEVT_USER_FIRST, 165, "spin_up"}, {wxEVT_SCROLL_LINEDOWN + wxEVT_USER_FIRST, 165, "spin_down"}, {wxEVT_SCROLL_THUMBTRACK + wxEVT_USER_FIRST, 165, "spin"}, - {wxEVT_COMMAND_SPLITTER_SASH_POS_CHANGED, 217, "command_splitter_sash_pos_changed"}, - {wxEVT_COMMAND_SPLITTER_SASH_POS_CHANGING, 217, "command_splitter_sash_pos_changing"}, - {wxEVT_COMMAND_SPLITTER_DOUBLECLICKED, 217, "command_splitter_doubleclicked"}, - {wxEVT_COMMAND_SPLITTER_UNSPLIT, 217, "command_splitter_unsplit"}, - {wxEVT_COMMAND_HTML_LINK_CLICKED, 219, "command_html_link_clicked"}, - {wxEVT_COMMAND_AUINOTEBOOK_PAGE_CLOSE, 222, "command_auinotebook_page_close"}, - {wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGED, 222, "command_auinotebook_page_changed"}, - {wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGING, 222, "command_auinotebook_page_changing"}, - {wxEVT_COMMAND_AUINOTEBOOK_BUTTON, 222, "command_auinotebook_button"}, - {wxEVT_COMMAND_AUINOTEBOOK_BEGIN_DRAG, 222, "command_auinotebook_begin_drag"}, - {wxEVT_COMMAND_AUINOTEBOOK_END_DRAG, 222, "command_auinotebook_end_drag"}, - {wxEVT_COMMAND_AUINOTEBOOK_DRAG_MOTION, 222, "command_auinotebook_drag_motion"}, - {wxEVT_COMMAND_AUINOTEBOOK_ALLOW_DND, 222, "command_auinotebook_allow_dnd"}, + {wxEVT_COMMAND_SPLITTER_SASH_POS_CHANGED, 218, "command_splitter_sash_pos_changed"}, + {wxEVT_COMMAND_SPLITTER_SASH_POS_CHANGING, 218, "command_splitter_sash_pos_changing"}, + {wxEVT_COMMAND_SPLITTER_DOUBLECLICKED, 218, "command_splitter_doubleclicked"}, + {wxEVT_COMMAND_SPLITTER_UNSPLIT, 218, "command_splitter_unsplit"}, + {wxEVT_COMMAND_HTML_LINK_CLICKED, 220, "command_html_link_clicked"}, + {wxEVT_COMMAND_AUINOTEBOOK_PAGE_CLOSE, 223, "command_auinotebook_page_close"}, + {wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGED, 223, "command_auinotebook_page_changed"}, + {wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGING, 223, "command_auinotebook_page_changing"}, + {wxEVT_COMMAND_AUINOTEBOOK_BUTTON, 223, "command_auinotebook_button"}, + {wxEVT_COMMAND_AUINOTEBOOK_BEGIN_DRAG, 223, "command_auinotebook_begin_drag"}, + {wxEVT_COMMAND_AUINOTEBOOK_END_DRAG, 223, "command_auinotebook_end_drag"}, + {wxEVT_COMMAND_AUINOTEBOOK_DRAG_MOTION, 223, "command_auinotebook_drag_motion"}, + {wxEVT_COMMAND_AUINOTEBOOK_ALLOW_DND, 223, "command_auinotebook_allow_dnd"}, #if wxCHECK_VERSION(2,8,5) - {wxEVT_COMMAND_AUINOTEBOOK_TAB_MIDDLE_DOWN, 222, "command_auinotebook_tab_middle_down"}, + {wxEVT_COMMAND_AUINOTEBOOK_TAB_MIDDLE_DOWN, 223, "command_auinotebook_tab_middle_down"}, #endif #if wxCHECK_VERSION(2,8,5) - {wxEVT_COMMAND_AUINOTEBOOK_TAB_MIDDLE_UP, 222, "command_auinotebook_tab_middle_up"}, + {wxEVT_COMMAND_AUINOTEBOOK_TAB_MIDDLE_UP, 223, "command_auinotebook_tab_middle_up"}, #endif #if wxCHECK_VERSION(2,8,5) - {wxEVT_COMMAND_AUINOTEBOOK_TAB_RIGHT_DOWN, 222, "command_auinotebook_tab_right_down"}, + {wxEVT_COMMAND_AUINOTEBOOK_TAB_RIGHT_DOWN, 223, "command_auinotebook_tab_right_down"}, #endif #if wxCHECK_VERSION(2,8,5) - {wxEVT_COMMAND_AUINOTEBOOK_TAB_RIGHT_UP, 222, "command_auinotebook_tab_right_up"}, + {wxEVT_COMMAND_AUINOTEBOOK_TAB_RIGHT_UP, 223, "command_auinotebook_tab_right_up"}, #endif #if wxCHECK_VERSION(2,8,5) - {wxEVT_COMMAND_AUINOTEBOOK_PAGE_CLOSED, 222, "command_auinotebook_page_closed"}, + {wxEVT_COMMAND_AUINOTEBOOK_PAGE_CLOSED, 223, "command_auinotebook_page_closed"}, #endif #if wxCHECK_VERSION(2,8,5) - {wxEVT_COMMAND_AUINOTEBOOK_DRAG_DONE, 222, "command_auinotebook_drag_done"}, + {wxEVT_COMMAND_AUINOTEBOOK_DRAG_DONE, 223, "command_auinotebook_drag_done"}, #endif #if wxCHECK_VERSION(2,8,5) - {wxEVT_COMMAND_AUINOTEBOOK_BG_DCLICK, 222, "command_auinotebook_bg_dclick"}, + {wxEVT_COMMAND_AUINOTEBOOK_BG_DCLICK, 223, "command_auinotebook_bg_dclick"}, #endif - {wxEVT_AUI_PANE_BUTTON, 223, "aui_pane_button"}, - {wxEVT_AUI_PANE_CLOSE, 223, "aui_pane_close"}, - {wxEVT_AUI_PANE_MAXIMIZE, 223, "aui_pane_maximize"}, - {wxEVT_AUI_PANE_RESTORE, 223, "aui_pane_restore"}, - {wxEVT_AUI_RENDER, 223, "aui_render"}, - {wxEVT_AUI_FIND_MANAGER, 223, "aui_find_manager"}, - {wxEVT_TASKBAR_MOVE, 226, "taskbar_move"}, - {wxEVT_TASKBAR_LEFT_DOWN, 226, "taskbar_left_down"}, - {wxEVT_TASKBAR_LEFT_UP, 226, "taskbar_left_up"}, - {wxEVT_TASKBAR_RIGHT_DOWN, 226, "taskbar_right_down"}, - {wxEVT_TASKBAR_RIGHT_UP, 226, "taskbar_right_up"}, - {wxEVT_TASKBAR_LEFT_DCLICK, 226, "taskbar_left_dclick"}, - {wxEVT_TASKBAR_RIGHT_DCLICK, 226, "taskbar_right_dclick"}, + {wxEVT_AUI_PANE_BUTTON, 224, "aui_pane_button"}, + {wxEVT_AUI_PANE_CLOSE, 224, "aui_pane_close"}, + {wxEVT_AUI_PANE_MAXIMIZE, 224, "aui_pane_maximize"}, + {wxEVT_AUI_PANE_RESTORE, 224, "aui_pane_restore"}, + {wxEVT_AUI_RENDER, 224, "aui_render"}, + {wxEVT_AUI_FIND_MANAGER, 224, "aui_find_manager"}, + {wxEVT_TASKBAR_MOVE, 227, "taskbar_move"}, + {wxEVT_TASKBAR_LEFT_DOWN, 227, "taskbar_left_down"}, + {wxEVT_TASKBAR_LEFT_UP, 227, "taskbar_left_up"}, + {wxEVT_TASKBAR_RIGHT_DOWN, 227, "taskbar_right_down"}, + {wxEVT_TASKBAR_RIGHT_UP, 227, "taskbar_right_up"}, + {wxEVT_TASKBAR_LEFT_DCLICK, 227, "taskbar_left_dclick"}, + {wxEVT_TASKBAR_RIGHT_DCLICK, 227, "taskbar_right_dclick"}, {-1, 0, } }; for(int i=0; event_types[i].ev_type != -1; i++) { @@ -743,7 +746,14 @@ case 209: {// wxNotebookEvent rt.addTupleCount(2); break; } -case 215: {// wxSpinEvent +case 215: {// wxClipboardTextEvent + evClass = (char*)"wxClipboardTextEvent"; + rt.addAtom((char*)"wxClipboardText"); + rt.addAtom(Etype->eName); + rt.addTupleCount(2); + break; +} +case 216: {// wxSpinEvent wxSpinEvent * ev = (wxSpinEvent *) event; evClass = (char*)"wxSpinEvent"; rt.addAtom((char*)"wxSpin"); @@ -752,14 +762,14 @@ case 215: {// wxSpinEvent rt.addTupleCount(3); break; } -case 217: {// wxSplitterEvent +case 218: {// wxSplitterEvent evClass = (char*)"wxSplitterEvent"; rt.addAtom((char*)"wxSplitter"); rt.addAtom(Etype->eName); rt.addTupleCount(2); break; } -case 219: {// wxHtmlLinkEvent +case 220: {// wxHtmlLinkEvent wxHtmlLinkEvent * ev = (wxHtmlLinkEvent *) event; evClass = (char*)"wxHtmlLinkEvent"; rt.addAtom((char*)"wxHtmlLink"); @@ -768,7 +778,7 @@ case 219: {// wxHtmlLinkEvent rt.addTupleCount(3); break; } -case 222: {// wxAuiNotebookEvent +case 223: {// wxAuiNotebookEvent wxAuiNotebookEvent * ev = (wxAuiNotebookEvent *) event; wxAuiNotebook * GetDragSource = ev->GetDragSource(); evClass = (char*)"wxAuiNotebookEvent"; @@ -780,7 +790,7 @@ case 222: {// wxAuiNotebookEvent rt.addTupleCount(5); break; } -case 223: {// wxAuiManagerEvent +case 224: {// wxAuiManagerEvent wxAuiManagerEvent * ev = (wxAuiManagerEvent *) event; wxAuiManager * GetManager = ev->GetManager(); wxAuiPaneInfo * GetPane = ev->GetPane(); @@ -797,7 +807,7 @@ case 223: {// wxAuiManagerEvent rt.addTupleCount(8); break; } -case 226: {// wxTaskBarIconEvent +case 227: {// wxTaskBarIconEvent evClass = (char*)"wxTaskBarIconEvent"; rt.addAtom((char*)"wxTaskBarIcon"); rt.addAtom(Etype->eName); diff --git a/lib/wx/c_src/gen/wxe_funcs.cpp b/lib/wx/c_src/gen/wxe_funcs.cpp index 2d55f34346..2d8dbb242b 100644 --- a/lib/wx/c_src/gen/wxe_funcs.cpp +++ b/lib/wx/c_src/gen/wxe_funcs.cpp @@ -2218,6 +2218,12 @@ case wxPanel_InitDialog: { // wxPanel::InitDialog This->InitDialog(); break; } +case wxPanel_SetFocusIgnoringChildren: { // wxPanel::SetFocusIgnoringChildren + wxPanel *This = (wxPanel *) getPtr(bp,memenv); bp += 4; + if(!This) throw wxe_badarg(0); + This->SetFocusIgnoringChildren(); + break; +} case wxScrolledWindow_new_0: { // wxScrolledWindow::wxScrolledWindow wxScrolledWindow * Result = new EwxScrolledWindow(); newPtr((void *) Result, 0, memenv); @@ -8849,16 +8855,14 @@ case wxStatusBar_Create: { // wxStatusBar::Create break; } case wxStatusBar_GetFieldRect: { // wxStatusBar::GetFieldRect + wxRect rect; wxStatusBar *This = (wxStatusBar *) getPtr(bp,memenv); bp += 4; int * i = (int *) bp; bp += 4; - int * rectX = (int *) bp; bp += 4; - int * rectY = (int *) bp; bp += 4; - int * rectW = (int *) bp; bp += 4; - int * rectH = (int *) bp; bp += 4; - wxRect rect = wxRect(*rectX,*rectY,*rectW,*rectH); if(!This) throw wxe_badarg(0); bool Result = This->GetFieldRect(*i,rect); rt.addBool(Result); + rt.add(rect); + rt.addTupleCount(2); break; } case wxStatusBar_GetFieldsCount: { // wxStatusBar::GetFieldsCount @@ -31360,7 +31364,7 @@ case wxAuiManagerEvent_CanVeto: { // wxAuiManagerEvent::CanVeto } case wxLogNull_new: { // wxLogNull::wxLogNull wxLogNull * Result = new wxLogNull(); - newPtr((void *) Result, 224, memenv); + newPtr((void *) Result, 225, memenv); rt.addRef(getRef((void *)Result,memenv), "wxLogNull"); break; } @@ -31450,7 +31454,7 @@ void WxeApp::delete_object(void *ptr, wxeRefData *refd) { case 211: /* delete (wxFileDataObject *) ptr;These objects must be deleted by owner object */ break; case 212: /* delete (wxTextDataObject *) ptr;These objects must be deleted by owner object */ break; case 213: /* delete (wxBitmapDataObject *) ptr;These objects must be deleted by owner object */ break; - case 224: delete (wxLogNull *) ptr; break; + case 225: delete (wxLogNull *) ptr; break; default: delete (wxObject *) ptr; }} diff --git a/lib/wx/c_src/gen/wxe_macros.h b/lib/wx/c_src/gen/wxe_macros.h index c341825d8d..bd7e962fcc 100644 --- a/lib/wx/c_src/gen/wxe_macros.h +++ b/lib/wx/c_src/gen/wxe_macros.h @@ -288,3068 +288,3069 @@ #define wxPanel_new_2 334 #define wxPanel_destruct 335 #define wxPanel_InitDialog 336 -#define wxScrolledWindow_new_0 337 -#define wxScrolledWindow_new_2 338 -#define wxScrolledWindow_destruct 339 -#define wxScrolledWindow_CalcScrolledPosition_4 340 -#define wxScrolledWindow_CalcScrolledPosition_1 341 -#define wxScrolledWindow_CalcUnscrolledPosition_4 342 -#define wxScrolledWindow_CalcUnscrolledPosition_1 343 -#define wxScrolledWindow_EnableScrolling 344 -#define wxScrolledWindow_GetScrollPixelsPerUnit 345 -#define wxScrolledWindow_GetViewStart 346 -#define wxScrolledWindow_DoPrepareDC 347 -#define wxScrolledWindow_PrepareDC 348 -#define wxScrolledWindow_Scroll 349 -#define wxScrolledWindow_SetScrollbars 350 -#define wxScrolledWindow_SetScrollRate 351 -#define wxScrolledWindow_SetTargetWindow 352 -#define wxSashWindow_new_0 353 -#define wxSashWindow_new_2 354 -#define wxSashWindow_destruct 355 -#define wxSashWindow_GetSashVisible 356 -#define wxSashWindow_GetMaximumSizeX 357 -#define wxSashWindow_GetMaximumSizeY 358 -#define wxSashWindow_GetMinimumSizeX 359 -#define wxSashWindow_GetMinimumSizeY 360 -#define wxSashWindow_SetMaximumSizeX 361 -#define wxSashWindow_SetMaximumSizeY 362 -#define wxSashWindow_SetMinimumSizeX 363 -#define wxSashWindow_SetMinimumSizeY 364 -#define wxSashWindow_SetSashVisible 365 -#define wxSashLayoutWindow_new_0 366 -#define wxSashLayoutWindow_new_2 367 -#define wxSashLayoutWindow_Create 368 -#define wxSashLayoutWindow_GetAlignment 369 -#define wxSashLayoutWindow_GetOrientation 370 -#define wxSashLayoutWindow_SetAlignment 371 -#define wxSashLayoutWindow_SetDefaultSize 372 -#define wxSashLayoutWindow_SetOrientation 373 -#define wxSashLayoutWindow_destroy 374 -#define wxGrid_new_0 375 -#define wxGrid_new_3 376 -#define wxGrid_new_4 377 -#define wxGrid_destruct 378 -#define wxGrid_AppendCols 379 -#define wxGrid_AppendRows 380 -#define wxGrid_AutoSize 381 -#define wxGrid_AutoSizeColumn 382 -#define wxGrid_AutoSizeColumns 383 -#define wxGrid_AutoSizeRow 384 -#define wxGrid_AutoSizeRows 385 -#define wxGrid_BeginBatch 386 -#define wxGrid_BlockToDeviceRect 387 -#define wxGrid_CanDragColSize 388 -#define wxGrid_CanDragRowSize 389 -#define wxGrid_CanDragGridSize 390 -#define wxGrid_CanEnableCellControl 391 -#define wxGrid_CellToRect_2 392 -#define wxGrid_CellToRect_1 393 -#define wxGrid_ClearGrid 394 -#define wxGrid_ClearSelection 395 -#define wxGrid_CreateGrid 396 -#define wxGrid_DeleteCols 397 -#define wxGrid_DeleteRows 398 -#define wxGrid_DisableCellEditControl 399 -#define wxGrid_DisableDragColSize 400 -#define wxGrid_DisableDragGridSize 401 -#define wxGrid_DisableDragRowSize 402 -#define wxGrid_EnableCellEditControl 403 -#define wxGrid_EnableDragColSize 404 -#define wxGrid_EnableDragGridSize 405 -#define wxGrid_EnableDragRowSize 406 -#define wxGrid_EnableEditing 407 -#define wxGrid_EnableGridLines 408 -#define wxGrid_EndBatch 409 -#define wxGrid_Fit 410 -#define wxGrid_ForceRefresh 411 -#define wxGrid_GetBatchCount 412 -#define wxGrid_GetCellAlignment 413 -#define wxGrid_GetCellBackgroundColour 414 -#define wxGrid_GetCellEditor 415 -#define wxGrid_GetCellFont 416 -#define wxGrid_GetCellRenderer 417 -#define wxGrid_GetCellTextColour 418 -#define wxGrid_GetCellValue_2 419 -#define wxGrid_GetCellValue_1 420 -#define wxGrid_GetColLabelAlignment 421 -#define wxGrid_GetColLabelSize 422 -#define wxGrid_GetColLabelValue 423 -#define wxGrid_GetColMinimalAcceptableWidth 424 -#define wxGrid_GetDefaultCellAlignment 425 -#define wxGrid_GetDefaultCellBackgroundColour 426 -#define wxGrid_GetDefaultCellFont 427 -#define wxGrid_GetDefaultCellTextColour 428 -#define wxGrid_GetDefaultColLabelSize 429 -#define wxGrid_GetDefaultColSize 430 -#define wxGrid_GetDefaultEditor 431 -#define wxGrid_GetDefaultEditorForCell_2 432 -#define wxGrid_GetDefaultEditorForCell_1 433 -#define wxGrid_GetDefaultEditorForType 434 -#define wxGrid_GetDefaultRenderer 435 -#define wxGrid_GetDefaultRendererForCell 436 -#define wxGrid_GetDefaultRendererForType 437 -#define wxGrid_GetDefaultRowLabelSize 438 -#define wxGrid_GetDefaultRowSize 439 -#define wxGrid_GetGridCursorCol 440 -#define wxGrid_GetGridCursorRow 441 -#define wxGrid_GetGridLineColour 442 -#define wxGrid_GridLinesEnabled 443 -#define wxGrid_GetLabelBackgroundColour 444 -#define wxGrid_GetLabelFont 445 -#define wxGrid_GetLabelTextColour 446 -#define wxGrid_GetNumberCols 447 -#define wxGrid_GetNumberRows 448 -#define wxGrid_GetOrCreateCellAttr 449 -#define wxGrid_GetRowMinimalAcceptableHeight 450 -#define wxGrid_GetRowLabelAlignment 451 -#define wxGrid_GetRowLabelSize 452 -#define wxGrid_GetRowLabelValue 453 -#define wxGrid_GetRowSize 454 -#define wxGrid_GetScrollLineX 455 -#define wxGrid_GetScrollLineY 456 -#define wxGrid_GetSelectedCells 457 -#define wxGrid_GetSelectedCols 458 -#define wxGrid_GetSelectedRows 459 -#define wxGrid_GetSelectionBackground 460 -#define wxGrid_GetSelectionBlockTopLeft 461 -#define wxGrid_GetSelectionBlockBottomRight 462 -#define wxGrid_GetSelectionForeground 463 -#define wxGrid_GetViewWidth 464 -#define wxGrid_GetGridWindow 465 -#define wxGrid_GetGridRowLabelWindow 466 -#define wxGrid_GetGridColLabelWindow 467 -#define wxGrid_GetGridCornerLabelWindow 468 -#define wxGrid_HideCellEditControl 469 -#define wxGrid_InsertCols 470 -#define wxGrid_InsertRows 471 -#define wxGrid_IsCellEditControlEnabled 472 -#define wxGrid_IsCurrentCellReadOnly 473 -#define wxGrid_IsEditable 474 -#define wxGrid_IsInSelection_2 475 -#define wxGrid_IsInSelection_1 476 -#define wxGrid_IsReadOnly 477 -#define wxGrid_IsSelection 478 -#define wxGrid_IsVisible_3 479 -#define wxGrid_IsVisible_2 480 -#define wxGrid_MakeCellVisible_2 481 -#define wxGrid_MakeCellVisible_1 482 -#define wxGrid_MoveCursorDown 483 -#define wxGrid_MoveCursorLeft 484 -#define wxGrid_MoveCursorRight 485 -#define wxGrid_MoveCursorUp 486 -#define wxGrid_MoveCursorDownBlock 487 -#define wxGrid_MoveCursorLeftBlock 488 -#define wxGrid_MoveCursorRightBlock 489 -#define wxGrid_MoveCursorUpBlock 490 -#define wxGrid_MovePageDown 491 -#define wxGrid_MovePageUp 492 -#define wxGrid_RegisterDataType 493 -#define wxGrid_SaveEditControlValue 494 -#define wxGrid_SelectAll 495 -#define wxGrid_SelectBlock_5 496 -#define wxGrid_SelectBlock_3 497 -#define wxGrid_SelectCol 498 -#define wxGrid_SelectRow 499 -#define wxGrid_SetCellAlignment_4 500 -#define wxGrid_SetCellAlignment_3 501 -#define wxGrid_SetCellAlignment_1 502 -#define wxGrid_SetCellBackgroundColour_3_0 503 -#define wxGrid_SetCellBackgroundColour_1 504 -#define wxGrid_SetCellBackgroundColour_3_1 505 -#define wxGrid_SetCellEditor 506 -#define wxGrid_SetCellFont 507 -#define wxGrid_SetCellRenderer 508 -#define wxGrid_SetCellTextColour_3_0 509 -#define wxGrid_SetCellTextColour_3_1 510 -#define wxGrid_SetCellTextColour_1 511 -#define wxGrid_SetCellValue_3_0 512 -#define wxGrid_SetCellValue_2 513 -#define wxGrid_SetCellValue_3_1 514 -#define wxGrid_SetColAttr 515 -#define wxGrid_SetColFormatBool 516 -#define wxGrid_SetColFormatNumber 517 -#define wxGrid_SetColFormatFloat 518 -#define wxGrid_SetColFormatCustom 519 -#define wxGrid_SetColLabelAlignment 520 -#define wxGrid_SetColLabelSize 521 -#define wxGrid_SetColLabelValue 522 -#define wxGrid_SetColMinimalWidth 523 -#define wxGrid_SetColMinimalAcceptableWidth 524 -#define wxGrid_SetColSize 525 -#define wxGrid_SetDefaultCellAlignment 526 -#define wxGrid_SetDefaultCellBackgroundColour 527 -#define wxGrid_SetDefaultCellFont 528 -#define wxGrid_SetDefaultCellTextColour 529 -#define wxGrid_SetDefaultEditor 530 -#define wxGrid_SetDefaultRenderer 531 -#define wxGrid_SetDefaultColSize 532 -#define wxGrid_SetDefaultRowSize 533 -#define wxGrid_SetGridCursor 534 -#define wxGrid_SetGridLineColour 535 -#define wxGrid_SetLabelBackgroundColour 536 -#define wxGrid_SetLabelFont 537 -#define wxGrid_SetLabelTextColour 538 -#define wxGrid_SetMargins 539 -#define wxGrid_SetReadOnly 540 -#define wxGrid_SetRowAttr 541 -#define wxGrid_SetRowLabelAlignment 542 -#define wxGrid_SetRowLabelSize 543 -#define wxGrid_SetRowLabelValue 544 -#define wxGrid_SetRowMinimalHeight 545 -#define wxGrid_SetRowMinimalAcceptableHeight 546 -#define wxGrid_SetRowSize 547 -#define wxGrid_SetScrollLineX 548 -#define wxGrid_SetScrollLineY 549 -#define wxGrid_SetSelectionBackground 550 -#define wxGrid_SetSelectionForeground 551 -#define wxGrid_SetSelectionMode 552 -#define wxGrid_ShowCellEditControl 553 -#define wxGrid_XToCol 554 -#define wxGrid_XToEdgeOfCol 555 -#define wxGrid_YToEdgeOfRow 556 -#define wxGrid_YToRow 557 -#define wxGridCellRenderer_Draw 558 -#define wxGridCellRenderer_GetBestSize 559 -#define wxGridCellEditor_Create 560 -#define wxGridCellEditor_IsCreated 561 -#define wxGridCellEditor_SetSize 562 -#define wxGridCellEditor_Show 563 -#define wxGridCellEditor_PaintBackground 564 -#define wxGridCellEditor_BeginEdit 565 -#define wxGridCellEditor_EndEdit 566 -#define wxGridCellEditor_Reset 567 -#define wxGridCellEditor_StartingKey 568 -#define wxGridCellEditor_StartingClick 569 -#define wxGridCellEditor_HandleReturn 570 -#define wxGridCellBoolRenderer_new 571 -#define wxGridCellBoolRenderer_destroy 572 -#define wxGridCellBoolEditor_new 573 -#define wxGridCellBoolEditor_IsTrueValue 574 -#define wxGridCellBoolEditor_UseStringValues 575 -#define wxGridCellBoolEditor_destroy 576 -#define wxGridCellFloatRenderer_new 577 -#define wxGridCellFloatRenderer_GetPrecision 578 -#define wxGridCellFloatRenderer_GetWidth 579 -#define wxGridCellFloatRenderer_SetParameters 580 -#define wxGridCellFloatRenderer_SetPrecision 581 -#define wxGridCellFloatRenderer_SetWidth 582 -#define wxGridCellFloatRenderer_destroy 583 -#define wxGridCellFloatEditor_new 584 -#define wxGridCellFloatEditor_SetParameters 585 -#define wxGridCellFloatEditor_destroy 586 -#define wxGridCellStringRenderer_new 587 -#define wxGridCellStringRenderer_destroy 588 -#define wxGridCellTextEditor_new 589 -#define wxGridCellTextEditor_SetParameters 590 -#define wxGridCellTextEditor_destroy 591 -#define wxGridCellChoiceEditor_new 593 -#define wxGridCellChoiceEditor_SetParameters 594 -#define wxGridCellChoiceEditor_destroy 595 -#define wxGridCellNumberRenderer_new 596 -#define wxGridCellNumberRenderer_destroy 597 -#define wxGridCellNumberEditor_new 598 -#define wxGridCellNumberEditor_GetValue 599 -#define wxGridCellNumberEditor_SetParameters 600 -#define wxGridCellNumberEditor_destroy 601 -#define wxGridCellAttr_SetTextColour 602 -#define wxGridCellAttr_SetBackgroundColour 603 -#define wxGridCellAttr_SetFont 604 -#define wxGridCellAttr_SetAlignment 605 -#define wxGridCellAttr_SetReadOnly 606 -#define wxGridCellAttr_SetRenderer 607 -#define wxGridCellAttr_SetEditor 608 -#define wxGridCellAttr_HasTextColour 609 -#define wxGridCellAttr_HasBackgroundColour 610 -#define wxGridCellAttr_HasFont 611 -#define wxGridCellAttr_HasAlignment 612 -#define wxGridCellAttr_HasRenderer 613 -#define wxGridCellAttr_HasEditor 614 -#define wxGridCellAttr_GetTextColour 615 -#define wxGridCellAttr_GetBackgroundColour 616 -#define wxGridCellAttr_GetFont 617 -#define wxGridCellAttr_GetAlignment 618 -#define wxGridCellAttr_GetRenderer 619 -#define wxGridCellAttr_GetEditor 620 -#define wxGridCellAttr_IsReadOnly 621 -#define wxGridCellAttr_SetDefAttr 622 -#define wxDC_Blit 623 -#define wxDC_CalcBoundingBox 624 -#define wxDC_Clear 625 -#define wxDC_ComputeScaleAndOrigin 626 -#define wxDC_CrossHair 627 -#define wxDC_DestroyClippingRegion 628 -#define wxDC_DeviceToLogicalX 629 -#define wxDC_DeviceToLogicalXRel 630 -#define wxDC_DeviceToLogicalY 631 -#define wxDC_DeviceToLogicalYRel 632 -#define wxDC_DrawArc 633 -#define wxDC_DrawBitmap 634 -#define wxDC_DrawCheckMark 635 -#define wxDC_DrawCircle 636 -#define wxDC_DrawEllipse_2 638 -#define wxDC_DrawEllipse_1 639 -#define wxDC_DrawEllipticArc 640 -#define wxDC_DrawIcon 641 -#define wxDC_DrawLabel 642 -#define wxDC_DrawLine 643 -#define wxDC_DrawLines 644 -#define wxDC_DrawPolygon 646 -#define wxDC_DrawPoint 648 -#define wxDC_DrawRectangle_2 650 -#define wxDC_DrawRectangle_1 651 -#define wxDC_DrawRotatedText 652 -#define wxDC_DrawRoundedRectangle_3 654 -#define wxDC_DrawRoundedRectangle_2 655 -#define wxDC_DrawText 656 -#define wxDC_EndDoc 657 -#define wxDC_EndPage 658 -#define wxDC_FloodFill 659 -#define wxDC_GetBackground 660 -#define wxDC_GetBackgroundMode 661 -#define wxDC_GetBrush 662 -#define wxDC_GetCharHeight 663 -#define wxDC_GetCharWidth 664 -#define wxDC_GetClippingBox 665 -#define wxDC_GetFont 667 -#define wxDC_GetLayoutDirection 668 -#define wxDC_GetLogicalFunction 669 -#define wxDC_GetMapMode 670 -#define wxDC_GetMultiLineTextExtent_4 671 -#define wxDC_GetMultiLineTextExtent_1 672 -#define wxDC_GetPartialTextExtents 673 -#define wxDC_GetPen 674 -#define wxDC_GetPixel 675 -#define wxDC_GetPPI 676 -#define wxDC_GetSize 678 -#define wxDC_GetSizeMM 680 -#define wxDC_GetTextBackground 681 -#define wxDC_GetTextExtent_4 682 -#define wxDC_GetTextExtent_1 683 -#define wxDC_GetTextForeground 685 -#define wxDC_GetUserScale 686 -#define wxDC_GradientFillConcentric_3 687 -#define wxDC_GradientFillConcentric_4 688 -#define wxDC_GradientFillLinear 689 -#define wxDC_LogicalToDeviceX 690 -#define wxDC_LogicalToDeviceXRel 691 -#define wxDC_LogicalToDeviceY 692 -#define wxDC_LogicalToDeviceYRel 693 -#define wxDC_MaxX 694 -#define wxDC_MaxY 695 -#define wxDC_MinX 696 -#define wxDC_MinY 697 -#define wxDC_IsOk 698 -#define wxDC_ResetBoundingBox 699 -#define wxDC_SetAxisOrientation 700 -#define wxDC_SetBackground 701 -#define wxDC_SetBackgroundMode 702 -#define wxDC_SetBrush 703 -#define wxDC_SetClippingRegion_2 705 -#define wxDC_SetClippingRegion_1_1 706 -#define wxDC_SetClippingRegion_1_0 707 -#define wxDC_SetDeviceOrigin 708 -#define wxDC_SetFont 709 -#define wxDC_SetLayoutDirection 710 -#define wxDC_SetLogicalFunction 711 -#define wxDC_SetMapMode 712 -#define wxDC_SetPalette 713 -#define wxDC_SetPen 714 -#define wxDC_SetTextBackground 715 -#define wxDC_SetTextForeground 716 -#define wxDC_SetUserScale 717 -#define wxDC_StartDoc 718 -#define wxDC_StartPage 719 -#define wxMirrorDC_new 720 -#define wxMirrorDC_destroy 721 -#define wxScreenDC_new 722 -#define wxScreenDC_destruct 723 -#define wxPostScriptDC_new_0 724 -#define wxPostScriptDC_new_1 725 -#define wxPostScriptDC_destruct 726 -#define wxPostScriptDC_SetResolution 727 -#define wxPostScriptDC_GetResolution 728 -#define wxWindowDC_new_0 729 -#define wxWindowDC_new_1 730 -#define wxWindowDC_destruct 731 -#define wxClientDC_new_0 732 -#define wxClientDC_new_1 733 -#define wxClientDC_destroy 734 -#define wxPaintDC_new_0 735 -#define wxPaintDC_new_1 736 -#define wxPaintDC_destroy 737 -#define wxMemoryDC_new_1_0 739 -#define wxMemoryDC_new_1_1 740 -#define wxMemoryDC_new_0 741 -#define wxMemoryDC_destruct 743 -#define wxMemoryDC_SelectObject 744 -#define wxMemoryDC_SelectObjectAsSource 745 -#define wxBufferedDC_new_0 746 -#define wxBufferedDC_new_2 747 -#define wxBufferedDC_new_3 748 -#define wxBufferedDC_destruct 749 -#define wxBufferedDC_Init_2 750 -#define wxBufferedDC_Init_3 751 -#define wxBufferedPaintDC_new_3 752 -#define wxBufferedPaintDC_new_2 753 -#define wxBufferedPaintDC_destruct 754 -#define wxGraphicsObject_destruct 755 -#define wxGraphicsObject_GetRenderer 756 -#define wxGraphicsObject_IsNull 757 -#define wxGraphicsContext_destruct 758 -#define wxGraphicsContext_Create_1_1 759 -#define wxGraphicsContext_Create_1_0 760 -#define wxGraphicsContext_Create_0 761 -#define wxGraphicsContext_CreatePen 762 -#define wxGraphicsContext_CreateBrush 763 -#define wxGraphicsContext_CreateRadialGradientBrush 764 -#define wxGraphicsContext_CreateLinearGradientBrush 765 -#define wxGraphicsContext_CreateFont 766 -#define wxGraphicsContext_CreateMatrix 767 -#define wxGraphicsContext_CreatePath 768 -#define wxGraphicsContext_Clip_1 769 -#define wxGraphicsContext_Clip_4 770 -#define wxGraphicsContext_ResetClip 771 -#define wxGraphicsContext_DrawBitmap 772 -#define wxGraphicsContext_DrawEllipse 773 -#define wxGraphicsContext_DrawIcon 774 -#define wxGraphicsContext_DrawLines 775 -#define wxGraphicsContext_DrawPath 776 -#define wxGraphicsContext_DrawRectangle 777 -#define wxGraphicsContext_DrawRoundedRectangle 778 -#define wxGraphicsContext_DrawText_3 779 -#define wxGraphicsContext_DrawText_4_0 780 -#define wxGraphicsContext_DrawText_4_1 781 -#define wxGraphicsContext_DrawText_5 782 -#define wxGraphicsContext_FillPath 783 -#define wxGraphicsContext_StrokePath 784 -#define wxGraphicsContext_GetPartialTextExtents 785 -#define wxGraphicsContext_GetTextExtent 786 -#define wxGraphicsContext_Rotate 787 -#define wxGraphicsContext_Scale 788 -#define wxGraphicsContext_Translate 789 -#define wxGraphicsContext_GetTransform 790 -#define wxGraphicsContext_SetTransform 791 -#define wxGraphicsContext_ConcatTransform 792 -#define wxGraphicsContext_SetBrush_1_1 793 -#define wxGraphicsContext_SetBrush_1_0 794 -#define wxGraphicsContext_SetFont_1 795 -#define wxGraphicsContext_SetFont_2 796 -#define wxGraphicsContext_SetPen_1_0 797 -#define wxGraphicsContext_SetPen_1_1 798 -#define wxGraphicsContext_StrokeLine 799 -#define wxGraphicsContext_StrokeLines 800 -#define wxGraphicsMatrix_Concat 802 -#define wxGraphicsMatrix_Get 804 -#define wxGraphicsMatrix_Invert 805 -#define wxGraphicsMatrix_IsEqual 806 -#define wxGraphicsMatrix_IsIdentity 808 -#define wxGraphicsMatrix_Rotate 809 -#define wxGraphicsMatrix_Scale 810 -#define wxGraphicsMatrix_Translate 811 -#define wxGraphicsMatrix_Set 812 -#define wxGraphicsMatrix_TransformPoint 813 -#define wxGraphicsMatrix_TransformDistance 814 -#define wxGraphicsPath_MoveToPoint_2 815 -#define wxGraphicsPath_MoveToPoint_1 816 -#define wxGraphicsPath_AddArc_6 817 -#define wxGraphicsPath_AddArc_5 818 -#define wxGraphicsPath_AddArcToPoint 819 -#define wxGraphicsPath_AddCircle 820 -#define wxGraphicsPath_AddCurveToPoint_6 821 -#define wxGraphicsPath_AddCurveToPoint_3 822 -#define wxGraphicsPath_AddEllipse 823 -#define wxGraphicsPath_AddLineToPoint_2 824 -#define wxGraphicsPath_AddLineToPoint_1 825 -#define wxGraphicsPath_AddPath 826 -#define wxGraphicsPath_AddQuadCurveToPoint 827 -#define wxGraphicsPath_AddRectangle 828 -#define wxGraphicsPath_AddRoundedRectangle 829 -#define wxGraphicsPath_CloseSubpath 830 -#define wxGraphicsPath_Contains_3 831 -#define wxGraphicsPath_Contains_2 832 -#define wxGraphicsPath_GetBox 834 -#define wxGraphicsPath_GetCurrentPoint 836 -#define wxGraphicsPath_Transform 837 -#define wxGraphicsRenderer_GetDefaultRenderer 838 -#define wxGraphicsRenderer_CreateContext_1_1 839 -#define wxGraphicsRenderer_CreateContext_1_0 840 -#define wxGraphicsRenderer_CreatePen 841 -#define wxGraphicsRenderer_CreateBrush 842 -#define wxGraphicsRenderer_CreateLinearGradientBrush 843 -#define wxGraphicsRenderer_CreateRadialGradientBrush 844 -#define wxGraphicsRenderer_CreateFont 845 -#define wxGraphicsRenderer_CreateMatrix 846 -#define wxGraphicsRenderer_CreatePath 847 -#define wxMenuBar_new_1 849 -#define wxMenuBar_new_0 851 -#define wxMenuBar_destruct 853 -#define wxMenuBar_Append 854 -#define wxMenuBar_Check 855 -#define wxMenuBar_Enable_2 856 -#define wxMenuBar_Enable_1 857 -#define wxMenuBar_EnableTop 858 -#define wxMenuBar_FindMenu 859 -#define wxMenuBar_FindMenuItem 860 -#define wxMenuBar_FindItem 861 -#define wxMenuBar_GetHelpString 862 -#define wxMenuBar_GetLabel_1 863 -#define wxMenuBar_GetLabel_0 864 -#define wxMenuBar_GetLabelTop 865 -#define wxMenuBar_GetMenu 866 -#define wxMenuBar_GetMenuCount 867 -#define wxMenuBar_Insert 868 -#define wxMenuBar_IsChecked 869 -#define wxMenuBar_IsEnabled_1 870 -#define wxMenuBar_IsEnabled_0 871 -#define wxMenuBar_Remove 872 -#define wxMenuBar_Replace 873 -#define wxMenuBar_SetHelpString 874 -#define wxMenuBar_SetLabel_2 875 -#define wxMenuBar_SetLabel_1 876 -#define wxMenuBar_SetLabelTop 877 -#define wxControl_GetLabel 878 -#define wxControl_SetLabel 879 -#define wxControlWithItems_Append_1 880 -#define wxControlWithItems_Append_2 881 -#define wxControlWithItems_appendStrings_1 882 -#define wxControlWithItems_Clear 883 -#define wxControlWithItems_Delete 884 -#define wxControlWithItems_FindString 885 -#define wxControlWithItems_getClientData 886 -#define wxControlWithItems_setClientData 887 -#define wxControlWithItems_GetCount 888 -#define wxControlWithItems_GetSelection 889 -#define wxControlWithItems_GetString 890 -#define wxControlWithItems_GetStringSelection 891 -#define wxControlWithItems_Insert_2 892 -#define wxControlWithItems_Insert_3 893 -#define wxControlWithItems_IsEmpty 894 -#define wxControlWithItems_Select 895 -#define wxControlWithItems_SetSelection 896 -#define wxControlWithItems_SetString 897 -#define wxControlWithItems_SetStringSelection 898 -#define wxMenu_new_2 901 -#define wxMenu_new_1 902 -#define wxMenu_destruct 904 -#define wxMenu_Append_3 905 -#define wxMenu_Append_1 906 -#define wxMenu_Append_4_0 907 -#define wxMenu_Append_4_1 908 -#define wxMenu_AppendCheckItem 909 -#define wxMenu_AppendRadioItem 910 -#define wxMenu_AppendSeparator 911 -#define wxMenu_Break 912 -#define wxMenu_Check 913 -#define wxMenu_Delete_1_0 914 -#define wxMenu_Delete_1_1 915 -#define wxMenu_Destroy_1_0 916 -#define wxMenu_Destroy_1_1 917 -#define wxMenu_Enable 918 -#define wxMenu_FindItem_1 919 -#define wxMenu_FindItem_2 920 -#define wxMenu_FindItemByPosition 921 -#define wxMenu_GetHelpString 922 -#define wxMenu_GetLabel 923 -#define wxMenu_GetMenuItemCount 924 -#define wxMenu_GetMenuItems 925 -#define wxMenu_GetTitle 927 -#define wxMenu_Insert_2 928 -#define wxMenu_Insert_3 929 -#define wxMenu_Insert_5_1 930 -#define wxMenu_Insert_5_0 931 -#define wxMenu_InsertCheckItem 932 -#define wxMenu_InsertRadioItem 933 -#define wxMenu_InsertSeparator 934 -#define wxMenu_IsChecked 935 -#define wxMenu_IsEnabled 936 -#define wxMenu_Prepend_1 937 -#define wxMenu_Prepend_2 938 -#define wxMenu_Prepend_4_1 939 -#define wxMenu_Prepend_4_0 940 -#define wxMenu_PrependCheckItem 941 -#define wxMenu_PrependRadioItem 942 -#define wxMenu_PrependSeparator 943 -#define wxMenu_Remove_1_0 944 -#define wxMenu_Remove_1_1 945 -#define wxMenu_SetHelpString 946 -#define wxMenu_SetLabel 947 -#define wxMenu_SetTitle 948 -#define wxMenuItem_new 949 -#define wxMenuItem_destruct 951 -#define wxMenuItem_Check 952 -#define wxMenuItem_Enable 953 -#define wxMenuItem_GetBitmap 954 -#define wxMenuItem_GetHelp 955 -#define wxMenuItem_GetId 956 -#define wxMenuItem_GetKind 957 -#define wxMenuItem_GetLabel 958 -#define wxMenuItem_GetLabelFromText 959 -#define wxMenuItem_GetMenu 960 -#define wxMenuItem_GetText 961 -#define wxMenuItem_GetSubMenu 962 -#define wxMenuItem_IsCheckable 963 -#define wxMenuItem_IsChecked 964 -#define wxMenuItem_IsEnabled 965 -#define wxMenuItem_IsSeparator 966 -#define wxMenuItem_IsSubMenu 967 -#define wxMenuItem_SetBitmap 968 -#define wxMenuItem_SetHelp 969 -#define wxMenuItem_SetMenu 970 -#define wxMenuItem_SetSubMenu 971 -#define wxMenuItem_SetText 972 -#define wxToolBar_AddControl 973 -#define wxToolBar_AddSeparator 974 -#define wxToolBar_AddTool_5 975 -#define wxToolBar_AddTool_4_0 976 -#define wxToolBar_AddTool_1 977 -#define wxToolBar_AddTool_4_1 978 -#define wxToolBar_AddTool_3 979 -#define wxToolBar_AddTool_6 980 -#define wxToolBar_AddCheckTool 981 -#define wxToolBar_AddRadioTool 982 -#define wxToolBar_DeleteTool 983 -#define wxToolBar_DeleteToolByPos 984 -#define wxToolBar_EnableTool 985 -#define wxToolBar_FindById 986 -#define wxToolBar_FindControl 987 -#define wxToolBar_FindToolForPosition 988 -#define wxToolBar_GetToolSize 989 -#define wxToolBar_GetToolBitmapSize 990 -#define wxToolBar_GetMargins 991 -#define wxToolBar_GetToolEnabled 992 -#define wxToolBar_GetToolLongHelp 993 -#define wxToolBar_GetToolPacking 994 -#define wxToolBar_GetToolPos 995 -#define wxToolBar_GetToolSeparation 996 -#define wxToolBar_GetToolShortHelp 997 -#define wxToolBar_GetToolState 998 -#define wxToolBar_InsertControl 999 -#define wxToolBar_InsertSeparator 1000 -#define wxToolBar_InsertTool_5 1001 -#define wxToolBar_InsertTool_2 1002 -#define wxToolBar_InsertTool_4 1003 -#define wxToolBar_Realize 1004 -#define wxToolBar_RemoveTool 1005 -#define wxToolBar_SetMargins 1006 -#define wxToolBar_SetToolBitmapSize 1007 -#define wxToolBar_SetToolLongHelp 1008 -#define wxToolBar_SetToolPacking 1009 -#define wxToolBar_SetToolShortHelp 1010 -#define wxToolBar_SetToolSeparation 1011 -#define wxToolBar_ToggleTool 1012 -#define wxStatusBar_new_0 1014 -#define wxStatusBar_new_2 1015 -#define wxStatusBar_destruct 1017 -#define wxStatusBar_Create 1018 -#define wxStatusBar_GetFieldRect 1019 -#define wxStatusBar_GetFieldsCount 1020 -#define wxStatusBar_GetStatusText 1021 -#define wxStatusBar_PopStatusText 1022 -#define wxStatusBar_PushStatusText 1023 -#define wxStatusBar_SetFieldsCount 1024 -#define wxStatusBar_SetMinHeight 1025 -#define wxStatusBar_SetStatusText 1026 -#define wxStatusBar_SetStatusWidths 1027 -#define wxStatusBar_SetStatusStyles 1028 -#define wxBitmap_new_0 1029 -#define wxBitmap_new_3 1030 -#define wxBitmap_new_4 1031 -#define wxBitmap_new_2_0 1032 -#define wxBitmap_new_2_1 1033 -#define wxBitmap_destruct 1034 -#define wxBitmap_ConvertToImage 1035 -#define wxBitmap_CopyFromIcon 1036 -#define wxBitmap_Create 1037 -#define wxBitmap_GetDepth 1038 -#define wxBitmap_GetHeight 1039 -#define wxBitmap_GetPalette 1040 -#define wxBitmap_GetMask 1041 -#define wxBitmap_GetWidth 1042 -#define wxBitmap_GetSubBitmap 1043 -#define wxBitmap_LoadFile 1044 -#define wxBitmap_Ok 1045 -#define wxBitmap_SaveFile 1046 -#define wxBitmap_SetDepth 1047 -#define wxBitmap_SetHeight 1048 -#define wxBitmap_SetMask 1049 -#define wxBitmap_SetPalette 1050 -#define wxBitmap_SetWidth 1051 -#define wxIcon_new_0 1052 -#define wxIcon_new_2 1053 -#define wxIcon_new_1 1054 -#define wxIcon_CopyFromBitmap 1055 -#define wxIcon_destroy 1056 -#define wxIconBundle_new_0 1057 -#define wxIconBundle_new_2 1058 -#define wxIconBundle_new_1_0 1059 -#define wxIconBundle_new_1_1 1060 -#define wxIconBundle_destruct 1061 -#define wxIconBundle_AddIcon_2 1062 -#define wxIconBundle_AddIcon_1 1063 -#define wxIconBundle_GetIcon_1_1 1064 -#define wxIconBundle_GetIcon_1_0 1065 -#define wxCursor_new_0 1066 -#define wxCursor_new_1_0 1067 -#define wxCursor_new_1_1 1068 -#define wxCursor_new_4 1069 -#define wxCursor_destruct 1070 -#define wxCursor_Ok 1071 -#define wxMask_new_0 1072 -#define wxMask_new_2_1 1073 -#define wxMask_new_2_0 1074 -#define wxMask_new_1 1075 -#define wxMask_destruct 1076 -#define wxMask_Create_2_1 1077 -#define wxMask_Create_2_0 1078 -#define wxMask_Create_1 1079 -#define wxImage_new_0 1080 -#define wxImage_new_3_0 1081 -#define wxImage_new_4 1082 -#define wxImage_new_5 1083 -#define wxImage_new_2 1084 -#define wxImage_new_3_1 1085 -#define wxImage_Blur 1086 -#define wxImage_BlurHorizontal 1087 -#define wxImage_BlurVertical 1088 -#define wxImage_ConvertAlphaToMask 1089 -#define wxImage_ConvertToGreyscale 1090 -#define wxImage_ConvertToMono 1091 -#define wxImage_Copy 1092 -#define wxImage_Create_3 1093 -#define wxImage_Create_4 1094 -#define wxImage_Create_5 1095 -#define wxImage_Destroy 1096 -#define wxImage_FindFirstUnusedColour 1097 -#define wxImage_GetImageExtWildcard 1098 -#define wxImage_GetAlpha_2 1099 -#define wxImage_GetAlpha_0 1100 -#define wxImage_GetBlue 1101 -#define wxImage_GetData 1102 -#define wxImage_GetGreen 1103 -#define wxImage_GetImageCount 1104 -#define wxImage_GetHeight 1105 -#define wxImage_GetMaskBlue 1106 -#define wxImage_GetMaskGreen 1107 -#define wxImage_GetMaskRed 1108 -#define wxImage_GetOrFindMaskColour 1109 -#define wxImage_GetPalette 1110 -#define wxImage_GetRed 1111 -#define wxImage_GetSubImage 1112 -#define wxImage_GetWidth 1113 -#define wxImage_HasAlpha 1114 -#define wxImage_HasMask 1115 -#define wxImage_GetOption 1116 -#define wxImage_GetOptionInt 1117 -#define wxImage_HasOption 1118 -#define wxImage_InitAlpha 1119 -#define wxImage_InitStandardHandlers 1120 -#define wxImage_IsTransparent 1121 -#define wxImage_LoadFile_2 1122 -#define wxImage_LoadFile_3 1123 -#define wxImage_Ok 1124 -#define wxImage_RemoveHandler 1125 -#define wxImage_Mirror 1126 -#define wxImage_Replace 1127 -#define wxImage_Rescale 1128 -#define wxImage_Resize 1129 -#define wxImage_Rotate 1130 -#define wxImage_RotateHue 1131 -#define wxImage_Rotate90 1132 -#define wxImage_SaveFile_1 1133 -#define wxImage_SaveFile_2_0 1134 -#define wxImage_SaveFile_2_1 1135 -#define wxImage_Scale 1136 -#define wxImage_Size 1137 -#define wxImage_SetAlpha_3 1138 -#define wxImage_SetAlpha_2 1139 -#define wxImage_SetData_2 1140 -#define wxImage_SetData_4 1141 -#define wxImage_SetMask 1142 -#define wxImage_SetMaskColour 1143 -#define wxImage_SetMaskFromImage 1144 -#define wxImage_SetOption_2_1 1145 -#define wxImage_SetOption_2_0 1146 -#define wxImage_SetPalette 1147 -#define wxImage_SetRGB_5 1148 -#define wxImage_SetRGB_4 1149 -#define wxImage_destroy 1150 -#define wxBrush_new_0 1151 -#define wxBrush_new_2 1152 -#define wxBrush_new_1 1153 -#define wxBrush_destruct 1155 -#define wxBrush_GetColour 1156 -#define wxBrush_GetStipple 1157 -#define wxBrush_GetStyle 1158 -#define wxBrush_IsHatch 1159 -#define wxBrush_IsOk 1160 -#define wxBrush_SetColour_1 1161 -#define wxBrush_SetColour_3 1162 -#define wxBrush_SetStipple 1163 -#define wxBrush_SetStyle 1164 -#define wxPen_new_0 1165 -#define wxPen_new_2 1166 -#define wxPen_destruct 1167 -#define wxPen_GetCap 1168 -#define wxPen_GetColour 1169 -#define wxPen_GetJoin 1170 -#define wxPen_GetStyle 1171 -#define wxPen_GetWidth 1172 -#define wxPen_IsOk 1173 -#define wxPen_SetCap 1174 -#define wxPen_SetColour_1 1175 -#define wxPen_SetColour_3 1176 -#define wxPen_SetJoin 1177 -#define wxPen_SetStyle 1178 -#define wxPen_SetWidth 1179 -#define wxRegion_new_0 1180 -#define wxRegion_new_4 1181 -#define wxRegion_new_2 1182 -#define wxRegion_new_1_1 1183 -#define wxRegion_new_1_0 1185 -#define wxRegion_destruct 1187 -#define wxRegion_Clear 1188 -#define wxRegion_Contains_2 1189 -#define wxRegion_Contains_1_0 1190 -#define wxRegion_Contains_4 1191 -#define wxRegion_Contains_1_1 1192 -#define wxRegion_ConvertToBitmap 1193 -#define wxRegion_GetBox 1194 -#define wxRegion_Intersect_4 1195 -#define wxRegion_Intersect_1_1 1196 -#define wxRegion_Intersect_1_0 1197 -#define wxRegion_IsEmpty 1198 -#define wxRegion_Subtract_4 1199 -#define wxRegion_Subtract_1_1 1200 -#define wxRegion_Subtract_1_0 1201 -#define wxRegion_Offset_2 1202 -#define wxRegion_Offset_1 1203 -#define wxRegion_Union_4 1204 -#define wxRegion_Union_1_2 1205 -#define wxRegion_Union_1_1 1206 -#define wxRegion_Union_1_0 1207 -#define wxRegion_Union_3 1208 -#define wxRegion_Xor_4 1209 -#define wxRegion_Xor_1_1 1210 -#define wxRegion_Xor_1_0 1211 -#define wxAcceleratorTable_new_0 1212 -#define wxAcceleratorTable_new_2 1213 -#define wxAcceleratorTable_destruct 1214 -#define wxAcceleratorTable_Ok 1215 -#define wxAcceleratorEntry_new_1_0 1216 -#define wxAcceleratorEntry_new_1_1 1217 -#define wxAcceleratorEntry_GetCommand 1218 -#define wxAcceleratorEntry_GetFlags 1219 -#define wxAcceleratorEntry_GetKeyCode 1220 -#define wxAcceleratorEntry_Set 1221 -#define wxAcceleratorEntry_destroy 1222 -#define wxCaret_new_3 1227 -#define wxCaret_new_2 1228 -#define wxCaret_destruct 1230 -#define wxCaret_Create_3 1231 -#define wxCaret_Create_2 1232 -#define wxCaret_GetBlinkTime 1233 -#define wxCaret_GetPosition 1235 -#define wxCaret_GetSize 1237 -#define wxCaret_GetWindow 1238 -#define wxCaret_Hide 1239 -#define wxCaret_IsOk 1240 -#define wxCaret_IsVisible 1241 -#define wxCaret_Move_2 1242 -#define wxCaret_Move_1 1243 -#define wxCaret_SetBlinkTime 1244 -#define wxCaret_SetSize_2 1245 -#define wxCaret_SetSize_1 1246 -#define wxCaret_Show 1247 -#define wxSizer_Add_2_1 1248 -#define wxSizer_Add_2_0 1249 -#define wxSizer_Add_3 1250 -#define wxSizer_Add_2_3 1251 -#define wxSizer_Add_2_2 1252 -#define wxSizer_AddSpacer 1253 -#define wxSizer_AddStretchSpacer 1254 -#define wxSizer_CalcMin 1255 -#define wxSizer_Clear 1256 -#define wxSizer_Detach_1_2 1257 -#define wxSizer_Detach_1_1 1258 -#define wxSizer_Detach_1_0 1259 -#define wxSizer_Fit 1260 -#define wxSizer_FitInside 1261 -#define wxSizer_GetChildren 1262 -#define wxSizer_GetItem_2_1 1263 -#define wxSizer_GetItem_2_0 1264 -#define wxSizer_GetItem_1 1265 -#define wxSizer_GetSize 1266 -#define wxSizer_GetPosition 1267 -#define wxSizer_GetMinSize 1268 -#define wxSizer_Hide_2_0 1269 -#define wxSizer_Hide_2_1 1270 -#define wxSizer_Hide_1 1271 -#define wxSizer_Insert_3_1 1272 -#define wxSizer_Insert_3_0 1273 -#define wxSizer_Insert_4 1274 -#define wxSizer_Insert_3_3 1275 -#define wxSizer_Insert_3_2 1276 -#define wxSizer_Insert_2 1277 -#define wxSizer_InsertSpacer 1278 -#define wxSizer_InsertStretchSpacer 1279 -#define wxSizer_IsShown_1_2 1280 -#define wxSizer_IsShown_1_1 1281 -#define wxSizer_IsShown_1_0 1282 -#define wxSizer_Layout 1283 -#define wxSizer_Prepend_2_1 1284 -#define wxSizer_Prepend_2_0 1285 -#define wxSizer_Prepend_3 1286 -#define wxSizer_Prepend_2_3 1287 -#define wxSizer_Prepend_2_2 1288 -#define wxSizer_Prepend_1 1289 -#define wxSizer_PrependSpacer 1290 -#define wxSizer_PrependStretchSpacer 1291 -#define wxSizer_RecalcSizes 1292 -#define wxSizer_Remove_1_1 1293 -#define wxSizer_Remove_1_0 1294 -#define wxSizer_Replace_3_1 1295 -#define wxSizer_Replace_3_0 1296 -#define wxSizer_Replace_2 1297 -#define wxSizer_SetDimension 1298 -#define wxSizer_SetMinSize_2 1299 -#define wxSizer_SetMinSize_1 1300 -#define wxSizer_SetItemMinSize_3_2 1301 -#define wxSizer_SetItemMinSize_2_2 1302 -#define wxSizer_SetItemMinSize_3_1 1303 -#define wxSizer_SetItemMinSize_2_1 1304 -#define wxSizer_SetItemMinSize_3_0 1305 -#define wxSizer_SetItemMinSize_2_0 1306 -#define wxSizer_SetSizeHints 1307 -#define wxSizer_SetVirtualSizeHints 1308 -#define wxSizer_Show_2_2 1309 -#define wxSizer_Show_2_1 1310 -#define wxSizer_Show_2_0 1311 -#define wxSizer_Show_1 1312 -#define wxSizerFlags_new 1313 -#define wxSizerFlags_Align 1314 -#define wxSizerFlags_Border_2 1315 -#define wxSizerFlags_Border_1 1316 -#define wxSizerFlags_Center 1317 -#define wxSizerFlags_Centre 1318 -#define wxSizerFlags_Expand 1319 -#define wxSizerFlags_Left 1320 -#define wxSizerFlags_Proportion 1321 -#define wxSizerFlags_Right 1322 -#define wxSizerFlags_destroy 1323 -#define wxSizerItem_new_5_1 1324 -#define wxSizerItem_new_2_1 1325 -#define wxSizerItem_new_5_0 1326 -#define wxSizerItem_new_2_0 1327 -#define wxSizerItem_new_6 1328 -#define wxSizerItem_new_3 1329 -#define wxSizerItem_new_0 1330 -#define wxSizerItem_destruct 1331 -#define wxSizerItem_CalcMin 1332 -#define wxSizerItem_DeleteWindows 1333 -#define wxSizerItem_DetachSizer 1334 -#define wxSizerItem_GetBorder 1335 -#define wxSizerItem_GetFlag 1336 -#define wxSizerItem_GetMinSize 1337 -#define wxSizerItem_GetPosition 1338 -#define wxSizerItem_GetProportion 1339 -#define wxSizerItem_GetRatio 1340 -#define wxSizerItem_GetRect 1341 -#define wxSizerItem_GetSize 1342 -#define wxSizerItem_GetSizer 1343 -#define wxSizerItem_GetSpacer 1344 -#define wxSizerItem_GetUserData 1345 -#define wxSizerItem_GetWindow 1346 -#define wxSizerItem_IsSizer 1347 -#define wxSizerItem_IsShown 1348 -#define wxSizerItem_IsSpacer 1349 -#define wxSizerItem_IsWindow 1350 -#define wxSizerItem_SetBorder 1351 -#define wxSizerItem_SetDimension 1352 -#define wxSizerItem_SetFlag 1353 -#define wxSizerItem_SetInitSize 1354 -#define wxSizerItem_SetMinSize_1 1355 -#define wxSizerItem_SetMinSize_2 1356 -#define wxSizerItem_SetProportion 1357 -#define wxSizerItem_SetRatio_2 1358 -#define wxSizerItem_SetRatio_1_1 1359 -#define wxSizerItem_SetRatio_1_0 1360 -#define wxSizerItem_SetSizer 1361 -#define wxSizerItem_SetSpacer_1 1362 -#define wxSizerItem_SetSpacer_2 1363 -#define wxSizerItem_SetWindow 1364 -#define wxSizerItem_Show 1365 -#define wxBoxSizer_new 1366 -#define wxBoxSizer_GetOrientation 1367 -#define wxBoxSizer_destroy 1368 -#define wxStaticBoxSizer_new_2 1369 -#define wxStaticBoxSizer_new_3 1370 -#define wxStaticBoxSizer_GetStaticBox 1371 -#define wxStaticBoxSizer_destroy 1372 -#define wxGridSizer_new_4 1373 -#define wxGridSizer_new_2 1374 -#define wxGridSizer_GetCols 1375 -#define wxGridSizer_GetHGap 1376 -#define wxGridSizer_GetRows 1377 -#define wxGridSizer_GetVGap 1378 -#define wxGridSizer_SetCols 1379 -#define wxGridSizer_SetHGap 1380 -#define wxGridSizer_SetRows 1381 -#define wxGridSizer_SetVGap 1382 -#define wxGridSizer_destroy 1383 -#define wxFlexGridSizer_new_4 1384 -#define wxFlexGridSizer_new_2 1385 -#define wxFlexGridSizer_AddGrowableCol 1386 -#define wxFlexGridSizer_AddGrowableRow 1387 -#define wxFlexGridSizer_GetFlexibleDirection 1388 -#define wxFlexGridSizer_GetNonFlexibleGrowMode 1389 -#define wxFlexGridSizer_RemoveGrowableCol 1390 -#define wxFlexGridSizer_RemoveGrowableRow 1391 -#define wxFlexGridSizer_SetFlexibleDirection 1392 -#define wxFlexGridSizer_SetNonFlexibleGrowMode 1393 -#define wxFlexGridSizer_destroy 1394 -#define wxGridBagSizer_new 1395 -#define wxGridBagSizer_Add_3_2 1396 -#define wxGridBagSizer_Add_3_1 1397 -#define wxGridBagSizer_Add_4 1398 -#define wxGridBagSizer_Add_1_0 1399 -#define wxGridBagSizer_Add_2_1 1400 -#define wxGridBagSizer_Add_2_0 1401 -#define wxGridBagSizer_Add_3_0 1402 -#define wxGridBagSizer_Add_1_1 1403 -#define wxGridBagSizer_CalcMin 1404 -#define wxGridBagSizer_CheckForIntersection_2 1405 -#define wxGridBagSizer_CheckForIntersection_3 1406 -#define wxGridBagSizer_FindItem_1_1 1407 -#define wxGridBagSizer_FindItem_1_0 1408 -#define wxGridBagSizer_FindItemAtPoint 1409 -#define wxGridBagSizer_FindItemAtPosition 1410 -#define wxGridBagSizer_FindItemWithData 1411 -#define wxGridBagSizer_GetCellSize 1412 -#define wxGridBagSizer_GetEmptyCellSize 1413 -#define wxGridBagSizer_GetItemPosition_1_2 1414 -#define wxGridBagSizer_GetItemPosition_1_1 1415 -#define wxGridBagSizer_GetItemPosition_1_0 1416 -#define wxGridBagSizer_GetItemSpan_1_2 1417 -#define wxGridBagSizer_GetItemSpan_1_1 1418 -#define wxGridBagSizer_GetItemSpan_1_0 1419 -#define wxGridBagSizer_SetEmptyCellSize 1420 -#define wxGridBagSizer_SetItemPosition_2_2 1421 -#define wxGridBagSizer_SetItemPosition_2_1 1422 -#define wxGridBagSizer_SetItemPosition_2_0 1423 -#define wxGridBagSizer_SetItemSpan_2_2 1424 -#define wxGridBagSizer_SetItemSpan_2_1 1425 -#define wxGridBagSizer_SetItemSpan_2_0 1426 -#define wxGridBagSizer_destroy 1427 -#define wxStdDialogButtonSizer_new 1428 -#define wxStdDialogButtonSizer_AddButton 1429 -#define wxStdDialogButtonSizer_Realize 1430 -#define wxStdDialogButtonSizer_SetAffirmativeButton 1431 -#define wxStdDialogButtonSizer_SetCancelButton 1432 -#define wxStdDialogButtonSizer_SetNegativeButton 1433 -#define wxStdDialogButtonSizer_destroy 1434 -#define wxFont_new_0 1435 -#define wxFont_new_1 1436 -#define wxFont_new_5 1437 -#define wxFont_destruct 1439 -#define wxFont_IsFixedWidth 1440 -#define wxFont_GetDefaultEncoding 1441 -#define wxFont_GetFaceName 1442 -#define wxFont_GetFamily 1443 -#define wxFont_GetNativeFontInfoDesc 1444 -#define wxFont_GetNativeFontInfoUserDesc 1445 -#define wxFont_GetPointSize 1446 -#define wxFont_GetStyle 1447 -#define wxFont_GetUnderlined 1448 -#define wxFont_GetWeight 1449 -#define wxFont_Ok 1450 -#define wxFont_SetDefaultEncoding 1451 -#define wxFont_SetFaceName 1452 -#define wxFont_SetFamily 1453 -#define wxFont_SetPointSize 1454 -#define wxFont_SetStyle 1455 -#define wxFont_SetUnderlined 1456 -#define wxFont_SetWeight 1457 -#define wxToolTip_Enable 1458 -#define wxToolTip_SetDelay 1459 -#define wxToolTip_new 1460 -#define wxToolTip_SetTip 1461 -#define wxToolTip_GetTip 1462 -#define wxToolTip_GetWindow 1463 -#define wxToolTip_destroy 1464 -#define wxButton_new_3 1466 -#define wxButton_new_0 1467 -#define wxButton_destruct 1468 -#define wxButton_Create 1469 -#define wxButton_GetDefaultSize 1470 -#define wxButton_SetDefault 1471 -#define wxButton_SetLabel 1472 -#define wxBitmapButton_new_4 1474 -#define wxBitmapButton_new_0 1475 -#define wxBitmapButton_Create 1476 -#define wxBitmapButton_GetBitmapDisabled 1477 -#define wxBitmapButton_GetBitmapFocus 1479 -#define wxBitmapButton_GetBitmapLabel 1481 -#define wxBitmapButton_GetBitmapSelected 1483 -#define wxBitmapButton_SetBitmapDisabled 1485 -#define wxBitmapButton_SetBitmapFocus 1486 -#define wxBitmapButton_SetBitmapLabel 1487 -#define wxBitmapButton_SetBitmapSelected 1488 -#define wxBitmapButton_destroy 1489 -#define wxToggleButton_new_0 1490 -#define wxToggleButton_new_4 1491 -#define wxToggleButton_Create 1492 -#define wxToggleButton_GetValue 1493 -#define wxToggleButton_SetValue 1494 -#define wxToggleButton_destroy 1495 -#define wxCalendarCtrl_new_0 1496 -#define wxCalendarCtrl_new_3 1497 -#define wxCalendarCtrl_Create 1498 -#define wxCalendarCtrl_destruct 1499 -#define wxCalendarCtrl_SetDate 1500 -#define wxCalendarCtrl_GetDate 1501 -#define wxCalendarCtrl_EnableYearChange 1502 -#define wxCalendarCtrl_EnableMonthChange 1503 -#define wxCalendarCtrl_EnableHolidayDisplay 1504 -#define wxCalendarCtrl_SetHeaderColours 1505 -#define wxCalendarCtrl_GetHeaderColourFg 1506 -#define wxCalendarCtrl_GetHeaderColourBg 1507 -#define wxCalendarCtrl_SetHighlightColours 1508 -#define wxCalendarCtrl_GetHighlightColourFg 1509 -#define wxCalendarCtrl_GetHighlightColourBg 1510 -#define wxCalendarCtrl_SetHolidayColours 1511 -#define wxCalendarCtrl_GetHolidayColourFg 1512 -#define wxCalendarCtrl_GetHolidayColourBg 1513 -#define wxCalendarCtrl_GetAttr 1514 -#define wxCalendarCtrl_SetAttr 1515 -#define wxCalendarCtrl_SetHoliday 1516 -#define wxCalendarCtrl_ResetAttr 1517 -#define wxCalendarCtrl_HitTest 1518 -#define wxCalendarDateAttr_new_0 1519 -#define wxCalendarDateAttr_new_2_1 1520 -#define wxCalendarDateAttr_new_2_0 1521 -#define wxCalendarDateAttr_SetTextColour 1522 -#define wxCalendarDateAttr_SetBackgroundColour 1523 -#define wxCalendarDateAttr_SetBorderColour 1524 -#define wxCalendarDateAttr_SetFont 1525 -#define wxCalendarDateAttr_SetBorder 1526 -#define wxCalendarDateAttr_SetHoliday 1527 -#define wxCalendarDateAttr_HasTextColour 1528 -#define wxCalendarDateAttr_HasBackgroundColour 1529 -#define wxCalendarDateAttr_HasBorderColour 1530 -#define wxCalendarDateAttr_HasFont 1531 -#define wxCalendarDateAttr_HasBorder 1532 -#define wxCalendarDateAttr_IsHoliday 1533 -#define wxCalendarDateAttr_GetTextColour 1534 -#define wxCalendarDateAttr_GetBackgroundColour 1535 -#define wxCalendarDateAttr_GetBorderColour 1536 -#define wxCalendarDateAttr_GetFont 1537 -#define wxCalendarDateAttr_GetBorder 1538 -#define wxCalendarDateAttr_destroy 1539 -#define wxCheckBox_new_4 1541 -#define wxCheckBox_new_0 1542 -#define wxCheckBox_Create 1543 -#define wxCheckBox_GetValue 1544 -#define wxCheckBox_Get3StateValue 1545 -#define wxCheckBox_Is3rdStateAllowedForUser 1546 -#define wxCheckBox_Is3State 1547 -#define wxCheckBox_IsChecked 1548 -#define wxCheckBox_SetValue 1549 -#define wxCheckBox_Set3StateValue 1550 -#define wxCheckBox_destroy 1551 -#define wxCheckListBox_new_0 1552 -#define wxCheckListBox_new_3 1554 -#define wxCheckListBox_Check 1555 -#define wxCheckListBox_IsChecked 1556 -#define wxCheckListBox_destroy 1557 -#define wxChoice_new_3 1560 -#define wxChoice_new_0 1561 -#define wxChoice_destruct 1563 -#define wxChoice_Create 1565 -#define wxChoice_Delete 1566 -#define wxChoice_GetColumns 1567 -#define wxChoice_SetColumns 1568 -#define wxComboBox_new_0 1569 -#define wxComboBox_new_3 1571 -#define wxComboBox_destruct 1572 -#define wxComboBox_Create 1574 -#define wxComboBox_CanCopy 1575 -#define wxComboBox_CanCut 1576 -#define wxComboBox_CanPaste 1577 -#define wxComboBox_CanRedo 1578 -#define wxComboBox_CanUndo 1579 -#define wxComboBox_Copy 1580 -#define wxComboBox_Cut 1581 -#define wxComboBox_GetInsertionPoint 1582 -#define wxComboBox_GetLastPosition 1583 -#define wxComboBox_GetValue 1584 -#define wxComboBox_Paste 1585 -#define wxComboBox_Redo 1586 -#define wxComboBox_Replace 1587 -#define wxComboBox_Remove 1588 -#define wxComboBox_SetInsertionPoint 1589 -#define wxComboBox_SetInsertionPointEnd 1590 -#define wxComboBox_SetSelection_1 1591 -#define wxComboBox_SetSelection_2 1592 -#define wxComboBox_SetValue 1593 -#define wxComboBox_Undo 1594 -#define wxGauge_new_0 1595 -#define wxGauge_new_4 1596 -#define wxGauge_Create 1597 -#define wxGauge_GetBezelFace 1598 -#define wxGauge_GetRange 1599 -#define wxGauge_GetShadowWidth 1600 -#define wxGauge_GetValue 1601 -#define wxGauge_IsVertical 1602 -#define wxGauge_SetBezelFace 1603 -#define wxGauge_SetRange 1604 -#define wxGauge_SetShadowWidth 1605 -#define wxGauge_SetValue 1606 -#define wxGauge_Pulse 1607 -#define wxGauge_destroy 1608 -#define wxGenericDirCtrl_new_0 1609 -#define wxGenericDirCtrl_new_2 1610 -#define wxGenericDirCtrl_destruct 1611 -#define wxGenericDirCtrl_Create 1612 -#define wxGenericDirCtrl_Init 1613 -#define wxGenericDirCtrl_CollapseTree 1614 -#define wxGenericDirCtrl_ExpandPath 1615 -#define wxGenericDirCtrl_GetDefaultPath 1616 -#define wxGenericDirCtrl_GetPath 1617 -#define wxGenericDirCtrl_GetFilePath 1618 -#define wxGenericDirCtrl_GetFilter 1619 -#define wxGenericDirCtrl_GetFilterIndex 1620 -#define wxGenericDirCtrl_GetRootId 1621 -#define wxGenericDirCtrl_GetTreeCtrl 1622 -#define wxGenericDirCtrl_ReCreateTree 1623 -#define wxGenericDirCtrl_SetDefaultPath 1624 -#define wxGenericDirCtrl_SetFilter 1625 -#define wxGenericDirCtrl_SetFilterIndex 1626 -#define wxGenericDirCtrl_SetPath 1627 -#define wxStaticBox_new_4 1629 -#define wxStaticBox_new_0 1630 -#define wxStaticBox_Create 1631 -#define wxStaticBox_destroy 1632 -#define wxStaticLine_new_2 1634 -#define wxStaticLine_new_0 1635 -#define wxStaticLine_Create 1636 -#define wxStaticLine_IsVertical 1637 -#define wxStaticLine_GetDefaultSize 1638 -#define wxStaticLine_destroy 1639 -#define wxListBox_new_3 1642 -#define wxListBox_new_0 1643 -#define wxListBox_destruct 1645 -#define wxListBox_Create 1647 -#define wxListBox_Deselect 1648 -#define wxListBox_GetSelections 1649 -#define wxListBox_InsertItems 1650 -#define wxListBox_IsSelected 1651 -#define wxListBox_Set 1653 -#define wxListBox_HitTest 1654 -#define wxListBox_SetFirstItem_1_0 1655 -#define wxListBox_SetFirstItem_1_1 1656 -#define wxListCtrl_new_0 1657 -#define wxListCtrl_new_2 1658 -#define wxListCtrl_Arrange 1659 -#define wxListCtrl_AssignImageList 1660 -#define wxListCtrl_ClearAll 1661 -#define wxListCtrl_Create 1662 -#define wxListCtrl_DeleteAllItems 1663 -#define wxListCtrl_DeleteColumn 1664 -#define wxListCtrl_DeleteItem 1665 -#define wxListCtrl_EditLabel 1666 -#define wxListCtrl_EnsureVisible 1667 -#define wxListCtrl_FindItem_3_0 1668 -#define wxListCtrl_FindItem_3_1 1669 -#define wxListCtrl_GetColumn 1670 -#define wxListCtrl_GetColumnCount 1671 -#define wxListCtrl_GetColumnWidth 1672 -#define wxListCtrl_GetCountPerPage 1673 -#define wxListCtrl_GetEditControl 1674 -#define wxListCtrl_GetImageList 1675 -#define wxListCtrl_GetItem 1676 -#define wxListCtrl_GetItemBackgroundColour 1677 -#define wxListCtrl_GetItemCount 1678 -#define wxListCtrl_GetItemData 1679 -#define wxListCtrl_GetItemFont 1680 -#define wxListCtrl_GetItemPosition 1681 -#define wxListCtrl_GetItemRect 1682 -#define wxListCtrl_GetItemSpacing 1683 -#define wxListCtrl_GetItemState 1684 -#define wxListCtrl_GetItemText 1685 -#define wxListCtrl_GetItemTextColour 1686 -#define wxListCtrl_GetNextItem 1687 -#define wxListCtrl_GetSelectedItemCount 1688 -#define wxListCtrl_GetTextColour 1689 -#define wxListCtrl_GetTopItem 1690 -#define wxListCtrl_GetViewRect 1691 -#define wxListCtrl_HitTest 1692 -#define wxListCtrl_InsertColumn_2 1693 -#define wxListCtrl_InsertColumn_3 1694 -#define wxListCtrl_InsertItem_1 1695 -#define wxListCtrl_InsertItem_2_1 1696 -#define wxListCtrl_InsertItem_2_0 1697 -#define wxListCtrl_InsertItem_3 1698 -#define wxListCtrl_RefreshItem 1699 -#define wxListCtrl_RefreshItems 1700 -#define wxListCtrl_ScrollList 1701 -#define wxListCtrl_SetBackgroundColour 1702 -#define wxListCtrl_SetColumn 1703 -#define wxListCtrl_SetColumnWidth 1704 -#define wxListCtrl_SetImageList 1705 -#define wxListCtrl_SetItem_1 1706 -#define wxListCtrl_SetItem_4 1707 -#define wxListCtrl_SetItemBackgroundColour 1708 -#define wxListCtrl_SetItemCount 1709 -#define wxListCtrl_SetItemData 1710 -#define wxListCtrl_SetItemFont 1711 -#define wxListCtrl_SetItemImage 1712 -#define wxListCtrl_SetItemColumnImage 1713 -#define wxListCtrl_SetItemPosition 1714 -#define wxListCtrl_SetItemState 1715 -#define wxListCtrl_SetItemText 1716 -#define wxListCtrl_SetItemTextColour 1717 -#define wxListCtrl_SetSingleStyle 1718 -#define wxListCtrl_SetTextColour 1719 -#define wxListCtrl_SetWindowStyleFlag 1720 -#define wxListCtrl_SortItems 1721 -#define wxListCtrl_destroy 1722 -#define wxListView_ClearColumnImage 1723 -#define wxListView_Focus 1724 -#define wxListView_GetFirstSelected 1725 -#define wxListView_GetFocusedItem 1726 -#define wxListView_GetNextSelected 1727 -#define wxListView_IsSelected 1728 -#define wxListView_Select 1729 -#define wxListView_SetColumnImage 1730 -#define wxListItem_new_0 1731 -#define wxListItem_new_1 1732 -#define wxListItem_destruct 1733 -#define wxListItem_Clear 1734 -#define wxListItem_GetAlign 1735 -#define wxListItem_GetBackgroundColour 1736 -#define wxListItem_GetColumn 1737 -#define wxListItem_GetFont 1738 -#define wxListItem_GetId 1739 -#define wxListItem_GetImage 1740 -#define wxListItem_GetMask 1741 -#define wxListItem_GetState 1742 -#define wxListItem_GetText 1743 -#define wxListItem_GetTextColour 1744 -#define wxListItem_GetWidth 1745 -#define wxListItem_SetAlign 1746 -#define wxListItem_SetBackgroundColour 1747 -#define wxListItem_SetColumn 1748 -#define wxListItem_SetFont 1749 -#define wxListItem_SetId 1750 -#define wxListItem_SetImage 1751 -#define wxListItem_SetMask 1752 -#define wxListItem_SetState 1753 -#define wxListItem_SetStateMask 1754 -#define wxListItem_SetText 1755 -#define wxListItem_SetTextColour 1756 -#define wxListItem_SetWidth 1757 -#define wxListItemAttr_new_0 1758 -#define wxListItemAttr_new_3 1759 -#define wxListItemAttr_GetBackgroundColour 1760 -#define wxListItemAttr_GetFont 1761 -#define wxListItemAttr_GetTextColour 1762 -#define wxListItemAttr_HasBackgroundColour 1763 -#define wxListItemAttr_HasFont 1764 -#define wxListItemAttr_HasTextColour 1765 -#define wxListItemAttr_SetBackgroundColour 1766 -#define wxListItemAttr_SetFont 1767 -#define wxListItemAttr_SetTextColour 1768 -#define wxListItemAttr_destroy 1769 -#define wxImageList_new_0 1770 -#define wxImageList_new_3 1771 -#define wxImageList_Add_1 1772 -#define wxImageList_Add_2_0 1773 -#define wxImageList_Add_2_1 1774 -#define wxImageList_Create 1775 -#define wxImageList_Draw 1777 -#define wxImageList_GetBitmap 1778 -#define wxImageList_GetIcon 1779 -#define wxImageList_GetImageCount 1780 -#define wxImageList_GetSize 1781 -#define wxImageList_Remove 1782 -#define wxImageList_RemoveAll 1783 -#define wxImageList_Replace_2 1784 -#define wxImageList_Replace_3 1785 -#define wxImageList_destroy 1786 -#define wxTextAttr_new_0 1787 -#define wxTextAttr_new_2 1788 -#define wxTextAttr_GetAlignment 1789 -#define wxTextAttr_GetBackgroundColour 1790 -#define wxTextAttr_GetFont 1791 -#define wxTextAttr_GetLeftIndent 1792 -#define wxTextAttr_GetLeftSubIndent 1793 -#define wxTextAttr_GetRightIndent 1794 -#define wxTextAttr_GetTabs 1795 -#define wxTextAttr_GetTextColour 1796 -#define wxTextAttr_HasBackgroundColour 1797 -#define wxTextAttr_HasFont 1798 -#define wxTextAttr_HasTextColour 1799 -#define wxTextAttr_GetFlags 1800 -#define wxTextAttr_IsDefault 1801 -#define wxTextAttr_SetAlignment 1802 -#define wxTextAttr_SetBackgroundColour 1803 -#define wxTextAttr_SetFlags 1804 -#define wxTextAttr_SetFont 1805 -#define wxTextAttr_SetLeftIndent 1806 -#define wxTextAttr_SetRightIndent 1807 -#define wxTextAttr_SetTabs 1808 -#define wxTextAttr_SetTextColour 1809 -#define wxTextAttr_destroy 1810 -#define wxTextCtrl_new_3 1812 -#define wxTextCtrl_new_0 1813 -#define wxTextCtrl_destruct 1815 -#define wxTextCtrl_AppendText 1816 -#define wxTextCtrl_CanCopy 1817 -#define wxTextCtrl_CanCut 1818 -#define wxTextCtrl_CanPaste 1819 -#define wxTextCtrl_CanRedo 1820 -#define wxTextCtrl_CanUndo 1821 -#define wxTextCtrl_Clear 1822 -#define wxTextCtrl_Copy 1823 -#define wxTextCtrl_Create 1824 -#define wxTextCtrl_Cut 1825 -#define wxTextCtrl_DiscardEdits 1826 -#define wxTextCtrl_EmulateKeyPress 1827 -#define wxTextCtrl_GetDefaultStyle 1828 -#define wxTextCtrl_GetInsertionPoint 1829 -#define wxTextCtrl_GetLastPosition 1830 -#define wxTextCtrl_GetLineLength 1831 -#define wxTextCtrl_GetLineText 1832 -#define wxTextCtrl_GetNumberOfLines 1833 -#define wxTextCtrl_GetRange 1834 -#define wxTextCtrl_GetSelection 1835 -#define wxTextCtrl_GetStringSelection 1836 -#define wxTextCtrl_GetStyle 1837 -#define wxTextCtrl_GetValue 1838 -#define wxTextCtrl_IsEditable 1839 -#define wxTextCtrl_IsModified 1840 -#define wxTextCtrl_IsMultiLine 1841 -#define wxTextCtrl_IsSingleLine 1842 -#define wxTextCtrl_LoadFile 1843 -#define wxTextCtrl_MarkDirty 1844 -#define wxTextCtrl_Paste 1845 -#define wxTextCtrl_PositionToXY 1846 -#define wxTextCtrl_Redo 1847 -#define wxTextCtrl_Remove 1848 -#define wxTextCtrl_Replace 1849 -#define wxTextCtrl_SaveFile 1850 -#define wxTextCtrl_SetDefaultStyle 1851 -#define wxTextCtrl_SetEditable 1852 -#define wxTextCtrl_SetInsertionPoint 1853 -#define wxTextCtrl_SetInsertionPointEnd 1854 -#define wxTextCtrl_SetMaxLength 1856 -#define wxTextCtrl_SetSelection 1857 -#define wxTextCtrl_SetStyle 1858 -#define wxTextCtrl_SetValue 1859 -#define wxTextCtrl_ShowPosition 1860 -#define wxTextCtrl_Undo 1861 -#define wxTextCtrl_WriteText 1862 -#define wxTextCtrl_XYToPosition 1863 -#define wxNotebook_new_0 1866 -#define wxNotebook_new_3 1867 -#define wxNotebook_destruct 1868 -#define wxNotebook_AddPage 1869 -#define wxNotebook_AdvanceSelection 1870 -#define wxNotebook_AssignImageList 1871 -#define wxNotebook_Create 1872 -#define wxNotebook_DeleteAllPages 1873 -#define wxNotebook_DeletePage 1874 -#define wxNotebook_RemovePage 1875 -#define wxNotebook_GetCurrentPage 1876 -#define wxNotebook_GetImageList 1877 -#define wxNotebook_GetPage 1879 -#define wxNotebook_GetPageCount 1880 -#define wxNotebook_GetPageImage 1881 -#define wxNotebook_GetPageText 1882 -#define wxNotebook_GetRowCount 1883 -#define wxNotebook_GetSelection 1884 -#define wxNotebook_GetThemeBackgroundColour 1885 -#define wxNotebook_HitTest 1887 -#define wxNotebook_InsertPage 1889 -#define wxNotebook_SetImageList 1890 -#define wxNotebook_SetPadding 1891 -#define wxNotebook_SetPageSize 1892 -#define wxNotebook_SetPageImage 1893 -#define wxNotebook_SetPageText 1894 -#define wxNotebook_SetSelection 1895 -#define wxNotebook_ChangeSelection 1896 -#define wxChoicebook_new_0 1897 -#define wxChoicebook_new_3 1898 -#define wxChoicebook_AddPage 1899 -#define wxChoicebook_AdvanceSelection 1900 -#define wxChoicebook_AssignImageList 1901 -#define wxChoicebook_Create 1902 -#define wxChoicebook_DeleteAllPages 1903 -#define wxChoicebook_DeletePage 1904 -#define wxChoicebook_RemovePage 1905 -#define wxChoicebook_GetCurrentPage 1906 -#define wxChoicebook_GetImageList 1907 -#define wxChoicebook_GetPage 1909 -#define wxChoicebook_GetPageCount 1910 -#define wxChoicebook_GetPageImage 1911 -#define wxChoicebook_GetPageText 1912 -#define wxChoicebook_GetSelection 1913 -#define wxChoicebook_HitTest 1914 -#define wxChoicebook_InsertPage 1915 -#define wxChoicebook_SetImageList 1916 -#define wxChoicebook_SetPageSize 1917 -#define wxChoicebook_SetPageImage 1918 -#define wxChoicebook_SetPageText 1919 -#define wxChoicebook_SetSelection 1920 -#define wxChoicebook_ChangeSelection 1921 -#define wxChoicebook_destroy 1922 -#define wxToolbook_new_0 1923 -#define wxToolbook_new_3 1924 -#define wxToolbook_AddPage 1925 -#define wxToolbook_AdvanceSelection 1926 -#define wxToolbook_AssignImageList 1927 -#define wxToolbook_Create 1928 -#define wxToolbook_DeleteAllPages 1929 -#define wxToolbook_DeletePage 1930 -#define wxToolbook_RemovePage 1931 -#define wxToolbook_GetCurrentPage 1932 -#define wxToolbook_GetImageList 1933 -#define wxToolbook_GetPage 1935 -#define wxToolbook_GetPageCount 1936 -#define wxToolbook_GetPageImage 1937 -#define wxToolbook_GetPageText 1938 -#define wxToolbook_GetSelection 1939 -#define wxToolbook_HitTest 1941 -#define wxToolbook_InsertPage 1942 -#define wxToolbook_SetImageList 1943 -#define wxToolbook_SetPageSize 1944 -#define wxToolbook_SetPageImage 1945 -#define wxToolbook_SetPageText 1946 -#define wxToolbook_SetSelection 1947 -#define wxToolbook_ChangeSelection 1948 -#define wxToolbook_destroy 1949 -#define wxListbook_new_0 1950 -#define wxListbook_new_3 1951 -#define wxListbook_AddPage 1952 -#define wxListbook_AdvanceSelection 1953 -#define wxListbook_AssignImageList 1954 -#define wxListbook_Create 1955 -#define wxListbook_DeleteAllPages 1956 -#define wxListbook_DeletePage 1957 -#define wxListbook_RemovePage 1958 -#define wxListbook_GetCurrentPage 1959 -#define wxListbook_GetImageList 1960 -#define wxListbook_GetPage 1962 -#define wxListbook_GetPageCount 1963 -#define wxListbook_GetPageImage 1964 -#define wxListbook_GetPageText 1965 -#define wxListbook_GetSelection 1966 -#define wxListbook_HitTest 1968 -#define wxListbook_InsertPage 1969 -#define wxListbook_SetImageList 1970 -#define wxListbook_SetPageSize 1971 -#define wxListbook_SetPageImage 1972 -#define wxListbook_SetPageText 1973 -#define wxListbook_SetSelection 1974 -#define wxListbook_ChangeSelection 1975 -#define wxListbook_destroy 1976 -#define wxTreebook_new_0 1977 -#define wxTreebook_new_3 1978 -#define wxTreebook_AddPage 1979 -#define wxTreebook_AdvanceSelection 1980 -#define wxTreebook_AssignImageList 1981 -#define wxTreebook_Create 1982 -#define wxTreebook_DeleteAllPages 1983 -#define wxTreebook_DeletePage 1984 -#define wxTreebook_RemovePage 1985 -#define wxTreebook_GetCurrentPage 1986 -#define wxTreebook_GetImageList 1987 -#define wxTreebook_GetPage 1989 -#define wxTreebook_GetPageCount 1990 -#define wxTreebook_GetPageImage 1991 -#define wxTreebook_GetPageText 1992 -#define wxTreebook_GetSelection 1993 -#define wxTreebook_ExpandNode 1994 -#define wxTreebook_IsNodeExpanded 1995 -#define wxTreebook_HitTest 1997 -#define wxTreebook_InsertPage 1998 -#define wxTreebook_InsertSubPage 1999 -#define wxTreebook_SetImageList 2000 -#define wxTreebook_SetPageSize 2001 -#define wxTreebook_SetPageImage 2002 -#define wxTreebook_SetPageText 2003 -#define wxTreebook_SetSelection 2004 -#define wxTreebook_ChangeSelection 2005 -#define wxTreebook_destroy 2006 -#define wxTreeCtrl_new_2 2009 -#define wxTreeCtrl_new_0 2010 -#define wxTreeCtrl_destruct 2012 -#define wxTreeCtrl_AddRoot 2013 -#define wxTreeCtrl_AppendItem 2014 -#define wxTreeCtrl_AssignImageList 2015 -#define wxTreeCtrl_AssignStateImageList 2016 -#define wxTreeCtrl_Collapse 2017 -#define wxTreeCtrl_CollapseAndReset 2018 -#define wxTreeCtrl_Create 2019 -#define wxTreeCtrl_Delete 2020 -#define wxTreeCtrl_DeleteAllItems 2021 -#define wxTreeCtrl_DeleteChildren 2022 -#define wxTreeCtrl_EditLabel 2023 -#define wxTreeCtrl_EnsureVisible 2024 -#define wxTreeCtrl_Expand 2025 -#define wxTreeCtrl_GetBoundingRect 2026 -#define wxTreeCtrl_GetChildrenCount 2028 -#define wxTreeCtrl_GetCount 2029 -#define wxTreeCtrl_GetEditControl 2030 -#define wxTreeCtrl_GetFirstChild 2031 -#define wxTreeCtrl_GetNextChild 2032 -#define wxTreeCtrl_GetFirstVisibleItem 2033 -#define wxTreeCtrl_GetImageList 2034 -#define wxTreeCtrl_GetIndent 2035 -#define wxTreeCtrl_GetItemBackgroundColour 2036 -#define wxTreeCtrl_GetItemData 2037 -#define wxTreeCtrl_GetItemFont 2038 -#define wxTreeCtrl_GetItemImage_1 2039 -#define wxTreeCtrl_GetItemImage_2 2040 -#define wxTreeCtrl_GetItemText 2041 -#define wxTreeCtrl_GetItemTextColour 2042 -#define wxTreeCtrl_GetLastChild 2043 -#define wxTreeCtrl_GetNextSibling 2044 -#define wxTreeCtrl_GetNextVisible 2045 -#define wxTreeCtrl_GetItemParent 2046 -#define wxTreeCtrl_GetPrevSibling 2047 -#define wxTreeCtrl_GetPrevVisible 2048 -#define wxTreeCtrl_GetRootItem 2049 -#define wxTreeCtrl_GetSelection 2050 -#define wxTreeCtrl_GetSelections 2051 -#define wxTreeCtrl_GetStateImageList 2052 -#define wxTreeCtrl_HitTest 2053 -#define wxTreeCtrl_InsertItem 2055 -#define wxTreeCtrl_IsBold 2056 -#define wxTreeCtrl_IsExpanded 2057 -#define wxTreeCtrl_IsSelected 2058 -#define wxTreeCtrl_IsVisible 2059 -#define wxTreeCtrl_ItemHasChildren 2060 -#define wxTreeCtrl_IsTreeItemIdOk 2061 -#define wxTreeCtrl_PrependItem 2062 -#define wxTreeCtrl_ScrollTo 2063 -#define wxTreeCtrl_SelectItem_1 2064 -#define wxTreeCtrl_SelectItem_2 2065 -#define wxTreeCtrl_SetIndent 2066 -#define wxTreeCtrl_SetImageList 2067 -#define wxTreeCtrl_SetItemBackgroundColour 2068 -#define wxTreeCtrl_SetItemBold 2069 -#define wxTreeCtrl_SetItemData 2070 -#define wxTreeCtrl_SetItemDropHighlight 2071 -#define wxTreeCtrl_SetItemFont 2072 -#define wxTreeCtrl_SetItemHasChildren 2073 -#define wxTreeCtrl_SetItemImage_2 2074 -#define wxTreeCtrl_SetItemImage_3 2075 -#define wxTreeCtrl_SetItemText 2076 -#define wxTreeCtrl_SetItemTextColour 2077 -#define wxTreeCtrl_SetStateImageList 2078 -#define wxTreeCtrl_SetWindowStyle 2079 -#define wxTreeCtrl_SortChildren 2080 -#define wxTreeCtrl_Toggle 2081 -#define wxTreeCtrl_ToggleItemSelection 2082 -#define wxTreeCtrl_Unselect 2083 -#define wxTreeCtrl_UnselectAll 2084 -#define wxTreeCtrl_UnselectItem 2085 -#define wxScrollBar_new_0 2086 -#define wxScrollBar_new_3 2087 -#define wxScrollBar_destruct 2088 -#define wxScrollBar_Create 2089 -#define wxScrollBar_GetRange 2090 -#define wxScrollBar_GetPageSize 2091 -#define wxScrollBar_GetThumbPosition 2092 -#define wxScrollBar_GetThumbSize 2093 -#define wxScrollBar_SetThumbPosition 2094 -#define wxScrollBar_SetScrollbar 2095 -#define wxSpinButton_new_2 2097 -#define wxSpinButton_new_0 2098 -#define wxSpinButton_Create 2099 -#define wxSpinButton_GetMax 2100 -#define wxSpinButton_GetMin 2101 -#define wxSpinButton_GetValue 2102 -#define wxSpinButton_SetRange 2103 -#define wxSpinButton_SetValue 2104 -#define wxSpinButton_destroy 2105 -#define wxSpinCtrl_new_0 2106 -#define wxSpinCtrl_new_2 2107 -#define wxSpinCtrl_Create 2109 -#define wxSpinCtrl_SetValue_1_1 2112 -#define wxSpinCtrl_SetValue_1_0 2113 -#define wxSpinCtrl_GetValue 2115 -#define wxSpinCtrl_SetRange 2117 -#define wxSpinCtrl_SetSelection 2118 -#define wxSpinCtrl_GetMin 2120 -#define wxSpinCtrl_GetMax 2122 -#define wxSpinCtrl_destroy 2123 -#define wxStaticText_new_0 2124 -#define wxStaticText_new_4 2125 -#define wxStaticText_Create 2126 -#define wxStaticText_GetLabel 2127 -#define wxStaticText_SetLabel 2128 -#define wxStaticText_Wrap 2129 -#define wxStaticText_destroy 2130 -#define wxStaticBitmap_new_0 2131 -#define wxStaticBitmap_new_4 2132 -#define wxStaticBitmap_Create 2133 -#define wxStaticBitmap_GetBitmap 2134 -#define wxStaticBitmap_SetBitmap 2135 -#define wxStaticBitmap_destroy 2136 -#define wxRadioBox_new 2137 -#define wxRadioBox_destruct 2139 -#define wxRadioBox_Create 2140 -#define wxRadioBox_Enable_2 2141 -#define wxRadioBox_Enable_1 2142 -#define wxRadioBox_GetSelection 2143 -#define wxRadioBox_GetString 2144 -#define wxRadioBox_SetSelection 2145 -#define wxRadioBox_Show_2 2146 -#define wxRadioBox_Show_1 2147 -#define wxRadioBox_GetColumnCount 2148 -#define wxRadioBox_GetItemHelpText 2149 -#define wxRadioBox_GetItemToolTip 2150 -#define wxRadioBox_GetItemFromPoint 2152 -#define wxRadioBox_GetRowCount 2153 -#define wxRadioBox_IsItemEnabled 2154 -#define wxRadioBox_IsItemShown 2155 -#define wxRadioBox_SetItemHelpText 2156 -#define wxRadioBox_SetItemToolTip 2157 -#define wxRadioButton_new_0 2158 -#define wxRadioButton_new_4 2159 -#define wxRadioButton_Create 2160 -#define wxRadioButton_GetValue 2161 -#define wxRadioButton_SetValue 2162 -#define wxRadioButton_destroy 2163 -#define wxSlider_new_6 2165 -#define wxSlider_new_0 2166 -#define wxSlider_Create 2167 -#define wxSlider_GetLineSize 2168 -#define wxSlider_GetMax 2169 -#define wxSlider_GetMin 2170 -#define wxSlider_GetPageSize 2171 -#define wxSlider_GetThumbLength 2172 -#define wxSlider_GetValue 2173 -#define wxSlider_SetLineSize 2174 -#define wxSlider_SetPageSize 2175 -#define wxSlider_SetRange 2176 -#define wxSlider_SetThumbLength 2177 -#define wxSlider_SetValue 2178 -#define wxSlider_destroy 2179 -#define wxDialog_new_4 2181 -#define wxDialog_new_0 2182 -#define wxDialog_destruct 2184 -#define wxDialog_Create 2185 -#define wxDialog_CreateButtonSizer 2186 -#define wxDialog_CreateStdDialogButtonSizer 2187 -#define wxDialog_EndModal 2188 -#define wxDialog_GetAffirmativeId 2189 -#define wxDialog_GetReturnCode 2190 -#define wxDialog_IsModal 2191 -#define wxDialog_SetAffirmativeId 2192 -#define wxDialog_SetReturnCode 2193 -#define wxDialog_Show 2194 -#define wxDialog_ShowModal 2195 -#define wxColourDialog_new_0 2196 -#define wxColourDialog_new_2 2197 -#define wxColourDialog_destruct 2198 -#define wxColourDialog_Create 2199 -#define wxColourDialog_GetColourData 2200 -#define wxColourData_new_0 2201 -#define wxColourData_new_1 2202 -#define wxColourData_destruct 2203 -#define wxColourData_GetChooseFull 2204 -#define wxColourData_GetColour 2205 -#define wxColourData_GetCustomColour 2207 -#define wxColourData_SetChooseFull 2208 -#define wxColourData_SetColour 2209 -#define wxColourData_SetCustomColour 2210 -#define wxPalette_new_0 2211 -#define wxPalette_new_4 2212 -#define wxPalette_destruct 2214 -#define wxPalette_Create 2215 -#define wxPalette_GetColoursCount 2216 -#define wxPalette_GetPixel 2217 -#define wxPalette_GetRGB 2218 -#define wxPalette_IsOk 2219 -#define wxDirDialog_new 2223 -#define wxDirDialog_destruct 2224 -#define wxDirDialog_GetPath 2225 -#define wxDirDialog_GetMessage 2226 -#define wxDirDialog_SetMessage 2227 -#define wxDirDialog_SetPath 2228 -#define wxFileDialog_new 2232 -#define wxFileDialog_destruct 2233 -#define wxFileDialog_GetDirectory 2234 -#define wxFileDialog_GetFilename 2235 -#define wxFileDialog_GetFilenames 2236 -#define wxFileDialog_GetFilterIndex 2237 -#define wxFileDialog_GetMessage 2238 -#define wxFileDialog_GetPath 2239 -#define wxFileDialog_GetPaths 2240 -#define wxFileDialog_GetWildcard 2241 -#define wxFileDialog_SetDirectory 2242 -#define wxFileDialog_SetFilename 2243 -#define wxFileDialog_SetFilterIndex 2244 -#define wxFileDialog_SetMessage 2245 -#define wxFileDialog_SetPath 2246 -#define wxFileDialog_SetWildcard 2247 -#define wxPickerBase_SetInternalMargin 2248 -#define wxPickerBase_GetInternalMargin 2249 -#define wxPickerBase_SetTextCtrlProportion 2250 -#define wxPickerBase_SetPickerCtrlProportion 2251 -#define wxPickerBase_GetTextCtrlProportion 2252 -#define wxPickerBase_GetPickerCtrlProportion 2253 -#define wxPickerBase_HasTextCtrl 2254 -#define wxPickerBase_GetTextCtrl 2255 -#define wxPickerBase_IsTextCtrlGrowable 2256 -#define wxPickerBase_SetPickerCtrlGrowable 2257 -#define wxPickerBase_SetTextCtrlGrowable 2258 -#define wxPickerBase_IsPickerCtrlGrowable 2259 -#define wxFilePickerCtrl_new_0 2260 -#define wxFilePickerCtrl_new_3 2261 -#define wxFilePickerCtrl_Create 2262 -#define wxFilePickerCtrl_GetPath 2263 -#define wxFilePickerCtrl_SetPath 2264 -#define wxFilePickerCtrl_destroy 2265 -#define wxDirPickerCtrl_new_0 2266 -#define wxDirPickerCtrl_new_3 2267 -#define wxDirPickerCtrl_Create 2268 -#define wxDirPickerCtrl_GetPath 2269 -#define wxDirPickerCtrl_SetPath 2270 -#define wxDirPickerCtrl_destroy 2271 -#define wxColourPickerCtrl_new_0 2272 -#define wxColourPickerCtrl_new_3 2273 -#define wxColourPickerCtrl_Create 2274 -#define wxColourPickerCtrl_GetColour 2275 -#define wxColourPickerCtrl_SetColour_1_1 2276 -#define wxColourPickerCtrl_SetColour_1_0 2277 -#define wxColourPickerCtrl_destroy 2278 -#define wxDatePickerCtrl_new_0 2279 -#define wxDatePickerCtrl_new_3 2280 -#define wxDatePickerCtrl_GetRange 2281 -#define wxDatePickerCtrl_GetValue 2282 -#define wxDatePickerCtrl_SetRange 2283 -#define wxDatePickerCtrl_SetValue 2284 -#define wxDatePickerCtrl_destroy 2285 -#define wxFontPickerCtrl_new_0 2286 -#define wxFontPickerCtrl_new_3 2287 -#define wxFontPickerCtrl_Create 2288 -#define wxFontPickerCtrl_GetSelectedFont 2289 -#define wxFontPickerCtrl_SetSelectedFont 2290 -#define wxFontPickerCtrl_GetMaxPointSize 2291 -#define wxFontPickerCtrl_SetMaxPointSize 2292 -#define wxFontPickerCtrl_destroy 2293 -#define wxFindReplaceDialog_new_0 2296 -#define wxFindReplaceDialog_new_4 2297 -#define wxFindReplaceDialog_destruct 2298 -#define wxFindReplaceDialog_Create 2299 -#define wxFindReplaceDialog_GetData 2300 -#define wxFindReplaceData_new_0 2301 -#define wxFindReplaceData_new_1 2302 -#define wxFindReplaceData_GetFindString 2303 -#define wxFindReplaceData_GetReplaceString 2304 -#define wxFindReplaceData_GetFlags 2305 -#define wxFindReplaceData_SetFlags 2306 -#define wxFindReplaceData_SetFindString 2307 -#define wxFindReplaceData_SetReplaceString 2308 -#define wxFindReplaceData_destroy 2309 -#define wxMultiChoiceDialog_new_0 2310 -#define wxMultiChoiceDialog_new_5 2312 -#define wxMultiChoiceDialog_GetSelections 2313 -#define wxMultiChoiceDialog_SetSelections 2314 -#define wxMultiChoiceDialog_destroy 2315 -#define wxSingleChoiceDialog_new_0 2316 -#define wxSingleChoiceDialog_new_5 2318 -#define wxSingleChoiceDialog_GetSelection 2319 -#define wxSingleChoiceDialog_GetStringSelection 2320 -#define wxSingleChoiceDialog_SetSelection 2321 -#define wxSingleChoiceDialog_destroy 2322 -#define wxTextEntryDialog_new 2323 -#define wxTextEntryDialog_GetValue 2324 -#define wxTextEntryDialog_SetValue 2325 -#define wxTextEntryDialog_destroy 2326 -#define wxPasswordEntryDialog_new 2327 -#define wxPasswordEntryDialog_destroy 2328 -#define wxFontData_new_0 2329 -#define wxFontData_new_1 2330 -#define wxFontData_destruct 2331 -#define wxFontData_EnableEffects 2332 -#define wxFontData_GetAllowSymbols 2333 -#define wxFontData_GetColour 2334 -#define wxFontData_GetChosenFont 2335 -#define wxFontData_GetEnableEffects 2336 -#define wxFontData_GetInitialFont 2337 -#define wxFontData_GetShowHelp 2338 -#define wxFontData_SetAllowSymbols 2339 -#define wxFontData_SetChosenFont 2340 -#define wxFontData_SetColour 2341 -#define wxFontData_SetInitialFont 2342 -#define wxFontData_SetRange 2343 -#define wxFontData_SetShowHelp 2344 -#define wxFontDialog_new_0 2348 -#define wxFontDialog_new_2 2350 -#define wxFontDialog_Create 2352 -#define wxFontDialog_GetFontData 2353 -#define wxFontDialog_destroy 2355 -#define wxProgressDialog_new 2356 -#define wxProgressDialog_destruct 2357 -#define wxProgressDialog_Resume 2358 -#define wxProgressDialog_Update_2 2359 -#define wxProgressDialog_Update_0 2360 -#define wxMessageDialog_new 2361 -#define wxMessageDialog_destruct 2362 -#define wxPageSetupDialog_new 2363 -#define wxPageSetupDialog_destruct 2364 -#define wxPageSetupDialog_GetPageSetupData 2365 -#define wxPageSetupDialog_ShowModal 2366 -#define wxPageSetupDialogData_new_0 2367 -#define wxPageSetupDialogData_new_1_0 2368 -#define wxPageSetupDialogData_new_1_1 2369 -#define wxPageSetupDialogData_destruct 2370 -#define wxPageSetupDialogData_EnableHelp 2371 -#define wxPageSetupDialogData_EnableMargins 2372 -#define wxPageSetupDialogData_EnableOrientation 2373 -#define wxPageSetupDialogData_EnablePaper 2374 -#define wxPageSetupDialogData_EnablePrinter 2375 -#define wxPageSetupDialogData_GetDefaultMinMargins 2376 -#define wxPageSetupDialogData_GetEnableMargins 2377 -#define wxPageSetupDialogData_GetEnableOrientation 2378 -#define wxPageSetupDialogData_GetEnablePaper 2379 -#define wxPageSetupDialogData_GetEnablePrinter 2380 -#define wxPageSetupDialogData_GetEnableHelp 2381 -#define wxPageSetupDialogData_GetDefaultInfo 2382 -#define wxPageSetupDialogData_GetMarginTopLeft 2383 -#define wxPageSetupDialogData_GetMarginBottomRight 2384 -#define wxPageSetupDialogData_GetMinMarginTopLeft 2385 -#define wxPageSetupDialogData_GetMinMarginBottomRight 2386 -#define wxPageSetupDialogData_GetPaperId 2387 -#define wxPageSetupDialogData_GetPaperSize 2388 -#define wxPageSetupDialogData_GetPrintData 2390 -#define wxPageSetupDialogData_IsOk 2391 -#define wxPageSetupDialogData_SetDefaultInfo 2392 -#define wxPageSetupDialogData_SetDefaultMinMargins 2393 -#define wxPageSetupDialogData_SetMarginTopLeft 2394 -#define wxPageSetupDialogData_SetMarginBottomRight 2395 -#define wxPageSetupDialogData_SetMinMarginTopLeft 2396 -#define wxPageSetupDialogData_SetMinMarginBottomRight 2397 -#define wxPageSetupDialogData_SetPaperId 2398 -#define wxPageSetupDialogData_SetPaperSize_1_1 2399 -#define wxPageSetupDialogData_SetPaperSize_1_0 2400 -#define wxPageSetupDialogData_SetPrintData 2401 -#define wxPrintDialog_new_2_0 2402 -#define wxPrintDialog_new_2_1 2403 -#define wxPrintDialog_destruct 2404 -#define wxPrintDialog_GetPrintDialogData 2405 -#define wxPrintDialog_GetPrintDC 2406 -#define wxPrintDialogData_new_0 2407 -#define wxPrintDialogData_new_1_1 2408 -#define wxPrintDialogData_new_1_0 2409 -#define wxPrintDialogData_destruct 2410 -#define wxPrintDialogData_EnableHelp 2411 -#define wxPrintDialogData_EnablePageNumbers 2412 -#define wxPrintDialogData_EnablePrintToFile 2413 -#define wxPrintDialogData_EnableSelection 2414 -#define wxPrintDialogData_GetAllPages 2415 -#define wxPrintDialogData_GetCollate 2416 -#define wxPrintDialogData_GetFromPage 2417 -#define wxPrintDialogData_GetMaxPage 2418 -#define wxPrintDialogData_GetMinPage 2419 -#define wxPrintDialogData_GetNoCopies 2420 -#define wxPrintDialogData_GetPrintData 2421 -#define wxPrintDialogData_GetPrintToFile 2422 -#define wxPrintDialogData_GetSelection 2423 -#define wxPrintDialogData_GetToPage 2424 -#define wxPrintDialogData_IsOk 2425 -#define wxPrintDialogData_SetCollate 2426 -#define wxPrintDialogData_SetFromPage 2427 -#define wxPrintDialogData_SetMaxPage 2428 -#define wxPrintDialogData_SetMinPage 2429 -#define wxPrintDialogData_SetNoCopies 2430 -#define wxPrintDialogData_SetPrintData 2431 -#define wxPrintDialogData_SetPrintToFile 2432 -#define wxPrintDialogData_SetSelection 2433 -#define wxPrintDialogData_SetToPage 2434 -#define wxPrintData_new_0 2435 -#define wxPrintData_new_1 2436 -#define wxPrintData_destruct 2437 -#define wxPrintData_GetCollate 2438 -#define wxPrintData_GetBin 2439 -#define wxPrintData_GetColour 2440 -#define wxPrintData_GetDuplex 2441 -#define wxPrintData_GetNoCopies 2442 -#define wxPrintData_GetOrientation 2443 -#define wxPrintData_GetPaperId 2444 -#define wxPrintData_GetPrinterName 2445 -#define wxPrintData_GetQuality 2446 -#define wxPrintData_IsOk 2447 -#define wxPrintData_SetBin 2448 -#define wxPrintData_SetCollate 2449 -#define wxPrintData_SetColour 2450 -#define wxPrintData_SetDuplex 2451 -#define wxPrintData_SetNoCopies 2452 -#define wxPrintData_SetOrientation 2453 -#define wxPrintData_SetPaperId 2454 -#define wxPrintData_SetPrinterName 2455 -#define wxPrintData_SetQuality 2456 -#define wxPrintPreview_new_2 2459 -#define wxPrintPreview_new_3 2460 -#define wxPrintPreview_destruct 2462 -#define wxPrintPreview_GetCanvas 2463 -#define wxPrintPreview_GetCurrentPage 2464 -#define wxPrintPreview_GetFrame 2465 -#define wxPrintPreview_GetMaxPage 2466 -#define wxPrintPreview_GetMinPage 2467 -#define wxPrintPreview_GetPrintout 2468 -#define wxPrintPreview_GetPrintoutForPrinting 2469 -#define wxPrintPreview_IsOk 2470 -#define wxPrintPreview_PaintPage 2471 -#define wxPrintPreview_Print 2472 -#define wxPrintPreview_RenderPage 2473 -#define wxPrintPreview_SetCanvas 2474 -#define wxPrintPreview_SetCurrentPage 2475 -#define wxPrintPreview_SetFrame 2476 -#define wxPrintPreview_SetPrintout 2477 -#define wxPrintPreview_SetZoom 2478 -#define wxPreviewFrame_new 2479 -#define wxPreviewFrame_destruct 2480 -#define wxPreviewFrame_CreateControlBar 2481 -#define wxPreviewFrame_CreateCanvas 2482 -#define wxPreviewFrame_Initialize 2483 -#define wxPreviewFrame_OnCloseWindow 2484 -#define wxPreviewControlBar_new 2485 -#define wxPreviewControlBar_destruct 2486 -#define wxPreviewControlBar_CreateButtons 2487 -#define wxPreviewControlBar_GetPrintPreview 2488 -#define wxPreviewControlBar_GetZoomControl 2489 -#define wxPreviewControlBar_SetZoomControl 2490 -#define wxPrinter_new 2492 -#define wxPrinter_CreateAbortWindow 2493 -#define wxPrinter_GetAbort 2494 -#define wxPrinter_GetLastError 2495 -#define wxPrinter_GetPrintDialogData 2496 -#define wxPrinter_Print 2497 -#define wxPrinter_PrintDialog 2498 -#define wxPrinter_ReportError 2499 -#define wxPrinter_Setup 2500 -#define wxPrinter_destroy 2501 -#define wxXmlResource_new_1 2502 -#define wxXmlResource_new_2 2503 -#define wxXmlResource_destruct 2504 -#define wxXmlResource_AttachUnknownControl 2505 -#define wxXmlResource_ClearHandlers 2506 -#define wxXmlResource_CompareVersion 2507 -#define wxXmlResource_Get 2508 -#define wxXmlResource_GetFlags 2509 -#define wxXmlResource_GetVersion 2510 -#define wxXmlResource_GetXRCID 2511 -#define wxXmlResource_InitAllHandlers 2512 -#define wxXmlResource_Load 2513 -#define wxXmlResource_LoadBitmap 2514 -#define wxXmlResource_LoadDialog_2 2515 -#define wxXmlResource_LoadDialog_3 2516 -#define wxXmlResource_LoadFrame_2 2517 -#define wxXmlResource_LoadFrame_3 2518 -#define wxXmlResource_LoadIcon 2519 -#define wxXmlResource_LoadMenu 2520 -#define wxXmlResource_LoadMenuBar_2 2521 -#define wxXmlResource_LoadMenuBar_1 2522 -#define wxXmlResource_LoadPanel_2 2523 -#define wxXmlResource_LoadPanel_3 2524 -#define wxXmlResource_LoadToolBar 2525 -#define wxXmlResource_Set 2526 -#define wxXmlResource_SetFlags 2527 -#define wxXmlResource_Unload 2528 -#define wxXmlResource_xrcctrl 2529 -#define wxHtmlEasyPrinting_new 2530 -#define wxHtmlEasyPrinting_destruct 2531 -#define wxHtmlEasyPrinting_GetPrintData 2532 -#define wxHtmlEasyPrinting_GetPageSetupData 2533 -#define wxHtmlEasyPrinting_PreviewFile 2534 -#define wxHtmlEasyPrinting_PreviewText 2535 -#define wxHtmlEasyPrinting_PrintFile 2536 -#define wxHtmlEasyPrinting_PrintText 2537 -#define wxHtmlEasyPrinting_PageSetup 2538 -#define wxHtmlEasyPrinting_SetFonts 2539 -#define wxHtmlEasyPrinting_SetHeader 2540 -#define wxHtmlEasyPrinting_SetFooter 2541 -#define wxGLCanvas_new_2 2543 -#define wxGLCanvas_new_3_1 2544 -#define wxGLCanvas_new_3_0 2545 -#define wxGLCanvas_GetContext 2546 -#define wxGLCanvas_SetCurrent 2548 -#define wxGLCanvas_SwapBuffers 2549 -#define wxGLCanvas_destroy 2550 -#define wxAuiManager_new 2551 -#define wxAuiManager_destruct 2552 -#define wxAuiManager_AddPane_2_1 2553 -#define wxAuiManager_AddPane_3 2554 -#define wxAuiManager_AddPane_2_0 2555 -#define wxAuiManager_DetachPane 2556 -#define wxAuiManager_GetAllPanes 2557 -#define wxAuiManager_GetArtProvider 2558 -#define wxAuiManager_GetDockSizeConstraint 2559 -#define wxAuiManager_GetFlags 2560 -#define wxAuiManager_GetManagedWindow 2561 -#define wxAuiManager_GetManager 2562 -#define wxAuiManager_GetPane_1_1 2563 -#define wxAuiManager_GetPane_1_0 2564 -#define wxAuiManager_HideHint 2565 -#define wxAuiManager_InsertPane 2566 -#define wxAuiManager_LoadPaneInfo 2567 -#define wxAuiManager_LoadPerspective 2568 -#define wxAuiManager_SavePaneInfo 2569 -#define wxAuiManager_SavePerspective 2570 -#define wxAuiManager_SetArtProvider 2571 -#define wxAuiManager_SetDockSizeConstraint 2572 -#define wxAuiManager_SetFlags 2573 -#define wxAuiManager_SetManagedWindow 2574 -#define wxAuiManager_ShowHint 2575 -#define wxAuiManager_UnInit 2576 -#define wxAuiManager_Update 2577 -#define wxAuiPaneInfo_new_0 2578 -#define wxAuiPaneInfo_new_1 2579 -#define wxAuiPaneInfo_destruct 2580 -#define wxAuiPaneInfo_BestSize_1 2581 -#define wxAuiPaneInfo_BestSize_2 2582 -#define wxAuiPaneInfo_Bottom 2583 -#define wxAuiPaneInfo_BottomDockable 2584 -#define wxAuiPaneInfo_Caption 2585 -#define wxAuiPaneInfo_CaptionVisible 2586 -#define wxAuiPaneInfo_Centre 2587 -#define wxAuiPaneInfo_CentrePane 2588 -#define wxAuiPaneInfo_CloseButton 2589 -#define wxAuiPaneInfo_DefaultPane 2590 -#define wxAuiPaneInfo_DestroyOnClose 2591 -#define wxAuiPaneInfo_Direction 2592 -#define wxAuiPaneInfo_Dock 2593 -#define wxAuiPaneInfo_Dockable 2594 -#define wxAuiPaneInfo_Fixed 2595 -#define wxAuiPaneInfo_Float 2596 -#define wxAuiPaneInfo_Floatable 2597 -#define wxAuiPaneInfo_FloatingPosition_1 2598 -#define wxAuiPaneInfo_FloatingPosition_2 2599 -#define wxAuiPaneInfo_FloatingSize_1 2600 -#define wxAuiPaneInfo_FloatingSize_2 2601 -#define wxAuiPaneInfo_Gripper 2602 -#define wxAuiPaneInfo_GripperTop 2603 -#define wxAuiPaneInfo_HasBorder 2604 -#define wxAuiPaneInfo_HasCaption 2605 -#define wxAuiPaneInfo_HasCloseButton 2606 -#define wxAuiPaneInfo_HasFlag 2607 -#define wxAuiPaneInfo_HasGripper 2608 -#define wxAuiPaneInfo_HasGripperTop 2609 -#define wxAuiPaneInfo_HasMaximizeButton 2610 -#define wxAuiPaneInfo_HasMinimizeButton 2611 -#define wxAuiPaneInfo_HasPinButton 2612 -#define wxAuiPaneInfo_Hide 2613 -#define wxAuiPaneInfo_IsBottomDockable 2614 -#define wxAuiPaneInfo_IsDocked 2615 -#define wxAuiPaneInfo_IsFixed 2616 -#define wxAuiPaneInfo_IsFloatable 2617 -#define wxAuiPaneInfo_IsFloating 2618 -#define wxAuiPaneInfo_IsLeftDockable 2619 -#define wxAuiPaneInfo_IsMovable 2620 -#define wxAuiPaneInfo_IsOk 2621 -#define wxAuiPaneInfo_IsResizable 2622 -#define wxAuiPaneInfo_IsRightDockable 2623 -#define wxAuiPaneInfo_IsShown 2624 -#define wxAuiPaneInfo_IsToolbar 2625 -#define wxAuiPaneInfo_IsTopDockable 2626 -#define wxAuiPaneInfo_Layer 2627 -#define wxAuiPaneInfo_Left 2628 -#define wxAuiPaneInfo_LeftDockable 2629 -#define wxAuiPaneInfo_MaxSize_1 2630 -#define wxAuiPaneInfo_MaxSize_2 2631 -#define wxAuiPaneInfo_MaximizeButton 2632 -#define wxAuiPaneInfo_MinSize_1 2633 -#define wxAuiPaneInfo_MinSize_2 2634 -#define wxAuiPaneInfo_MinimizeButton 2635 -#define wxAuiPaneInfo_Movable 2636 -#define wxAuiPaneInfo_Name 2637 -#define wxAuiPaneInfo_PaneBorder 2638 -#define wxAuiPaneInfo_PinButton 2639 -#define wxAuiPaneInfo_Position 2640 -#define wxAuiPaneInfo_Resizable 2641 -#define wxAuiPaneInfo_Right 2642 -#define wxAuiPaneInfo_RightDockable 2643 -#define wxAuiPaneInfo_Row 2644 -#define wxAuiPaneInfo_SafeSet 2645 -#define wxAuiPaneInfo_SetFlag 2646 -#define wxAuiPaneInfo_Show 2647 -#define wxAuiPaneInfo_ToolbarPane 2648 -#define wxAuiPaneInfo_Top 2649 -#define wxAuiPaneInfo_TopDockable 2650 -#define wxAuiPaneInfo_Window 2651 -#define wxAuiNotebook_new_0 2652 -#define wxAuiNotebook_new_2 2653 -#define wxAuiNotebook_AddPage 2654 -#define wxAuiNotebook_Create 2655 -#define wxAuiNotebook_DeletePage 2656 -#define wxAuiNotebook_GetArtProvider 2657 -#define wxAuiNotebook_GetPage 2658 -#define wxAuiNotebook_GetPageBitmap 2659 -#define wxAuiNotebook_GetPageCount 2660 -#define wxAuiNotebook_GetPageIndex 2661 -#define wxAuiNotebook_GetPageText 2662 -#define wxAuiNotebook_GetSelection 2663 -#define wxAuiNotebook_InsertPage 2664 -#define wxAuiNotebook_RemovePage 2665 -#define wxAuiNotebook_SetArtProvider 2666 -#define wxAuiNotebook_SetFont 2667 -#define wxAuiNotebook_SetPageBitmap 2668 -#define wxAuiNotebook_SetPageText 2669 -#define wxAuiNotebook_SetSelection 2670 -#define wxAuiNotebook_SetTabCtrlHeight 2671 -#define wxAuiNotebook_SetUniformBitmapSize 2672 -#define wxAuiNotebook_destroy 2673 -#define wxMDIParentFrame_new_0 2674 -#define wxMDIParentFrame_new_4 2675 -#define wxMDIParentFrame_destruct 2676 -#define wxMDIParentFrame_ActivateNext 2677 -#define wxMDIParentFrame_ActivatePrevious 2678 -#define wxMDIParentFrame_ArrangeIcons 2679 -#define wxMDIParentFrame_Cascade 2680 -#define wxMDIParentFrame_Create 2681 -#define wxMDIParentFrame_GetActiveChild 2682 -#define wxMDIParentFrame_GetClientWindow 2683 -#define wxMDIParentFrame_Tile 2684 -#define wxMDIChildFrame_new_0 2685 -#define wxMDIChildFrame_new_4 2686 -#define wxMDIChildFrame_destruct 2687 -#define wxMDIChildFrame_Activate 2688 -#define wxMDIChildFrame_Create 2689 -#define wxMDIChildFrame_Maximize 2690 -#define wxMDIChildFrame_Restore 2691 -#define wxMDIClientWindow_new_0 2692 -#define wxMDIClientWindow_new_2 2693 -#define wxMDIClientWindow_destruct 2694 -#define wxMDIClientWindow_CreateClient 2695 -#define wxLayoutAlgorithm_new 2696 -#define wxLayoutAlgorithm_LayoutFrame 2697 -#define wxLayoutAlgorithm_LayoutMDIFrame 2698 -#define wxLayoutAlgorithm_LayoutWindow 2699 -#define wxLayoutAlgorithm_destroy 2700 -#define wxEvent_GetId 2701 -#define wxEvent_GetSkipped 2702 -#define wxEvent_GetTimestamp 2703 -#define wxEvent_IsCommandEvent 2704 -#define wxEvent_ResumePropagation 2705 -#define wxEvent_ShouldPropagate 2706 -#define wxEvent_Skip 2707 -#define wxEvent_StopPropagation 2708 -#define wxCommandEvent_getClientData 2709 -#define wxCommandEvent_GetExtraLong 2710 -#define wxCommandEvent_GetInt 2711 -#define wxCommandEvent_GetSelection 2712 -#define wxCommandEvent_GetString 2713 -#define wxCommandEvent_IsChecked 2714 -#define wxCommandEvent_IsSelection 2715 -#define wxCommandEvent_SetInt 2716 -#define wxCommandEvent_SetString 2717 -#define wxScrollEvent_GetOrientation 2718 -#define wxScrollEvent_GetPosition 2719 -#define wxScrollWinEvent_GetOrientation 2720 -#define wxScrollWinEvent_GetPosition 2721 -#define wxMouseEvent_AltDown 2722 -#define wxMouseEvent_Button 2723 -#define wxMouseEvent_ButtonDClick 2724 -#define wxMouseEvent_ButtonDown 2725 -#define wxMouseEvent_ButtonUp 2726 -#define wxMouseEvent_CmdDown 2727 -#define wxMouseEvent_ControlDown 2728 -#define wxMouseEvent_Dragging 2729 -#define wxMouseEvent_Entering 2730 -#define wxMouseEvent_GetButton 2731 -#define wxMouseEvent_GetPosition 2734 -#define wxMouseEvent_GetLogicalPosition 2735 -#define wxMouseEvent_GetLinesPerAction 2736 -#define wxMouseEvent_GetWheelRotation 2737 -#define wxMouseEvent_GetWheelDelta 2738 -#define wxMouseEvent_GetX 2739 -#define wxMouseEvent_GetY 2740 -#define wxMouseEvent_IsButton 2741 -#define wxMouseEvent_IsPageScroll 2742 -#define wxMouseEvent_Leaving 2743 -#define wxMouseEvent_LeftDClick 2744 -#define wxMouseEvent_LeftDown 2745 -#define wxMouseEvent_LeftIsDown 2746 -#define wxMouseEvent_LeftUp 2747 -#define wxMouseEvent_MetaDown 2748 -#define wxMouseEvent_MiddleDClick 2749 -#define wxMouseEvent_MiddleDown 2750 -#define wxMouseEvent_MiddleIsDown 2751 -#define wxMouseEvent_MiddleUp 2752 -#define wxMouseEvent_Moving 2753 -#define wxMouseEvent_RightDClick 2754 -#define wxMouseEvent_RightDown 2755 -#define wxMouseEvent_RightIsDown 2756 -#define wxMouseEvent_RightUp 2757 -#define wxMouseEvent_ShiftDown 2758 -#define wxSetCursorEvent_GetCursor 2759 -#define wxSetCursorEvent_GetX 2760 -#define wxSetCursorEvent_GetY 2761 -#define wxSetCursorEvent_HasCursor 2762 -#define wxSetCursorEvent_SetCursor 2763 -#define wxKeyEvent_AltDown 2764 -#define wxKeyEvent_CmdDown 2765 -#define wxKeyEvent_ControlDown 2766 -#define wxKeyEvent_GetKeyCode 2767 -#define wxKeyEvent_GetModifiers 2768 -#define wxKeyEvent_GetPosition 2771 -#define wxKeyEvent_GetRawKeyCode 2772 -#define wxKeyEvent_GetRawKeyFlags 2773 -#define wxKeyEvent_GetUnicodeKey 2774 -#define wxKeyEvent_GetX 2775 -#define wxKeyEvent_GetY 2776 -#define wxKeyEvent_HasModifiers 2777 -#define wxKeyEvent_MetaDown 2778 -#define wxKeyEvent_ShiftDown 2779 -#define wxSizeEvent_GetSize 2780 -#define wxMoveEvent_GetPosition 2781 -#define wxEraseEvent_GetDC 2782 -#define wxFocusEvent_GetWindow 2783 -#define wxChildFocusEvent_GetWindow 2784 -#define wxMenuEvent_GetMenu 2785 -#define wxMenuEvent_GetMenuId 2786 -#define wxMenuEvent_IsPopup 2787 -#define wxCloseEvent_CanVeto 2788 -#define wxCloseEvent_GetLoggingOff 2789 -#define wxCloseEvent_SetCanVeto 2790 -#define wxCloseEvent_SetLoggingOff 2791 -#define wxCloseEvent_Veto 2792 -#define wxShowEvent_SetShow 2793 -#define wxShowEvent_GetShow 2794 -#define wxIconizeEvent_Iconized 2795 -#define wxJoystickEvent_ButtonDown 2796 -#define wxJoystickEvent_ButtonIsDown 2797 -#define wxJoystickEvent_ButtonUp 2798 -#define wxJoystickEvent_GetButtonChange 2799 -#define wxJoystickEvent_GetButtonState 2800 -#define wxJoystickEvent_GetJoystick 2801 -#define wxJoystickEvent_GetPosition 2802 -#define wxJoystickEvent_GetZPosition 2803 -#define wxJoystickEvent_IsButton 2804 -#define wxJoystickEvent_IsMove 2805 -#define wxJoystickEvent_IsZMove 2806 -#define wxUpdateUIEvent_CanUpdate 2807 -#define wxUpdateUIEvent_Check 2808 -#define wxUpdateUIEvent_Enable 2809 -#define wxUpdateUIEvent_Show 2810 -#define wxUpdateUIEvent_GetChecked 2811 -#define wxUpdateUIEvent_GetEnabled 2812 -#define wxUpdateUIEvent_GetShown 2813 -#define wxUpdateUIEvent_GetSetChecked 2814 -#define wxUpdateUIEvent_GetSetEnabled 2815 -#define wxUpdateUIEvent_GetSetShown 2816 -#define wxUpdateUIEvent_GetSetText 2817 -#define wxUpdateUIEvent_GetText 2818 -#define wxUpdateUIEvent_GetMode 2819 -#define wxUpdateUIEvent_GetUpdateInterval 2820 -#define wxUpdateUIEvent_ResetUpdateTime 2821 -#define wxUpdateUIEvent_SetMode 2822 -#define wxUpdateUIEvent_SetText 2823 -#define wxUpdateUIEvent_SetUpdateInterval 2824 -#define wxMouseCaptureChangedEvent_GetCapturedWindow 2825 -#define wxPaletteChangedEvent_SetChangedWindow 2826 -#define wxPaletteChangedEvent_GetChangedWindow 2827 -#define wxQueryNewPaletteEvent_SetPaletteRealized 2828 -#define wxQueryNewPaletteEvent_GetPaletteRealized 2829 -#define wxNavigationKeyEvent_GetDirection 2830 -#define wxNavigationKeyEvent_SetDirection 2831 -#define wxNavigationKeyEvent_IsWindowChange 2832 -#define wxNavigationKeyEvent_SetWindowChange 2833 -#define wxNavigationKeyEvent_IsFromTab 2834 -#define wxNavigationKeyEvent_SetFromTab 2835 -#define wxNavigationKeyEvent_GetCurrentFocus 2836 -#define wxNavigationKeyEvent_SetCurrentFocus 2837 -#define wxHelpEvent_GetOrigin 2838 -#define wxHelpEvent_GetPosition 2839 -#define wxHelpEvent_SetOrigin 2840 -#define wxHelpEvent_SetPosition 2841 -#define wxContextMenuEvent_GetPosition 2842 -#define wxContextMenuEvent_SetPosition 2843 -#define wxIdleEvent_CanSend 2844 -#define wxIdleEvent_GetMode 2845 -#define wxIdleEvent_RequestMore 2846 -#define wxIdleEvent_MoreRequested 2847 -#define wxIdleEvent_SetMode 2848 -#define wxGridEvent_AltDown 2849 -#define wxGridEvent_ControlDown 2850 -#define wxGridEvent_GetCol 2851 -#define wxGridEvent_GetPosition 2852 -#define wxGridEvent_GetRow 2853 -#define wxGridEvent_MetaDown 2854 -#define wxGridEvent_Selecting 2855 -#define wxGridEvent_ShiftDown 2856 -#define wxNotifyEvent_Allow 2857 -#define wxNotifyEvent_IsAllowed 2858 -#define wxNotifyEvent_Veto 2859 -#define wxSashEvent_GetEdge 2860 -#define wxSashEvent_GetDragRect 2861 -#define wxSashEvent_GetDragStatus 2862 -#define wxListEvent_GetCacheFrom 2863 -#define wxListEvent_GetCacheTo 2864 -#define wxListEvent_GetKeyCode 2865 -#define wxListEvent_GetIndex 2866 -#define wxListEvent_GetColumn 2867 -#define wxListEvent_GetPoint 2868 -#define wxListEvent_GetLabel 2869 -#define wxListEvent_GetText 2870 -#define wxListEvent_GetImage 2871 -#define wxListEvent_GetData 2872 -#define wxListEvent_GetMask 2873 -#define wxListEvent_GetItem 2874 -#define wxListEvent_IsEditCancelled 2875 -#define wxDateEvent_GetDate 2876 -#define wxCalendarEvent_GetWeekDay 2877 -#define wxFileDirPickerEvent_GetPath 2878 -#define wxColourPickerEvent_GetColour 2879 -#define wxFontPickerEvent_GetFont 2880 -#define wxStyledTextEvent_GetPosition 2881 -#define wxStyledTextEvent_GetKey 2882 -#define wxStyledTextEvent_GetModifiers 2883 -#define wxStyledTextEvent_GetModificationType 2884 -#define wxStyledTextEvent_GetText 2885 -#define wxStyledTextEvent_GetLength 2886 -#define wxStyledTextEvent_GetLinesAdded 2887 -#define wxStyledTextEvent_GetLine 2888 -#define wxStyledTextEvent_GetFoldLevelNow 2889 -#define wxStyledTextEvent_GetFoldLevelPrev 2890 -#define wxStyledTextEvent_GetMargin 2891 -#define wxStyledTextEvent_GetMessage 2892 -#define wxStyledTextEvent_GetWParam 2893 -#define wxStyledTextEvent_GetLParam 2894 -#define wxStyledTextEvent_GetListType 2895 -#define wxStyledTextEvent_GetX 2896 -#define wxStyledTextEvent_GetY 2897 -#define wxStyledTextEvent_GetDragText 2898 -#define wxStyledTextEvent_GetDragAllowMove 2899 -#define wxStyledTextEvent_GetDragResult 2900 -#define wxStyledTextEvent_GetShift 2901 -#define wxStyledTextEvent_GetControl 2902 -#define wxStyledTextEvent_GetAlt 2903 -#define utils_wxGetKeyState 2904 -#define utils_wxGetMousePosition 2905 -#define utils_wxGetMouseState 2906 -#define utils_wxSetDetectableAutoRepeat 2907 -#define utils_wxBell 2908 -#define utils_wxFindMenuItemId 2909 -#define utils_wxGenericFindWindowAtPoint 2910 -#define utils_wxFindWindowAtPoint 2911 -#define utils_wxBeginBusyCursor 2912 -#define utils_wxEndBusyCursor 2913 -#define utils_wxIsBusy 2914 -#define utils_wxShutdown 2915 -#define utils_wxShell 2916 -#define utils_wxLaunchDefaultBrowser 2917 -#define utils_wxGetEmailAddress 2918 -#define utils_wxGetUserId 2919 -#define utils_wxGetHomeDir 2920 -#define utils_wxNewId 2921 -#define utils_wxRegisterId 2922 -#define utils_wxGetCurrentId 2923 -#define utils_wxGetOsDescription 2924 -#define utils_wxIsPlatformLittleEndian 2925 -#define utils_wxIsPlatform64Bit 2926 -#define wxPrintout_new 2927 -#define wxPrintout_destruct 2928 -#define wxPrintout_GetDC 2929 -#define wxPrintout_GetPageSizeMM 2930 -#define wxPrintout_GetPageSizePixels 2931 -#define wxPrintout_GetPaperRectPixels 2932 -#define wxPrintout_GetPPIPrinter 2933 -#define wxPrintout_GetPPIScreen 2934 -#define wxPrintout_GetTitle 2935 -#define wxPrintout_IsPreview 2936 -#define wxPrintout_FitThisSizeToPaper 2937 -#define wxPrintout_FitThisSizeToPage 2938 -#define wxPrintout_FitThisSizeToPageMargins 2939 -#define wxPrintout_MapScreenSizeToPaper 2940 -#define wxPrintout_MapScreenSizeToPage 2941 -#define wxPrintout_MapScreenSizeToPageMargins 2942 -#define wxPrintout_MapScreenSizeToDevice 2943 -#define wxPrintout_GetLogicalPaperRect 2944 -#define wxPrintout_GetLogicalPageRect 2945 -#define wxPrintout_GetLogicalPageMarginsRect 2946 -#define wxPrintout_SetLogicalOrigin 2947 -#define wxPrintout_OffsetLogicalOrigin 2948 -#define wxStyledTextCtrl_new_2 2949 -#define wxStyledTextCtrl_new_0 2950 -#define wxStyledTextCtrl_destruct 2951 -#define wxStyledTextCtrl_Create 2952 -#define wxStyledTextCtrl_AddText 2953 -#define wxStyledTextCtrl_AddStyledText 2954 -#define wxStyledTextCtrl_InsertText 2955 -#define wxStyledTextCtrl_ClearAll 2956 -#define wxStyledTextCtrl_ClearDocumentStyle 2957 -#define wxStyledTextCtrl_GetLength 2958 -#define wxStyledTextCtrl_GetCharAt 2959 -#define wxStyledTextCtrl_GetCurrentPos 2960 -#define wxStyledTextCtrl_GetAnchor 2961 -#define wxStyledTextCtrl_GetStyleAt 2962 -#define wxStyledTextCtrl_Redo 2963 -#define wxStyledTextCtrl_SetUndoCollection 2964 -#define wxStyledTextCtrl_SelectAll 2965 -#define wxStyledTextCtrl_SetSavePoint 2966 -#define wxStyledTextCtrl_GetStyledText 2967 -#define wxStyledTextCtrl_CanRedo 2968 -#define wxStyledTextCtrl_MarkerLineFromHandle 2969 -#define wxStyledTextCtrl_MarkerDeleteHandle 2970 -#define wxStyledTextCtrl_GetUndoCollection 2971 -#define wxStyledTextCtrl_GetViewWhiteSpace 2972 -#define wxStyledTextCtrl_SetViewWhiteSpace 2973 -#define wxStyledTextCtrl_PositionFromPoint 2974 -#define wxStyledTextCtrl_PositionFromPointClose 2975 -#define wxStyledTextCtrl_GotoLine 2976 -#define wxStyledTextCtrl_GotoPos 2977 -#define wxStyledTextCtrl_SetAnchor 2978 -#define wxStyledTextCtrl_GetCurLine 2979 -#define wxStyledTextCtrl_GetEndStyled 2980 -#define wxStyledTextCtrl_ConvertEOLs 2981 -#define wxStyledTextCtrl_GetEOLMode 2982 -#define wxStyledTextCtrl_SetEOLMode 2983 -#define wxStyledTextCtrl_StartStyling 2984 -#define wxStyledTextCtrl_SetStyling 2985 -#define wxStyledTextCtrl_GetBufferedDraw 2986 -#define wxStyledTextCtrl_SetBufferedDraw 2987 -#define wxStyledTextCtrl_SetTabWidth 2988 -#define wxStyledTextCtrl_GetTabWidth 2989 -#define wxStyledTextCtrl_SetCodePage 2990 -#define wxStyledTextCtrl_MarkerDefine 2991 -#define wxStyledTextCtrl_MarkerSetForeground 2992 -#define wxStyledTextCtrl_MarkerSetBackground 2993 -#define wxStyledTextCtrl_MarkerAdd 2994 -#define wxStyledTextCtrl_MarkerDelete 2995 -#define wxStyledTextCtrl_MarkerDeleteAll 2996 -#define wxStyledTextCtrl_MarkerGet 2997 -#define wxStyledTextCtrl_MarkerNext 2998 -#define wxStyledTextCtrl_MarkerPrevious 2999 -#define wxStyledTextCtrl_MarkerDefineBitmap 3000 -#define wxStyledTextCtrl_MarkerAddSet 3001 -#define wxStyledTextCtrl_MarkerSetAlpha 3002 -#define wxStyledTextCtrl_SetMarginType 3003 -#define wxStyledTextCtrl_GetMarginType 3004 -#define wxStyledTextCtrl_SetMarginWidth 3005 -#define wxStyledTextCtrl_GetMarginWidth 3006 -#define wxStyledTextCtrl_SetMarginMask 3007 -#define wxStyledTextCtrl_GetMarginMask 3008 -#define wxStyledTextCtrl_SetMarginSensitive 3009 -#define wxStyledTextCtrl_GetMarginSensitive 3010 -#define wxStyledTextCtrl_StyleClearAll 3011 -#define wxStyledTextCtrl_StyleSetForeground 3012 -#define wxStyledTextCtrl_StyleSetBackground 3013 -#define wxStyledTextCtrl_StyleSetBold 3014 -#define wxStyledTextCtrl_StyleSetItalic 3015 -#define wxStyledTextCtrl_StyleSetSize 3016 -#define wxStyledTextCtrl_StyleSetFaceName 3017 -#define wxStyledTextCtrl_StyleSetEOLFilled 3018 -#define wxStyledTextCtrl_StyleResetDefault 3019 -#define wxStyledTextCtrl_StyleSetUnderline 3020 -#define wxStyledTextCtrl_StyleSetCase 3021 -#define wxStyledTextCtrl_StyleSetHotSpot 3022 -#define wxStyledTextCtrl_SetSelForeground 3023 -#define wxStyledTextCtrl_SetSelBackground 3024 -#define wxStyledTextCtrl_GetSelAlpha 3025 -#define wxStyledTextCtrl_SetSelAlpha 3026 -#define wxStyledTextCtrl_SetCaretForeground 3027 -#define wxStyledTextCtrl_CmdKeyAssign 3028 -#define wxStyledTextCtrl_CmdKeyClear 3029 -#define wxStyledTextCtrl_CmdKeyClearAll 3030 -#define wxStyledTextCtrl_SetStyleBytes 3031 -#define wxStyledTextCtrl_StyleSetVisible 3032 -#define wxStyledTextCtrl_GetCaretPeriod 3033 -#define wxStyledTextCtrl_SetCaretPeriod 3034 -#define wxStyledTextCtrl_SetWordChars 3035 -#define wxStyledTextCtrl_BeginUndoAction 3036 -#define wxStyledTextCtrl_EndUndoAction 3037 -#define wxStyledTextCtrl_IndicatorSetStyle 3038 -#define wxStyledTextCtrl_IndicatorGetStyle 3039 -#define wxStyledTextCtrl_IndicatorSetForeground 3040 -#define wxStyledTextCtrl_IndicatorGetForeground 3041 -#define wxStyledTextCtrl_SetWhitespaceForeground 3042 -#define wxStyledTextCtrl_SetWhitespaceBackground 3043 -#define wxStyledTextCtrl_GetStyleBits 3044 -#define wxStyledTextCtrl_SetLineState 3045 -#define wxStyledTextCtrl_GetLineState 3046 -#define wxStyledTextCtrl_GetMaxLineState 3047 -#define wxStyledTextCtrl_GetCaretLineVisible 3048 -#define wxStyledTextCtrl_SetCaretLineVisible 3049 -#define wxStyledTextCtrl_GetCaretLineBackground 3050 -#define wxStyledTextCtrl_SetCaretLineBackground 3051 -#define wxStyledTextCtrl_AutoCompShow 3052 -#define wxStyledTextCtrl_AutoCompCancel 3053 -#define wxStyledTextCtrl_AutoCompActive 3054 -#define wxStyledTextCtrl_AutoCompPosStart 3055 -#define wxStyledTextCtrl_AutoCompComplete 3056 -#define wxStyledTextCtrl_AutoCompStops 3057 -#define wxStyledTextCtrl_AutoCompSetSeparator 3058 -#define wxStyledTextCtrl_AutoCompGetSeparator 3059 -#define wxStyledTextCtrl_AutoCompSelect 3060 -#define wxStyledTextCtrl_AutoCompSetCancelAtStart 3061 -#define wxStyledTextCtrl_AutoCompGetCancelAtStart 3062 -#define wxStyledTextCtrl_AutoCompSetFillUps 3063 -#define wxStyledTextCtrl_AutoCompSetChooseSingle 3064 -#define wxStyledTextCtrl_AutoCompGetChooseSingle 3065 -#define wxStyledTextCtrl_AutoCompSetIgnoreCase 3066 -#define wxStyledTextCtrl_AutoCompGetIgnoreCase 3067 -#define wxStyledTextCtrl_UserListShow 3068 -#define wxStyledTextCtrl_AutoCompSetAutoHide 3069 -#define wxStyledTextCtrl_AutoCompGetAutoHide 3070 -#define wxStyledTextCtrl_AutoCompSetDropRestOfWord 3071 -#define wxStyledTextCtrl_AutoCompGetDropRestOfWord 3072 -#define wxStyledTextCtrl_RegisterImage 3073 -#define wxStyledTextCtrl_ClearRegisteredImages 3074 -#define wxStyledTextCtrl_AutoCompGetTypeSeparator 3075 -#define wxStyledTextCtrl_AutoCompSetTypeSeparator 3076 -#define wxStyledTextCtrl_AutoCompSetMaxWidth 3077 -#define wxStyledTextCtrl_AutoCompGetMaxWidth 3078 -#define wxStyledTextCtrl_AutoCompSetMaxHeight 3079 -#define wxStyledTextCtrl_AutoCompGetMaxHeight 3080 -#define wxStyledTextCtrl_SetIndent 3081 -#define wxStyledTextCtrl_GetIndent 3082 -#define wxStyledTextCtrl_SetUseTabs 3083 -#define wxStyledTextCtrl_GetUseTabs 3084 -#define wxStyledTextCtrl_SetLineIndentation 3085 -#define wxStyledTextCtrl_GetLineIndentation 3086 -#define wxStyledTextCtrl_GetLineIndentPosition 3087 -#define wxStyledTextCtrl_GetColumn 3088 -#define wxStyledTextCtrl_SetUseHorizontalScrollBar 3089 -#define wxStyledTextCtrl_GetUseHorizontalScrollBar 3090 -#define wxStyledTextCtrl_SetIndentationGuides 3091 -#define wxStyledTextCtrl_GetIndentationGuides 3092 -#define wxStyledTextCtrl_SetHighlightGuide 3093 -#define wxStyledTextCtrl_GetHighlightGuide 3094 -#define wxStyledTextCtrl_GetLineEndPosition 3095 -#define wxStyledTextCtrl_GetCodePage 3096 -#define wxStyledTextCtrl_GetCaretForeground 3097 -#define wxStyledTextCtrl_GetReadOnly 3098 -#define wxStyledTextCtrl_SetCurrentPos 3099 -#define wxStyledTextCtrl_SetSelectionStart 3100 -#define wxStyledTextCtrl_GetSelectionStart 3101 -#define wxStyledTextCtrl_SetSelectionEnd 3102 -#define wxStyledTextCtrl_GetSelectionEnd 3103 -#define wxStyledTextCtrl_SetPrintMagnification 3104 -#define wxStyledTextCtrl_GetPrintMagnification 3105 -#define wxStyledTextCtrl_SetPrintColourMode 3106 -#define wxStyledTextCtrl_GetPrintColourMode 3107 -#define wxStyledTextCtrl_FindText 3108 -#define wxStyledTextCtrl_FormatRange 3109 -#define wxStyledTextCtrl_GetFirstVisibleLine 3110 -#define wxStyledTextCtrl_GetLine 3111 -#define wxStyledTextCtrl_GetLineCount 3112 -#define wxStyledTextCtrl_SetMarginLeft 3113 -#define wxStyledTextCtrl_GetMarginLeft 3114 -#define wxStyledTextCtrl_SetMarginRight 3115 -#define wxStyledTextCtrl_GetMarginRight 3116 -#define wxStyledTextCtrl_GetModify 3117 -#define wxStyledTextCtrl_SetSelection 3118 -#define wxStyledTextCtrl_GetSelectedText 3119 -#define wxStyledTextCtrl_GetTextRange 3120 -#define wxStyledTextCtrl_HideSelection 3121 -#define wxStyledTextCtrl_LineFromPosition 3122 -#define wxStyledTextCtrl_PositionFromLine 3123 -#define wxStyledTextCtrl_LineScroll 3124 -#define wxStyledTextCtrl_EnsureCaretVisible 3125 -#define wxStyledTextCtrl_ReplaceSelection 3126 -#define wxStyledTextCtrl_SetReadOnly 3127 -#define wxStyledTextCtrl_CanPaste 3128 -#define wxStyledTextCtrl_CanUndo 3129 -#define wxStyledTextCtrl_EmptyUndoBuffer 3130 -#define wxStyledTextCtrl_Undo 3131 -#define wxStyledTextCtrl_Cut 3132 -#define wxStyledTextCtrl_Copy 3133 -#define wxStyledTextCtrl_Paste 3134 -#define wxStyledTextCtrl_Clear 3135 -#define wxStyledTextCtrl_SetText 3136 -#define wxStyledTextCtrl_GetText 3137 -#define wxStyledTextCtrl_GetTextLength 3138 -#define wxStyledTextCtrl_GetOvertype 3139 -#define wxStyledTextCtrl_SetCaretWidth 3140 -#define wxStyledTextCtrl_GetCaretWidth 3141 -#define wxStyledTextCtrl_SetTargetStart 3142 -#define wxStyledTextCtrl_GetTargetStart 3143 -#define wxStyledTextCtrl_SetTargetEnd 3144 -#define wxStyledTextCtrl_GetTargetEnd 3145 -#define wxStyledTextCtrl_ReplaceTarget 3146 -#define wxStyledTextCtrl_SearchInTarget 3147 -#define wxStyledTextCtrl_SetSearchFlags 3148 -#define wxStyledTextCtrl_GetSearchFlags 3149 -#define wxStyledTextCtrl_CallTipShow 3150 -#define wxStyledTextCtrl_CallTipCancel 3151 -#define wxStyledTextCtrl_CallTipActive 3152 -#define wxStyledTextCtrl_CallTipPosAtStart 3153 -#define wxStyledTextCtrl_CallTipSetHighlight 3154 -#define wxStyledTextCtrl_CallTipSetBackground 3155 -#define wxStyledTextCtrl_CallTipSetForeground 3156 -#define wxStyledTextCtrl_CallTipSetForegroundHighlight 3157 -#define wxStyledTextCtrl_CallTipUseStyle 3158 -#define wxStyledTextCtrl_VisibleFromDocLine 3159 -#define wxStyledTextCtrl_DocLineFromVisible 3160 -#define wxStyledTextCtrl_WrapCount 3161 -#define wxStyledTextCtrl_SetFoldLevel 3162 -#define wxStyledTextCtrl_GetFoldLevel 3163 -#define wxStyledTextCtrl_GetLastChild 3164 -#define wxStyledTextCtrl_GetFoldParent 3165 -#define wxStyledTextCtrl_ShowLines 3166 -#define wxStyledTextCtrl_HideLines 3167 -#define wxStyledTextCtrl_GetLineVisible 3168 -#define wxStyledTextCtrl_SetFoldExpanded 3169 -#define wxStyledTextCtrl_GetFoldExpanded 3170 -#define wxStyledTextCtrl_ToggleFold 3171 -#define wxStyledTextCtrl_EnsureVisible 3172 -#define wxStyledTextCtrl_SetFoldFlags 3173 -#define wxStyledTextCtrl_EnsureVisibleEnforcePolicy 3174 -#define wxStyledTextCtrl_SetTabIndents 3175 -#define wxStyledTextCtrl_GetTabIndents 3176 -#define wxStyledTextCtrl_SetBackSpaceUnIndents 3177 -#define wxStyledTextCtrl_GetBackSpaceUnIndents 3178 -#define wxStyledTextCtrl_SetMouseDwellTime 3179 -#define wxStyledTextCtrl_GetMouseDwellTime 3180 -#define wxStyledTextCtrl_WordStartPosition 3181 -#define wxStyledTextCtrl_WordEndPosition 3182 -#define wxStyledTextCtrl_SetWrapMode 3183 -#define wxStyledTextCtrl_GetWrapMode 3184 -#define wxStyledTextCtrl_SetWrapVisualFlags 3185 -#define wxStyledTextCtrl_GetWrapVisualFlags 3186 -#define wxStyledTextCtrl_SetWrapVisualFlagsLocation 3187 -#define wxStyledTextCtrl_GetWrapVisualFlagsLocation 3188 -#define wxStyledTextCtrl_SetWrapStartIndent 3189 -#define wxStyledTextCtrl_GetWrapStartIndent 3190 -#define wxStyledTextCtrl_SetLayoutCache 3191 -#define wxStyledTextCtrl_GetLayoutCache 3192 -#define wxStyledTextCtrl_SetScrollWidth 3193 -#define wxStyledTextCtrl_GetScrollWidth 3194 -#define wxStyledTextCtrl_TextWidth 3195 -#define wxStyledTextCtrl_GetEndAtLastLine 3196 -#define wxStyledTextCtrl_TextHeight 3197 -#define wxStyledTextCtrl_SetUseVerticalScrollBar 3198 -#define wxStyledTextCtrl_GetUseVerticalScrollBar 3199 -#define wxStyledTextCtrl_AppendText 3200 -#define wxStyledTextCtrl_GetTwoPhaseDraw 3201 -#define wxStyledTextCtrl_SetTwoPhaseDraw 3202 -#define wxStyledTextCtrl_TargetFromSelection 3203 -#define wxStyledTextCtrl_LinesJoin 3204 -#define wxStyledTextCtrl_LinesSplit 3205 -#define wxStyledTextCtrl_SetFoldMarginColour 3206 -#define wxStyledTextCtrl_SetFoldMarginHiColour 3207 -#define wxStyledTextCtrl_LineDown 3208 -#define wxStyledTextCtrl_LineDownExtend 3209 -#define wxStyledTextCtrl_LineUp 3210 -#define wxStyledTextCtrl_LineUpExtend 3211 -#define wxStyledTextCtrl_CharLeft 3212 -#define wxStyledTextCtrl_CharLeftExtend 3213 -#define wxStyledTextCtrl_CharRight 3214 -#define wxStyledTextCtrl_CharRightExtend 3215 -#define wxStyledTextCtrl_WordLeft 3216 -#define wxStyledTextCtrl_WordLeftExtend 3217 -#define wxStyledTextCtrl_WordRight 3218 -#define wxStyledTextCtrl_WordRightExtend 3219 -#define wxStyledTextCtrl_Home 3220 -#define wxStyledTextCtrl_HomeExtend 3221 -#define wxStyledTextCtrl_LineEnd 3222 -#define wxStyledTextCtrl_LineEndExtend 3223 -#define wxStyledTextCtrl_DocumentStart 3224 -#define wxStyledTextCtrl_DocumentStartExtend 3225 -#define wxStyledTextCtrl_DocumentEnd 3226 -#define wxStyledTextCtrl_DocumentEndExtend 3227 -#define wxStyledTextCtrl_PageUp 3228 -#define wxStyledTextCtrl_PageUpExtend 3229 -#define wxStyledTextCtrl_PageDown 3230 -#define wxStyledTextCtrl_PageDownExtend 3231 -#define wxStyledTextCtrl_EditToggleOvertype 3232 -#define wxStyledTextCtrl_Cancel 3233 -#define wxStyledTextCtrl_DeleteBack 3234 -#define wxStyledTextCtrl_Tab 3235 -#define wxStyledTextCtrl_BackTab 3236 -#define wxStyledTextCtrl_NewLine 3237 -#define wxStyledTextCtrl_FormFeed 3238 -#define wxStyledTextCtrl_VCHome 3239 -#define wxStyledTextCtrl_VCHomeExtend 3240 -#define wxStyledTextCtrl_ZoomIn 3241 -#define wxStyledTextCtrl_ZoomOut 3242 -#define wxStyledTextCtrl_DelWordLeft 3243 -#define wxStyledTextCtrl_DelWordRight 3244 -#define wxStyledTextCtrl_LineCut 3245 -#define wxStyledTextCtrl_LineDelete 3246 -#define wxStyledTextCtrl_LineTranspose 3247 -#define wxStyledTextCtrl_LineDuplicate 3248 -#define wxStyledTextCtrl_LowerCase 3249 -#define wxStyledTextCtrl_UpperCase 3250 -#define wxStyledTextCtrl_LineScrollDown 3251 -#define wxStyledTextCtrl_LineScrollUp 3252 -#define wxStyledTextCtrl_DeleteBackNotLine 3253 -#define wxStyledTextCtrl_HomeDisplay 3254 -#define wxStyledTextCtrl_HomeDisplayExtend 3255 -#define wxStyledTextCtrl_LineEndDisplay 3256 -#define wxStyledTextCtrl_LineEndDisplayExtend 3257 -#define wxStyledTextCtrl_HomeWrapExtend 3258 -#define wxStyledTextCtrl_LineEndWrap 3259 -#define wxStyledTextCtrl_LineEndWrapExtend 3260 -#define wxStyledTextCtrl_VCHomeWrap 3261 -#define wxStyledTextCtrl_VCHomeWrapExtend 3262 -#define wxStyledTextCtrl_LineCopy 3263 -#define wxStyledTextCtrl_MoveCaretInsideView 3264 -#define wxStyledTextCtrl_LineLength 3265 -#define wxStyledTextCtrl_BraceHighlight 3266 -#define wxStyledTextCtrl_BraceBadLight 3267 -#define wxStyledTextCtrl_BraceMatch 3268 -#define wxStyledTextCtrl_GetViewEOL 3269 -#define wxStyledTextCtrl_SetViewEOL 3270 -#define wxStyledTextCtrl_SetModEventMask 3271 -#define wxStyledTextCtrl_GetEdgeColumn 3272 -#define wxStyledTextCtrl_SetEdgeColumn 3273 -#define wxStyledTextCtrl_SetEdgeMode 3274 -#define wxStyledTextCtrl_GetEdgeMode 3275 -#define wxStyledTextCtrl_GetEdgeColour 3276 -#define wxStyledTextCtrl_SetEdgeColour 3277 -#define wxStyledTextCtrl_SearchAnchor 3278 -#define wxStyledTextCtrl_SearchNext 3279 -#define wxStyledTextCtrl_SearchPrev 3280 -#define wxStyledTextCtrl_LinesOnScreen 3281 -#define wxStyledTextCtrl_UsePopUp 3282 -#define wxStyledTextCtrl_SelectionIsRectangle 3283 -#define wxStyledTextCtrl_SetZoom 3284 -#define wxStyledTextCtrl_GetZoom 3285 -#define wxStyledTextCtrl_GetModEventMask 3286 -#define wxStyledTextCtrl_SetSTCFocus 3287 -#define wxStyledTextCtrl_GetSTCFocus 3288 -#define wxStyledTextCtrl_SetStatus 3289 -#define wxStyledTextCtrl_GetStatus 3290 -#define wxStyledTextCtrl_SetMouseDownCaptures 3291 -#define wxStyledTextCtrl_GetMouseDownCaptures 3292 -#define wxStyledTextCtrl_SetSTCCursor 3293 -#define wxStyledTextCtrl_GetSTCCursor 3294 -#define wxStyledTextCtrl_SetControlCharSymbol 3295 -#define wxStyledTextCtrl_GetControlCharSymbol 3296 -#define wxStyledTextCtrl_WordPartLeft 3297 -#define wxStyledTextCtrl_WordPartLeftExtend 3298 -#define wxStyledTextCtrl_WordPartRight 3299 -#define wxStyledTextCtrl_WordPartRightExtend 3300 -#define wxStyledTextCtrl_SetVisiblePolicy 3301 -#define wxStyledTextCtrl_DelLineLeft 3302 -#define wxStyledTextCtrl_DelLineRight 3303 -#define wxStyledTextCtrl_GetXOffset 3304 -#define wxStyledTextCtrl_ChooseCaretX 3305 -#define wxStyledTextCtrl_SetXCaretPolicy 3306 -#define wxStyledTextCtrl_SetYCaretPolicy 3307 -#define wxStyledTextCtrl_GetPrintWrapMode 3308 -#define wxStyledTextCtrl_SetHotspotActiveForeground 3309 -#define wxStyledTextCtrl_SetHotspotActiveBackground 3310 -#define wxStyledTextCtrl_SetHotspotActiveUnderline 3311 -#define wxStyledTextCtrl_SetHotspotSingleLine 3312 -#define wxStyledTextCtrl_ParaDownExtend 3313 -#define wxStyledTextCtrl_ParaUp 3314 -#define wxStyledTextCtrl_ParaUpExtend 3315 -#define wxStyledTextCtrl_PositionBefore 3316 -#define wxStyledTextCtrl_PositionAfter 3317 -#define wxStyledTextCtrl_CopyRange 3318 -#define wxStyledTextCtrl_CopyText 3319 -#define wxStyledTextCtrl_SetSelectionMode 3320 -#define wxStyledTextCtrl_GetSelectionMode 3321 -#define wxStyledTextCtrl_LineDownRectExtend 3322 -#define wxStyledTextCtrl_LineUpRectExtend 3323 -#define wxStyledTextCtrl_CharLeftRectExtend 3324 -#define wxStyledTextCtrl_CharRightRectExtend 3325 -#define wxStyledTextCtrl_HomeRectExtend 3326 -#define wxStyledTextCtrl_VCHomeRectExtend 3327 -#define wxStyledTextCtrl_LineEndRectExtend 3328 -#define wxStyledTextCtrl_PageUpRectExtend 3329 -#define wxStyledTextCtrl_PageDownRectExtend 3330 -#define wxStyledTextCtrl_StutteredPageUp 3331 -#define wxStyledTextCtrl_StutteredPageUpExtend 3332 -#define wxStyledTextCtrl_StutteredPageDown 3333 -#define wxStyledTextCtrl_StutteredPageDownExtend 3334 -#define wxStyledTextCtrl_WordLeftEnd 3335 -#define wxStyledTextCtrl_WordLeftEndExtend 3336 -#define wxStyledTextCtrl_WordRightEnd 3337 -#define wxStyledTextCtrl_WordRightEndExtend 3338 -#define wxStyledTextCtrl_SetWhitespaceChars 3339 -#define wxStyledTextCtrl_SetCharsDefault 3340 -#define wxStyledTextCtrl_AutoCompGetCurrent 3341 -#define wxStyledTextCtrl_Allocate 3342 -#define wxStyledTextCtrl_FindColumn 3343 -#define wxStyledTextCtrl_GetCaretSticky 3344 -#define wxStyledTextCtrl_SetCaretSticky 3345 -#define wxStyledTextCtrl_ToggleCaretSticky 3346 -#define wxStyledTextCtrl_SetPasteConvertEndings 3347 -#define wxStyledTextCtrl_GetPasteConvertEndings 3348 -#define wxStyledTextCtrl_SelectionDuplicate 3349 -#define wxStyledTextCtrl_SetCaretLineBackAlpha 3350 -#define wxStyledTextCtrl_GetCaretLineBackAlpha 3351 -#define wxStyledTextCtrl_StartRecord 3352 -#define wxStyledTextCtrl_StopRecord 3353 -#define wxStyledTextCtrl_SetLexer 3354 -#define wxStyledTextCtrl_GetLexer 3355 -#define wxStyledTextCtrl_Colourise 3356 -#define wxStyledTextCtrl_SetProperty 3357 -#define wxStyledTextCtrl_SetKeyWords 3358 -#define wxStyledTextCtrl_SetLexerLanguage 3359 -#define wxStyledTextCtrl_GetProperty 3360 -#define wxStyledTextCtrl_GetStyleBitsNeeded 3361 -#define wxStyledTextCtrl_GetCurrentLine 3362 -#define wxStyledTextCtrl_StyleSetSpec 3363 -#define wxStyledTextCtrl_StyleSetFont 3364 -#define wxStyledTextCtrl_StyleSetFontAttr 3365 -#define wxStyledTextCtrl_StyleSetCharacterSet 3366 -#define wxStyledTextCtrl_StyleSetFontEncoding 3367 -#define wxStyledTextCtrl_CmdKeyExecute 3368 -#define wxStyledTextCtrl_SetMargins 3369 -#define wxStyledTextCtrl_GetSelection 3370 -#define wxStyledTextCtrl_PointFromPosition 3371 -#define wxStyledTextCtrl_ScrollToLine 3372 -#define wxStyledTextCtrl_ScrollToColumn 3373 -#define wxStyledTextCtrl_SetVScrollBar 3374 -#define wxStyledTextCtrl_SetHScrollBar 3375 -#define wxStyledTextCtrl_GetLastKeydownProcessed 3376 -#define wxStyledTextCtrl_SetLastKeydownProcessed 3377 -#define wxStyledTextCtrl_SaveFile 3378 -#define wxStyledTextCtrl_LoadFile 3379 -#define wxStyledTextCtrl_DoDragOver 3380 -#define wxStyledTextCtrl_DoDropText 3381 -#define wxStyledTextCtrl_GetUseAntiAliasing 3382 -#define wxStyledTextCtrl_AddTextRaw 3383 -#define wxStyledTextCtrl_InsertTextRaw 3384 -#define wxStyledTextCtrl_GetCurLineRaw 3385 -#define wxStyledTextCtrl_GetLineRaw 3386 -#define wxStyledTextCtrl_GetSelectedTextRaw 3387 -#define wxStyledTextCtrl_GetTextRangeRaw 3388 -#define wxStyledTextCtrl_SetTextRaw 3389 -#define wxStyledTextCtrl_GetTextRaw 3390 -#define wxStyledTextCtrl_AppendTextRaw 3391 -#define wxArtProvider_GetBitmap 3392 -#define wxArtProvider_GetIcon 3393 -#define wxTreeEvent_GetKeyCode 3394 -#define wxTreeEvent_GetItem 3395 -#define wxTreeEvent_GetKeyEvent 3396 -#define wxTreeEvent_GetLabel 3397 -#define wxTreeEvent_GetOldItem 3398 -#define wxTreeEvent_GetPoint 3399 -#define wxTreeEvent_IsEditCancelled 3400 -#define wxTreeEvent_SetToolTip 3401 -#define wxNotebookEvent_GetOldSelection 3402 -#define wxNotebookEvent_GetSelection 3403 -#define wxNotebookEvent_SetOldSelection 3404 -#define wxNotebookEvent_SetSelection 3405 -#define wxFileDataObject_new 3406 -#define wxFileDataObject_AddFile 3407 -#define wxFileDataObject_GetFilenames 3408 -#define wxFileDataObject_destroy 3409 -#define wxTextDataObject_new 3410 -#define wxTextDataObject_GetTextLength 3411 -#define wxTextDataObject_GetText 3412 -#define wxTextDataObject_SetText 3413 -#define wxTextDataObject_destroy 3414 -#define wxBitmapDataObject_new_1_1 3415 -#define wxBitmapDataObject_new_1_0 3416 -#define wxBitmapDataObject_GetBitmap 3417 -#define wxBitmapDataObject_SetBitmap 3418 -#define wxBitmapDataObject_destroy 3419 -#define wxClipboard_new 3421 -#define wxClipboard_destruct 3422 -#define wxClipboard_AddData 3423 -#define wxClipboard_Clear 3424 -#define wxClipboard_Close 3425 -#define wxClipboard_Flush 3426 -#define wxClipboard_GetData 3427 -#define wxClipboard_IsOpened 3428 -#define wxClipboard_Open 3429 -#define wxClipboard_SetData 3430 -#define wxClipboard_UsePrimarySelection 3432 -#define wxClipboard_IsSupported 3433 -#define wxClipboard_Get 3434 -#define wxSpinEvent_GetPosition 3435 -#define wxSpinEvent_SetPosition 3436 -#define wxSplitterWindow_new_0 3437 -#define wxSplitterWindow_new_2 3438 -#define wxSplitterWindow_destruct 3439 -#define wxSplitterWindow_Create 3440 -#define wxSplitterWindow_GetMinimumPaneSize 3441 -#define wxSplitterWindow_GetSashGravity 3442 -#define wxSplitterWindow_GetSashPosition 3443 -#define wxSplitterWindow_GetSplitMode 3444 -#define wxSplitterWindow_GetWindow1 3445 -#define wxSplitterWindow_GetWindow2 3446 -#define wxSplitterWindow_Initialize 3447 -#define wxSplitterWindow_IsSplit 3448 -#define wxSplitterWindow_ReplaceWindow 3449 -#define wxSplitterWindow_SetSashGravity 3450 -#define wxSplitterWindow_SetSashPosition 3451 -#define wxSplitterWindow_SetSashSize 3452 -#define wxSplitterWindow_SetMinimumPaneSize 3453 -#define wxSplitterWindow_SetSplitMode 3454 -#define wxSplitterWindow_SplitHorizontally 3455 -#define wxSplitterWindow_SplitVertically 3456 -#define wxSplitterWindow_Unsplit 3457 -#define wxSplitterWindow_UpdateSize 3458 -#define wxSplitterEvent_GetSashPosition 3459 -#define wxSplitterEvent_GetX 3460 -#define wxSplitterEvent_GetY 3461 -#define wxSplitterEvent_GetWindowBeingRemoved 3462 -#define wxSplitterEvent_SetSashPosition 3463 -#define wxHtmlWindow_new_0 3464 -#define wxHtmlWindow_new_2 3465 -#define wxHtmlWindow_AppendToPage 3466 -#define wxHtmlWindow_GetOpenedAnchor 3467 -#define wxHtmlWindow_GetOpenedPage 3468 -#define wxHtmlWindow_GetOpenedPageTitle 3469 -#define wxHtmlWindow_GetRelatedFrame 3470 -#define wxHtmlWindow_HistoryBack 3471 -#define wxHtmlWindow_HistoryCanBack 3472 -#define wxHtmlWindow_HistoryCanForward 3473 -#define wxHtmlWindow_HistoryClear 3474 -#define wxHtmlWindow_HistoryForward 3475 -#define wxHtmlWindow_LoadFile 3476 -#define wxHtmlWindow_LoadPage 3477 -#define wxHtmlWindow_SelectAll 3478 -#define wxHtmlWindow_SelectionToText 3479 -#define wxHtmlWindow_SelectLine 3480 -#define wxHtmlWindow_SelectWord 3481 -#define wxHtmlWindow_SetBorders 3482 -#define wxHtmlWindow_SetFonts 3483 -#define wxHtmlWindow_SetPage 3484 -#define wxHtmlWindow_SetRelatedFrame 3485 -#define wxHtmlWindow_SetRelatedStatusBar 3486 -#define wxHtmlWindow_ToText 3487 -#define wxHtmlWindow_destroy 3488 -#define wxHtmlLinkEvent_GetLinkInfo 3489 -#define wxSystemSettings_GetColour 3490 -#define wxSystemSettings_GetFont 3491 -#define wxSystemSettings_GetMetric 3492 -#define wxSystemSettings_GetScreenType 3493 -#define wxSystemOptions_GetOption 3494 -#define wxSystemOptions_GetOptionInt 3495 -#define wxSystemOptions_HasOption 3496 -#define wxSystemOptions_IsFalse 3497 -#define wxSystemOptions_SetOption_2_1 3498 -#define wxSystemOptions_SetOption_2_0 3499 -#define wxAuiNotebookEvent_SetSelection 3500 -#define wxAuiNotebookEvent_GetSelection 3501 -#define wxAuiNotebookEvent_SetOldSelection 3502 -#define wxAuiNotebookEvent_GetOldSelection 3503 -#define wxAuiNotebookEvent_SetDragSource 3504 -#define wxAuiNotebookEvent_GetDragSource 3505 -#define wxAuiManagerEvent_SetManager 3506 -#define wxAuiManagerEvent_GetManager 3507 -#define wxAuiManagerEvent_SetPane 3508 -#define wxAuiManagerEvent_GetPane 3509 -#define wxAuiManagerEvent_SetButton 3510 -#define wxAuiManagerEvent_GetButton 3511 -#define wxAuiManagerEvent_SetDC 3512 -#define wxAuiManagerEvent_GetDC 3513 -#define wxAuiManagerEvent_Veto 3514 -#define wxAuiManagerEvent_GetVeto 3515 -#define wxAuiManagerEvent_SetCanVeto 3516 -#define wxAuiManagerEvent_CanVeto 3517 -#define wxLogNull_new 3518 -#define wxLogNull_destroy 3519 -#define wxTaskBarIcon_new 3520 -#define wxTaskBarIcon_destruct 3521 -#define wxTaskBarIcon_PopupMenu 3522 -#define wxTaskBarIcon_RemoveIcon 3523 -#define wxTaskBarIcon_SetIcon 3524 +#define wxPanel_SetFocusIgnoringChildren 337 +#define wxScrolledWindow_new_0 338 +#define wxScrolledWindow_new_2 339 +#define wxScrolledWindow_destruct 340 +#define wxScrolledWindow_CalcScrolledPosition_4 341 +#define wxScrolledWindow_CalcScrolledPosition_1 342 +#define wxScrolledWindow_CalcUnscrolledPosition_4 343 +#define wxScrolledWindow_CalcUnscrolledPosition_1 344 +#define wxScrolledWindow_EnableScrolling 345 +#define wxScrolledWindow_GetScrollPixelsPerUnit 346 +#define wxScrolledWindow_GetViewStart 347 +#define wxScrolledWindow_DoPrepareDC 348 +#define wxScrolledWindow_PrepareDC 349 +#define wxScrolledWindow_Scroll 350 +#define wxScrolledWindow_SetScrollbars 351 +#define wxScrolledWindow_SetScrollRate 352 +#define wxScrolledWindow_SetTargetWindow 353 +#define wxSashWindow_new_0 354 +#define wxSashWindow_new_2 355 +#define wxSashWindow_destruct 356 +#define wxSashWindow_GetSashVisible 357 +#define wxSashWindow_GetMaximumSizeX 358 +#define wxSashWindow_GetMaximumSizeY 359 +#define wxSashWindow_GetMinimumSizeX 360 +#define wxSashWindow_GetMinimumSizeY 361 +#define wxSashWindow_SetMaximumSizeX 362 +#define wxSashWindow_SetMaximumSizeY 363 +#define wxSashWindow_SetMinimumSizeX 364 +#define wxSashWindow_SetMinimumSizeY 365 +#define wxSashWindow_SetSashVisible 366 +#define wxSashLayoutWindow_new_0 367 +#define wxSashLayoutWindow_new_2 368 +#define wxSashLayoutWindow_Create 369 +#define wxSashLayoutWindow_GetAlignment 370 +#define wxSashLayoutWindow_GetOrientation 371 +#define wxSashLayoutWindow_SetAlignment 372 +#define wxSashLayoutWindow_SetDefaultSize 373 +#define wxSashLayoutWindow_SetOrientation 374 +#define wxSashLayoutWindow_destroy 375 +#define wxGrid_new_0 376 +#define wxGrid_new_3 377 +#define wxGrid_new_4 378 +#define wxGrid_destruct 379 +#define wxGrid_AppendCols 380 +#define wxGrid_AppendRows 381 +#define wxGrid_AutoSize 382 +#define wxGrid_AutoSizeColumn 383 +#define wxGrid_AutoSizeColumns 384 +#define wxGrid_AutoSizeRow 385 +#define wxGrid_AutoSizeRows 386 +#define wxGrid_BeginBatch 387 +#define wxGrid_BlockToDeviceRect 388 +#define wxGrid_CanDragColSize 389 +#define wxGrid_CanDragRowSize 390 +#define wxGrid_CanDragGridSize 391 +#define wxGrid_CanEnableCellControl 392 +#define wxGrid_CellToRect_2 393 +#define wxGrid_CellToRect_1 394 +#define wxGrid_ClearGrid 395 +#define wxGrid_ClearSelection 396 +#define wxGrid_CreateGrid 397 +#define wxGrid_DeleteCols 398 +#define wxGrid_DeleteRows 399 +#define wxGrid_DisableCellEditControl 400 +#define wxGrid_DisableDragColSize 401 +#define wxGrid_DisableDragGridSize 402 +#define wxGrid_DisableDragRowSize 403 +#define wxGrid_EnableCellEditControl 404 +#define wxGrid_EnableDragColSize 405 +#define wxGrid_EnableDragGridSize 406 +#define wxGrid_EnableDragRowSize 407 +#define wxGrid_EnableEditing 408 +#define wxGrid_EnableGridLines 409 +#define wxGrid_EndBatch 410 +#define wxGrid_Fit 411 +#define wxGrid_ForceRefresh 412 +#define wxGrid_GetBatchCount 413 +#define wxGrid_GetCellAlignment 414 +#define wxGrid_GetCellBackgroundColour 415 +#define wxGrid_GetCellEditor 416 +#define wxGrid_GetCellFont 417 +#define wxGrid_GetCellRenderer 418 +#define wxGrid_GetCellTextColour 419 +#define wxGrid_GetCellValue_2 420 +#define wxGrid_GetCellValue_1 421 +#define wxGrid_GetColLabelAlignment 422 +#define wxGrid_GetColLabelSize 423 +#define wxGrid_GetColLabelValue 424 +#define wxGrid_GetColMinimalAcceptableWidth 425 +#define wxGrid_GetDefaultCellAlignment 426 +#define wxGrid_GetDefaultCellBackgroundColour 427 +#define wxGrid_GetDefaultCellFont 428 +#define wxGrid_GetDefaultCellTextColour 429 +#define wxGrid_GetDefaultColLabelSize 430 +#define wxGrid_GetDefaultColSize 431 +#define wxGrid_GetDefaultEditor 432 +#define wxGrid_GetDefaultEditorForCell_2 433 +#define wxGrid_GetDefaultEditorForCell_1 434 +#define wxGrid_GetDefaultEditorForType 435 +#define wxGrid_GetDefaultRenderer 436 +#define wxGrid_GetDefaultRendererForCell 437 +#define wxGrid_GetDefaultRendererForType 438 +#define wxGrid_GetDefaultRowLabelSize 439 +#define wxGrid_GetDefaultRowSize 440 +#define wxGrid_GetGridCursorCol 441 +#define wxGrid_GetGridCursorRow 442 +#define wxGrid_GetGridLineColour 443 +#define wxGrid_GridLinesEnabled 444 +#define wxGrid_GetLabelBackgroundColour 445 +#define wxGrid_GetLabelFont 446 +#define wxGrid_GetLabelTextColour 447 +#define wxGrid_GetNumberCols 448 +#define wxGrid_GetNumberRows 449 +#define wxGrid_GetOrCreateCellAttr 450 +#define wxGrid_GetRowMinimalAcceptableHeight 451 +#define wxGrid_GetRowLabelAlignment 452 +#define wxGrid_GetRowLabelSize 453 +#define wxGrid_GetRowLabelValue 454 +#define wxGrid_GetRowSize 455 +#define wxGrid_GetScrollLineX 456 +#define wxGrid_GetScrollLineY 457 +#define wxGrid_GetSelectedCells 458 +#define wxGrid_GetSelectedCols 459 +#define wxGrid_GetSelectedRows 460 +#define wxGrid_GetSelectionBackground 461 +#define wxGrid_GetSelectionBlockTopLeft 462 +#define wxGrid_GetSelectionBlockBottomRight 463 +#define wxGrid_GetSelectionForeground 464 +#define wxGrid_GetViewWidth 465 +#define wxGrid_GetGridWindow 466 +#define wxGrid_GetGridRowLabelWindow 467 +#define wxGrid_GetGridColLabelWindow 468 +#define wxGrid_GetGridCornerLabelWindow 469 +#define wxGrid_HideCellEditControl 470 +#define wxGrid_InsertCols 471 +#define wxGrid_InsertRows 472 +#define wxGrid_IsCellEditControlEnabled 473 +#define wxGrid_IsCurrentCellReadOnly 474 +#define wxGrid_IsEditable 475 +#define wxGrid_IsInSelection_2 476 +#define wxGrid_IsInSelection_1 477 +#define wxGrid_IsReadOnly 478 +#define wxGrid_IsSelection 479 +#define wxGrid_IsVisible_3 480 +#define wxGrid_IsVisible_2 481 +#define wxGrid_MakeCellVisible_2 482 +#define wxGrid_MakeCellVisible_1 483 +#define wxGrid_MoveCursorDown 484 +#define wxGrid_MoveCursorLeft 485 +#define wxGrid_MoveCursorRight 486 +#define wxGrid_MoveCursorUp 487 +#define wxGrid_MoveCursorDownBlock 488 +#define wxGrid_MoveCursorLeftBlock 489 +#define wxGrid_MoveCursorRightBlock 490 +#define wxGrid_MoveCursorUpBlock 491 +#define wxGrid_MovePageDown 492 +#define wxGrid_MovePageUp 493 +#define wxGrid_RegisterDataType 494 +#define wxGrid_SaveEditControlValue 495 +#define wxGrid_SelectAll 496 +#define wxGrid_SelectBlock_5 497 +#define wxGrid_SelectBlock_3 498 +#define wxGrid_SelectCol 499 +#define wxGrid_SelectRow 500 +#define wxGrid_SetCellAlignment_4 501 +#define wxGrid_SetCellAlignment_3 502 +#define wxGrid_SetCellAlignment_1 503 +#define wxGrid_SetCellBackgroundColour_3_0 504 +#define wxGrid_SetCellBackgroundColour_1 505 +#define wxGrid_SetCellBackgroundColour_3_1 506 +#define wxGrid_SetCellEditor 507 +#define wxGrid_SetCellFont 508 +#define wxGrid_SetCellRenderer 509 +#define wxGrid_SetCellTextColour_3_0 510 +#define wxGrid_SetCellTextColour_3_1 511 +#define wxGrid_SetCellTextColour_1 512 +#define wxGrid_SetCellValue_3_0 513 +#define wxGrid_SetCellValue_2 514 +#define wxGrid_SetCellValue_3_1 515 +#define wxGrid_SetColAttr 516 +#define wxGrid_SetColFormatBool 517 +#define wxGrid_SetColFormatNumber 518 +#define wxGrid_SetColFormatFloat 519 +#define wxGrid_SetColFormatCustom 520 +#define wxGrid_SetColLabelAlignment 521 +#define wxGrid_SetColLabelSize 522 +#define wxGrid_SetColLabelValue 523 +#define wxGrid_SetColMinimalWidth 524 +#define wxGrid_SetColMinimalAcceptableWidth 525 +#define wxGrid_SetColSize 526 +#define wxGrid_SetDefaultCellAlignment 527 +#define wxGrid_SetDefaultCellBackgroundColour 528 +#define wxGrid_SetDefaultCellFont 529 +#define wxGrid_SetDefaultCellTextColour 530 +#define wxGrid_SetDefaultEditor 531 +#define wxGrid_SetDefaultRenderer 532 +#define wxGrid_SetDefaultColSize 533 +#define wxGrid_SetDefaultRowSize 534 +#define wxGrid_SetGridCursor 535 +#define wxGrid_SetGridLineColour 536 +#define wxGrid_SetLabelBackgroundColour 537 +#define wxGrid_SetLabelFont 538 +#define wxGrid_SetLabelTextColour 539 +#define wxGrid_SetMargins 540 +#define wxGrid_SetReadOnly 541 +#define wxGrid_SetRowAttr 542 +#define wxGrid_SetRowLabelAlignment 543 +#define wxGrid_SetRowLabelSize 544 +#define wxGrid_SetRowLabelValue 545 +#define wxGrid_SetRowMinimalHeight 546 +#define wxGrid_SetRowMinimalAcceptableHeight 547 +#define wxGrid_SetRowSize 548 +#define wxGrid_SetScrollLineX 549 +#define wxGrid_SetScrollLineY 550 +#define wxGrid_SetSelectionBackground 551 +#define wxGrid_SetSelectionForeground 552 +#define wxGrid_SetSelectionMode 553 +#define wxGrid_ShowCellEditControl 554 +#define wxGrid_XToCol 555 +#define wxGrid_XToEdgeOfCol 556 +#define wxGrid_YToEdgeOfRow 557 +#define wxGrid_YToRow 558 +#define wxGridCellRenderer_Draw 559 +#define wxGridCellRenderer_GetBestSize 560 +#define wxGridCellEditor_Create 561 +#define wxGridCellEditor_IsCreated 562 +#define wxGridCellEditor_SetSize 563 +#define wxGridCellEditor_Show 564 +#define wxGridCellEditor_PaintBackground 565 +#define wxGridCellEditor_BeginEdit 566 +#define wxGridCellEditor_EndEdit 567 +#define wxGridCellEditor_Reset 568 +#define wxGridCellEditor_StartingKey 569 +#define wxGridCellEditor_StartingClick 570 +#define wxGridCellEditor_HandleReturn 571 +#define wxGridCellBoolRenderer_new 572 +#define wxGridCellBoolRenderer_destroy 573 +#define wxGridCellBoolEditor_new 574 +#define wxGridCellBoolEditor_IsTrueValue 575 +#define wxGridCellBoolEditor_UseStringValues 576 +#define wxGridCellBoolEditor_destroy 577 +#define wxGridCellFloatRenderer_new 578 +#define wxGridCellFloatRenderer_GetPrecision 579 +#define wxGridCellFloatRenderer_GetWidth 580 +#define wxGridCellFloatRenderer_SetParameters 581 +#define wxGridCellFloatRenderer_SetPrecision 582 +#define wxGridCellFloatRenderer_SetWidth 583 +#define wxGridCellFloatRenderer_destroy 584 +#define wxGridCellFloatEditor_new 585 +#define wxGridCellFloatEditor_SetParameters 586 +#define wxGridCellFloatEditor_destroy 587 +#define wxGridCellStringRenderer_new 588 +#define wxGridCellStringRenderer_destroy 589 +#define wxGridCellTextEditor_new 590 +#define wxGridCellTextEditor_SetParameters 591 +#define wxGridCellTextEditor_destroy 592 +#define wxGridCellChoiceEditor_new 594 +#define wxGridCellChoiceEditor_SetParameters 595 +#define wxGridCellChoiceEditor_destroy 596 +#define wxGridCellNumberRenderer_new 597 +#define wxGridCellNumberRenderer_destroy 598 +#define wxGridCellNumberEditor_new 599 +#define wxGridCellNumberEditor_GetValue 600 +#define wxGridCellNumberEditor_SetParameters 601 +#define wxGridCellNumberEditor_destroy 602 +#define wxGridCellAttr_SetTextColour 603 +#define wxGridCellAttr_SetBackgroundColour 604 +#define wxGridCellAttr_SetFont 605 +#define wxGridCellAttr_SetAlignment 606 +#define wxGridCellAttr_SetReadOnly 607 +#define wxGridCellAttr_SetRenderer 608 +#define wxGridCellAttr_SetEditor 609 +#define wxGridCellAttr_HasTextColour 610 +#define wxGridCellAttr_HasBackgroundColour 611 +#define wxGridCellAttr_HasFont 612 +#define wxGridCellAttr_HasAlignment 613 +#define wxGridCellAttr_HasRenderer 614 +#define wxGridCellAttr_HasEditor 615 +#define wxGridCellAttr_GetTextColour 616 +#define wxGridCellAttr_GetBackgroundColour 617 +#define wxGridCellAttr_GetFont 618 +#define wxGridCellAttr_GetAlignment 619 +#define wxGridCellAttr_GetRenderer 620 +#define wxGridCellAttr_GetEditor 621 +#define wxGridCellAttr_IsReadOnly 622 +#define wxGridCellAttr_SetDefAttr 623 +#define wxDC_Blit 624 +#define wxDC_CalcBoundingBox 625 +#define wxDC_Clear 626 +#define wxDC_ComputeScaleAndOrigin 627 +#define wxDC_CrossHair 628 +#define wxDC_DestroyClippingRegion 629 +#define wxDC_DeviceToLogicalX 630 +#define wxDC_DeviceToLogicalXRel 631 +#define wxDC_DeviceToLogicalY 632 +#define wxDC_DeviceToLogicalYRel 633 +#define wxDC_DrawArc 634 +#define wxDC_DrawBitmap 635 +#define wxDC_DrawCheckMark 636 +#define wxDC_DrawCircle 637 +#define wxDC_DrawEllipse_2 639 +#define wxDC_DrawEllipse_1 640 +#define wxDC_DrawEllipticArc 641 +#define wxDC_DrawIcon 642 +#define wxDC_DrawLabel 643 +#define wxDC_DrawLine 644 +#define wxDC_DrawLines 645 +#define wxDC_DrawPolygon 647 +#define wxDC_DrawPoint 649 +#define wxDC_DrawRectangle_2 651 +#define wxDC_DrawRectangle_1 652 +#define wxDC_DrawRotatedText 653 +#define wxDC_DrawRoundedRectangle_3 655 +#define wxDC_DrawRoundedRectangle_2 656 +#define wxDC_DrawText 657 +#define wxDC_EndDoc 658 +#define wxDC_EndPage 659 +#define wxDC_FloodFill 660 +#define wxDC_GetBackground 661 +#define wxDC_GetBackgroundMode 662 +#define wxDC_GetBrush 663 +#define wxDC_GetCharHeight 664 +#define wxDC_GetCharWidth 665 +#define wxDC_GetClippingBox 666 +#define wxDC_GetFont 668 +#define wxDC_GetLayoutDirection 669 +#define wxDC_GetLogicalFunction 670 +#define wxDC_GetMapMode 671 +#define wxDC_GetMultiLineTextExtent_4 672 +#define wxDC_GetMultiLineTextExtent_1 673 +#define wxDC_GetPartialTextExtents 674 +#define wxDC_GetPen 675 +#define wxDC_GetPixel 676 +#define wxDC_GetPPI 677 +#define wxDC_GetSize 679 +#define wxDC_GetSizeMM 681 +#define wxDC_GetTextBackground 682 +#define wxDC_GetTextExtent_4 683 +#define wxDC_GetTextExtent_1 684 +#define wxDC_GetTextForeground 686 +#define wxDC_GetUserScale 687 +#define wxDC_GradientFillConcentric_3 688 +#define wxDC_GradientFillConcentric_4 689 +#define wxDC_GradientFillLinear 690 +#define wxDC_LogicalToDeviceX 691 +#define wxDC_LogicalToDeviceXRel 692 +#define wxDC_LogicalToDeviceY 693 +#define wxDC_LogicalToDeviceYRel 694 +#define wxDC_MaxX 695 +#define wxDC_MaxY 696 +#define wxDC_MinX 697 +#define wxDC_MinY 698 +#define wxDC_IsOk 699 +#define wxDC_ResetBoundingBox 700 +#define wxDC_SetAxisOrientation 701 +#define wxDC_SetBackground 702 +#define wxDC_SetBackgroundMode 703 +#define wxDC_SetBrush 704 +#define wxDC_SetClippingRegion_2 706 +#define wxDC_SetClippingRegion_1_1 707 +#define wxDC_SetClippingRegion_1_0 708 +#define wxDC_SetDeviceOrigin 709 +#define wxDC_SetFont 710 +#define wxDC_SetLayoutDirection 711 +#define wxDC_SetLogicalFunction 712 +#define wxDC_SetMapMode 713 +#define wxDC_SetPalette 714 +#define wxDC_SetPen 715 +#define wxDC_SetTextBackground 716 +#define wxDC_SetTextForeground 717 +#define wxDC_SetUserScale 718 +#define wxDC_StartDoc 719 +#define wxDC_StartPage 720 +#define wxMirrorDC_new 721 +#define wxMirrorDC_destroy 722 +#define wxScreenDC_new 723 +#define wxScreenDC_destruct 724 +#define wxPostScriptDC_new_0 725 +#define wxPostScriptDC_new_1 726 +#define wxPostScriptDC_destruct 727 +#define wxPostScriptDC_SetResolution 728 +#define wxPostScriptDC_GetResolution 729 +#define wxWindowDC_new_0 730 +#define wxWindowDC_new_1 731 +#define wxWindowDC_destruct 732 +#define wxClientDC_new_0 733 +#define wxClientDC_new_1 734 +#define wxClientDC_destroy 735 +#define wxPaintDC_new_0 736 +#define wxPaintDC_new_1 737 +#define wxPaintDC_destroy 738 +#define wxMemoryDC_new_1_0 740 +#define wxMemoryDC_new_1_1 741 +#define wxMemoryDC_new_0 742 +#define wxMemoryDC_destruct 744 +#define wxMemoryDC_SelectObject 745 +#define wxMemoryDC_SelectObjectAsSource 746 +#define wxBufferedDC_new_0 747 +#define wxBufferedDC_new_2 748 +#define wxBufferedDC_new_3 749 +#define wxBufferedDC_destruct 750 +#define wxBufferedDC_Init_2 751 +#define wxBufferedDC_Init_3 752 +#define wxBufferedPaintDC_new_3 753 +#define wxBufferedPaintDC_new_2 754 +#define wxBufferedPaintDC_destruct 755 +#define wxGraphicsObject_destruct 756 +#define wxGraphicsObject_GetRenderer 757 +#define wxGraphicsObject_IsNull 758 +#define wxGraphicsContext_destruct 759 +#define wxGraphicsContext_Create_1_1 760 +#define wxGraphicsContext_Create_1_0 761 +#define wxGraphicsContext_Create_0 762 +#define wxGraphicsContext_CreatePen 763 +#define wxGraphicsContext_CreateBrush 764 +#define wxGraphicsContext_CreateRadialGradientBrush 765 +#define wxGraphicsContext_CreateLinearGradientBrush 766 +#define wxGraphicsContext_CreateFont 767 +#define wxGraphicsContext_CreateMatrix 768 +#define wxGraphicsContext_CreatePath 769 +#define wxGraphicsContext_Clip_1 770 +#define wxGraphicsContext_Clip_4 771 +#define wxGraphicsContext_ResetClip 772 +#define wxGraphicsContext_DrawBitmap 773 +#define wxGraphicsContext_DrawEllipse 774 +#define wxGraphicsContext_DrawIcon 775 +#define wxGraphicsContext_DrawLines 776 +#define wxGraphicsContext_DrawPath 777 +#define wxGraphicsContext_DrawRectangle 778 +#define wxGraphicsContext_DrawRoundedRectangle 779 +#define wxGraphicsContext_DrawText_3 780 +#define wxGraphicsContext_DrawText_4_0 781 +#define wxGraphicsContext_DrawText_4_1 782 +#define wxGraphicsContext_DrawText_5 783 +#define wxGraphicsContext_FillPath 784 +#define wxGraphicsContext_StrokePath 785 +#define wxGraphicsContext_GetPartialTextExtents 786 +#define wxGraphicsContext_GetTextExtent 787 +#define wxGraphicsContext_Rotate 788 +#define wxGraphicsContext_Scale 789 +#define wxGraphicsContext_Translate 790 +#define wxGraphicsContext_GetTransform 791 +#define wxGraphicsContext_SetTransform 792 +#define wxGraphicsContext_ConcatTransform 793 +#define wxGraphicsContext_SetBrush_1_1 794 +#define wxGraphicsContext_SetBrush_1_0 795 +#define wxGraphicsContext_SetFont_1 796 +#define wxGraphicsContext_SetFont_2 797 +#define wxGraphicsContext_SetPen_1_0 798 +#define wxGraphicsContext_SetPen_1_1 799 +#define wxGraphicsContext_StrokeLine 800 +#define wxGraphicsContext_StrokeLines 801 +#define wxGraphicsMatrix_Concat 803 +#define wxGraphicsMatrix_Get 805 +#define wxGraphicsMatrix_Invert 806 +#define wxGraphicsMatrix_IsEqual 807 +#define wxGraphicsMatrix_IsIdentity 809 +#define wxGraphicsMatrix_Rotate 810 +#define wxGraphicsMatrix_Scale 811 +#define wxGraphicsMatrix_Translate 812 +#define wxGraphicsMatrix_Set 813 +#define wxGraphicsMatrix_TransformPoint 814 +#define wxGraphicsMatrix_TransformDistance 815 +#define wxGraphicsPath_MoveToPoint_2 816 +#define wxGraphicsPath_MoveToPoint_1 817 +#define wxGraphicsPath_AddArc_6 818 +#define wxGraphicsPath_AddArc_5 819 +#define wxGraphicsPath_AddArcToPoint 820 +#define wxGraphicsPath_AddCircle 821 +#define wxGraphicsPath_AddCurveToPoint_6 822 +#define wxGraphicsPath_AddCurveToPoint_3 823 +#define wxGraphicsPath_AddEllipse 824 +#define wxGraphicsPath_AddLineToPoint_2 825 +#define wxGraphicsPath_AddLineToPoint_1 826 +#define wxGraphicsPath_AddPath 827 +#define wxGraphicsPath_AddQuadCurveToPoint 828 +#define wxGraphicsPath_AddRectangle 829 +#define wxGraphicsPath_AddRoundedRectangle 830 +#define wxGraphicsPath_CloseSubpath 831 +#define wxGraphicsPath_Contains_3 832 +#define wxGraphicsPath_Contains_2 833 +#define wxGraphicsPath_GetBox 835 +#define wxGraphicsPath_GetCurrentPoint 837 +#define wxGraphicsPath_Transform 838 +#define wxGraphicsRenderer_GetDefaultRenderer 839 +#define wxGraphicsRenderer_CreateContext_1_1 840 +#define wxGraphicsRenderer_CreateContext_1_0 841 +#define wxGraphicsRenderer_CreatePen 842 +#define wxGraphicsRenderer_CreateBrush 843 +#define wxGraphicsRenderer_CreateLinearGradientBrush 844 +#define wxGraphicsRenderer_CreateRadialGradientBrush 845 +#define wxGraphicsRenderer_CreateFont 846 +#define wxGraphicsRenderer_CreateMatrix 847 +#define wxGraphicsRenderer_CreatePath 848 +#define wxMenuBar_new_1 850 +#define wxMenuBar_new_0 852 +#define wxMenuBar_destruct 854 +#define wxMenuBar_Append 855 +#define wxMenuBar_Check 856 +#define wxMenuBar_Enable_2 857 +#define wxMenuBar_Enable_1 858 +#define wxMenuBar_EnableTop 859 +#define wxMenuBar_FindMenu 860 +#define wxMenuBar_FindMenuItem 861 +#define wxMenuBar_FindItem 862 +#define wxMenuBar_GetHelpString 863 +#define wxMenuBar_GetLabel_1 864 +#define wxMenuBar_GetLabel_0 865 +#define wxMenuBar_GetLabelTop 866 +#define wxMenuBar_GetMenu 867 +#define wxMenuBar_GetMenuCount 868 +#define wxMenuBar_Insert 869 +#define wxMenuBar_IsChecked 870 +#define wxMenuBar_IsEnabled_1 871 +#define wxMenuBar_IsEnabled_0 872 +#define wxMenuBar_Remove 873 +#define wxMenuBar_Replace 874 +#define wxMenuBar_SetHelpString 875 +#define wxMenuBar_SetLabel_2 876 +#define wxMenuBar_SetLabel_1 877 +#define wxMenuBar_SetLabelTop 878 +#define wxControl_GetLabel 879 +#define wxControl_SetLabel 880 +#define wxControlWithItems_Append_1 881 +#define wxControlWithItems_Append_2 882 +#define wxControlWithItems_appendStrings_1 883 +#define wxControlWithItems_Clear 884 +#define wxControlWithItems_Delete 885 +#define wxControlWithItems_FindString 886 +#define wxControlWithItems_getClientData 887 +#define wxControlWithItems_setClientData 888 +#define wxControlWithItems_GetCount 889 +#define wxControlWithItems_GetSelection 890 +#define wxControlWithItems_GetString 891 +#define wxControlWithItems_GetStringSelection 892 +#define wxControlWithItems_Insert_2 893 +#define wxControlWithItems_Insert_3 894 +#define wxControlWithItems_IsEmpty 895 +#define wxControlWithItems_Select 896 +#define wxControlWithItems_SetSelection 897 +#define wxControlWithItems_SetString 898 +#define wxControlWithItems_SetStringSelection 899 +#define wxMenu_new_2 902 +#define wxMenu_new_1 903 +#define wxMenu_destruct 905 +#define wxMenu_Append_3 906 +#define wxMenu_Append_1 907 +#define wxMenu_Append_4_0 908 +#define wxMenu_Append_4_1 909 +#define wxMenu_AppendCheckItem 910 +#define wxMenu_AppendRadioItem 911 +#define wxMenu_AppendSeparator 912 +#define wxMenu_Break 913 +#define wxMenu_Check 914 +#define wxMenu_Delete_1_0 915 +#define wxMenu_Delete_1_1 916 +#define wxMenu_Destroy_1_0 917 +#define wxMenu_Destroy_1_1 918 +#define wxMenu_Enable 919 +#define wxMenu_FindItem_1 920 +#define wxMenu_FindItem_2 921 +#define wxMenu_FindItemByPosition 922 +#define wxMenu_GetHelpString 923 +#define wxMenu_GetLabel 924 +#define wxMenu_GetMenuItemCount 925 +#define wxMenu_GetMenuItems 926 +#define wxMenu_GetTitle 928 +#define wxMenu_Insert_2 929 +#define wxMenu_Insert_3 930 +#define wxMenu_Insert_5_1 931 +#define wxMenu_Insert_5_0 932 +#define wxMenu_InsertCheckItem 933 +#define wxMenu_InsertRadioItem 934 +#define wxMenu_InsertSeparator 935 +#define wxMenu_IsChecked 936 +#define wxMenu_IsEnabled 937 +#define wxMenu_Prepend_1 938 +#define wxMenu_Prepend_2 939 +#define wxMenu_Prepend_4_1 940 +#define wxMenu_Prepend_4_0 941 +#define wxMenu_PrependCheckItem 942 +#define wxMenu_PrependRadioItem 943 +#define wxMenu_PrependSeparator 944 +#define wxMenu_Remove_1_0 945 +#define wxMenu_Remove_1_1 946 +#define wxMenu_SetHelpString 947 +#define wxMenu_SetLabel 948 +#define wxMenu_SetTitle 949 +#define wxMenuItem_new 950 +#define wxMenuItem_destruct 952 +#define wxMenuItem_Check 953 +#define wxMenuItem_Enable 954 +#define wxMenuItem_GetBitmap 955 +#define wxMenuItem_GetHelp 956 +#define wxMenuItem_GetId 957 +#define wxMenuItem_GetKind 958 +#define wxMenuItem_GetLabel 959 +#define wxMenuItem_GetLabelFromText 960 +#define wxMenuItem_GetMenu 961 +#define wxMenuItem_GetText 962 +#define wxMenuItem_GetSubMenu 963 +#define wxMenuItem_IsCheckable 964 +#define wxMenuItem_IsChecked 965 +#define wxMenuItem_IsEnabled 966 +#define wxMenuItem_IsSeparator 967 +#define wxMenuItem_IsSubMenu 968 +#define wxMenuItem_SetBitmap 969 +#define wxMenuItem_SetHelp 970 +#define wxMenuItem_SetMenu 971 +#define wxMenuItem_SetSubMenu 972 +#define wxMenuItem_SetText 973 +#define wxToolBar_AddControl 974 +#define wxToolBar_AddSeparator 975 +#define wxToolBar_AddTool_5 976 +#define wxToolBar_AddTool_4_0 977 +#define wxToolBar_AddTool_1 978 +#define wxToolBar_AddTool_4_1 979 +#define wxToolBar_AddTool_3 980 +#define wxToolBar_AddTool_6 981 +#define wxToolBar_AddCheckTool 982 +#define wxToolBar_AddRadioTool 983 +#define wxToolBar_DeleteTool 984 +#define wxToolBar_DeleteToolByPos 985 +#define wxToolBar_EnableTool 986 +#define wxToolBar_FindById 987 +#define wxToolBar_FindControl 988 +#define wxToolBar_FindToolForPosition 989 +#define wxToolBar_GetToolSize 990 +#define wxToolBar_GetToolBitmapSize 991 +#define wxToolBar_GetMargins 992 +#define wxToolBar_GetToolEnabled 993 +#define wxToolBar_GetToolLongHelp 994 +#define wxToolBar_GetToolPacking 995 +#define wxToolBar_GetToolPos 996 +#define wxToolBar_GetToolSeparation 997 +#define wxToolBar_GetToolShortHelp 998 +#define wxToolBar_GetToolState 999 +#define wxToolBar_InsertControl 1000 +#define wxToolBar_InsertSeparator 1001 +#define wxToolBar_InsertTool_5 1002 +#define wxToolBar_InsertTool_2 1003 +#define wxToolBar_InsertTool_4 1004 +#define wxToolBar_Realize 1005 +#define wxToolBar_RemoveTool 1006 +#define wxToolBar_SetMargins 1007 +#define wxToolBar_SetToolBitmapSize 1008 +#define wxToolBar_SetToolLongHelp 1009 +#define wxToolBar_SetToolPacking 1010 +#define wxToolBar_SetToolShortHelp 1011 +#define wxToolBar_SetToolSeparation 1012 +#define wxToolBar_ToggleTool 1013 +#define wxStatusBar_new_0 1015 +#define wxStatusBar_new_2 1016 +#define wxStatusBar_destruct 1018 +#define wxStatusBar_Create 1019 +#define wxStatusBar_GetFieldRect 1020 +#define wxStatusBar_GetFieldsCount 1021 +#define wxStatusBar_GetStatusText 1022 +#define wxStatusBar_PopStatusText 1023 +#define wxStatusBar_PushStatusText 1024 +#define wxStatusBar_SetFieldsCount 1025 +#define wxStatusBar_SetMinHeight 1026 +#define wxStatusBar_SetStatusText 1027 +#define wxStatusBar_SetStatusWidths 1028 +#define wxStatusBar_SetStatusStyles 1029 +#define wxBitmap_new_0 1030 +#define wxBitmap_new_3 1031 +#define wxBitmap_new_4 1032 +#define wxBitmap_new_2_0 1033 +#define wxBitmap_new_2_1 1034 +#define wxBitmap_destruct 1035 +#define wxBitmap_ConvertToImage 1036 +#define wxBitmap_CopyFromIcon 1037 +#define wxBitmap_Create 1038 +#define wxBitmap_GetDepth 1039 +#define wxBitmap_GetHeight 1040 +#define wxBitmap_GetPalette 1041 +#define wxBitmap_GetMask 1042 +#define wxBitmap_GetWidth 1043 +#define wxBitmap_GetSubBitmap 1044 +#define wxBitmap_LoadFile 1045 +#define wxBitmap_Ok 1046 +#define wxBitmap_SaveFile 1047 +#define wxBitmap_SetDepth 1048 +#define wxBitmap_SetHeight 1049 +#define wxBitmap_SetMask 1050 +#define wxBitmap_SetPalette 1051 +#define wxBitmap_SetWidth 1052 +#define wxIcon_new_0 1053 +#define wxIcon_new_2 1054 +#define wxIcon_new_1 1055 +#define wxIcon_CopyFromBitmap 1056 +#define wxIcon_destroy 1057 +#define wxIconBundle_new_0 1058 +#define wxIconBundle_new_2 1059 +#define wxIconBundle_new_1_0 1060 +#define wxIconBundle_new_1_1 1061 +#define wxIconBundle_destruct 1062 +#define wxIconBundle_AddIcon_2 1063 +#define wxIconBundle_AddIcon_1 1064 +#define wxIconBundle_GetIcon_1_1 1065 +#define wxIconBundle_GetIcon_1_0 1066 +#define wxCursor_new_0 1067 +#define wxCursor_new_1_0 1068 +#define wxCursor_new_1_1 1069 +#define wxCursor_new_4 1070 +#define wxCursor_destruct 1071 +#define wxCursor_Ok 1072 +#define wxMask_new_0 1073 +#define wxMask_new_2_1 1074 +#define wxMask_new_2_0 1075 +#define wxMask_new_1 1076 +#define wxMask_destruct 1077 +#define wxMask_Create_2_1 1078 +#define wxMask_Create_2_0 1079 +#define wxMask_Create_1 1080 +#define wxImage_new_0 1081 +#define wxImage_new_3_0 1082 +#define wxImage_new_4 1083 +#define wxImage_new_5 1084 +#define wxImage_new_2 1085 +#define wxImage_new_3_1 1086 +#define wxImage_Blur 1087 +#define wxImage_BlurHorizontal 1088 +#define wxImage_BlurVertical 1089 +#define wxImage_ConvertAlphaToMask 1090 +#define wxImage_ConvertToGreyscale 1091 +#define wxImage_ConvertToMono 1092 +#define wxImage_Copy 1093 +#define wxImage_Create_3 1094 +#define wxImage_Create_4 1095 +#define wxImage_Create_5 1096 +#define wxImage_Destroy 1097 +#define wxImage_FindFirstUnusedColour 1098 +#define wxImage_GetImageExtWildcard 1099 +#define wxImage_GetAlpha_2 1100 +#define wxImage_GetAlpha_0 1101 +#define wxImage_GetBlue 1102 +#define wxImage_GetData 1103 +#define wxImage_GetGreen 1104 +#define wxImage_GetImageCount 1105 +#define wxImage_GetHeight 1106 +#define wxImage_GetMaskBlue 1107 +#define wxImage_GetMaskGreen 1108 +#define wxImage_GetMaskRed 1109 +#define wxImage_GetOrFindMaskColour 1110 +#define wxImage_GetPalette 1111 +#define wxImage_GetRed 1112 +#define wxImage_GetSubImage 1113 +#define wxImage_GetWidth 1114 +#define wxImage_HasAlpha 1115 +#define wxImage_HasMask 1116 +#define wxImage_GetOption 1117 +#define wxImage_GetOptionInt 1118 +#define wxImage_HasOption 1119 +#define wxImage_InitAlpha 1120 +#define wxImage_InitStandardHandlers 1121 +#define wxImage_IsTransparent 1122 +#define wxImage_LoadFile_2 1123 +#define wxImage_LoadFile_3 1124 +#define wxImage_Ok 1125 +#define wxImage_RemoveHandler 1126 +#define wxImage_Mirror 1127 +#define wxImage_Replace 1128 +#define wxImage_Rescale 1129 +#define wxImage_Resize 1130 +#define wxImage_Rotate 1131 +#define wxImage_RotateHue 1132 +#define wxImage_Rotate90 1133 +#define wxImage_SaveFile_1 1134 +#define wxImage_SaveFile_2_0 1135 +#define wxImage_SaveFile_2_1 1136 +#define wxImage_Scale 1137 +#define wxImage_Size 1138 +#define wxImage_SetAlpha_3 1139 +#define wxImage_SetAlpha_2 1140 +#define wxImage_SetData_2 1141 +#define wxImage_SetData_4 1142 +#define wxImage_SetMask 1143 +#define wxImage_SetMaskColour 1144 +#define wxImage_SetMaskFromImage 1145 +#define wxImage_SetOption_2_1 1146 +#define wxImage_SetOption_2_0 1147 +#define wxImage_SetPalette 1148 +#define wxImage_SetRGB_5 1149 +#define wxImage_SetRGB_4 1150 +#define wxImage_destroy 1151 +#define wxBrush_new_0 1152 +#define wxBrush_new_2 1153 +#define wxBrush_new_1 1154 +#define wxBrush_destruct 1156 +#define wxBrush_GetColour 1157 +#define wxBrush_GetStipple 1158 +#define wxBrush_GetStyle 1159 +#define wxBrush_IsHatch 1160 +#define wxBrush_IsOk 1161 +#define wxBrush_SetColour_1 1162 +#define wxBrush_SetColour_3 1163 +#define wxBrush_SetStipple 1164 +#define wxBrush_SetStyle 1165 +#define wxPen_new_0 1166 +#define wxPen_new_2 1167 +#define wxPen_destruct 1168 +#define wxPen_GetCap 1169 +#define wxPen_GetColour 1170 +#define wxPen_GetJoin 1171 +#define wxPen_GetStyle 1172 +#define wxPen_GetWidth 1173 +#define wxPen_IsOk 1174 +#define wxPen_SetCap 1175 +#define wxPen_SetColour_1 1176 +#define wxPen_SetColour_3 1177 +#define wxPen_SetJoin 1178 +#define wxPen_SetStyle 1179 +#define wxPen_SetWidth 1180 +#define wxRegion_new_0 1181 +#define wxRegion_new_4 1182 +#define wxRegion_new_2 1183 +#define wxRegion_new_1_1 1184 +#define wxRegion_new_1_0 1186 +#define wxRegion_destruct 1188 +#define wxRegion_Clear 1189 +#define wxRegion_Contains_2 1190 +#define wxRegion_Contains_1_0 1191 +#define wxRegion_Contains_4 1192 +#define wxRegion_Contains_1_1 1193 +#define wxRegion_ConvertToBitmap 1194 +#define wxRegion_GetBox 1195 +#define wxRegion_Intersect_4 1196 +#define wxRegion_Intersect_1_1 1197 +#define wxRegion_Intersect_1_0 1198 +#define wxRegion_IsEmpty 1199 +#define wxRegion_Subtract_4 1200 +#define wxRegion_Subtract_1_1 1201 +#define wxRegion_Subtract_1_0 1202 +#define wxRegion_Offset_2 1203 +#define wxRegion_Offset_1 1204 +#define wxRegion_Union_4 1205 +#define wxRegion_Union_1_2 1206 +#define wxRegion_Union_1_1 1207 +#define wxRegion_Union_1_0 1208 +#define wxRegion_Union_3 1209 +#define wxRegion_Xor_4 1210 +#define wxRegion_Xor_1_1 1211 +#define wxRegion_Xor_1_0 1212 +#define wxAcceleratorTable_new_0 1213 +#define wxAcceleratorTable_new_2 1214 +#define wxAcceleratorTable_destruct 1215 +#define wxAcceleratorTable_Ok 1216 +#define wxAcceleratorEntry_new_1_0 1217 +#define wxAcceleratorEntry_new_1_1 1218 +#define wxAcceleratorEntry_GetCommand 1219 +#define wxAcceleratorEntry_GetFlags 1220 +#define wxAcceleratorEntry_GetKeyCode 1221 +#define wxAcceleratorEntry_Set 1222 +#define wxAcceleratorEntry_destroy 1223 +#define wxCaret_new_3 1228 +#define wxCaret_new_2 1229 +#define wxCaret_destruct 1231 +#define wxCaret_Create_3 1232 +#define wxCaret_Create_2 1233 +#define wxCaret_GetBlinkTime 1234 +#define wxCaret_GetPosition 1236 +#define wxCaret_GetSize 1238 +#define wxCaret_GetWindow 1239 +#define wxCaret_Hide 1240 +#define wxCaret_IsOk 1241 +#define wxCaret_IsVisible 1242 +#define wxCaret_Move_2 1243 +#define wxCaret_Move_1 1244 +#define wxCaret_SetBlinkTime 1245 +#define wxCaret_SetSize_2 1246 +#define wxCaret_SetSize_1 1247 +#define wxCaret_Show 1248 +#define wxSizer_Add_2_1 1249 +#define wxSizer_Add_2_0 1250 +#define wxSizer_Add_3 1251 +#define wxSizer_Add_2_3 1252 +#define wxSizer_Add_2_2 1253 +#define wxSizer_AddSpacer 1254 +#define wxSizer_AddStretchSpacer 1255 +#define wxSizer_CalcMin 1256 +#define wxSizer_Clear 1257 +#define wxSizer_Detach_1_2 1258 +#define wxSizer_Detach_1_1 1259 +#define wxSizer_Detach_1_0 1260 +#define wxSizer_Fit 1261 +#define wxSizer_FitInside 1262 +#define wxSizer_GetChildren 1263 +#define wxSizer_GetItem_2_1 1264 +#define wxSizer_GetItem_2_0 1265 +#define wxSizer_GetItem_1 1266 +#define wxSizer_GetSize 1267 +#define wxSizer_GetPosition 1268 +#define wxSizer_GetMinSize 1269 +#define wxSizer_Hide_2_0 1270 +#define wxSizer_Hide_2_1 1271 +#define wxSizer_Hide_1 1272 +#define wxSizer_Insert_3_1 1273 +#define wxSizer_Insert_3_0 1274 +#define wxSizer_Insert_4 1275 +#define wxSizer_Insert_3_3 1276 +#define wxSizer_Insert_3_2 1277 +#define wxSizer_Insert_2 1278 +#define wxSizer_InsertSpacer 1279 +#define wxSizer_InsertStretchSpacer 1280 +#define wxSizer_IsShown_1_2 1281 +#define wxSizer_IsShown_1_1 1282 +#define wxSizer_IsShown_1_0 1283 +#define wxSizer_Layout 1284 +#define wxSizer_Prepend_2_1 1285 +#define wxSizer_Prepend_2_0 1286 +#define wxSizer_Prepend_3 1287 +#define wxSizer_Prepend_2_3 1288 +#define wxSizer_Prepend_2_2 1289 +#define wxSizer_Prepend_1 1290 +#define wxSizer_PrependSpacer 1291 +#define wxSizer_PrependStretchSpacer 1292 +#define wxSizer_RecalcSizes 1293 +#define wxSizer_Remove_1_1 1294 +#define wxSizer_Remove_1_0 1295 +#define wxSizer_Replace_3_1 1296 +#define wxSizer_Replace_3_0 1297 +#define wxSizer_Replace_2 1298 +#define wxSizer_SetDimension 1299 +#define wxSizer_SetMinSize_2 1300 +#define wxSizer_SetMinSize_1 1301 +#define wxSizer_SetItemMinSize_3_2 1302 +#define wxSizer_SetItemMinSize_2_2 1303 +#define wxSizer_SetItemMinSize_3_1 1304 +#define wxSizer_SetItemMinSize_2_1 1305 +#define wxSizer_SetItemMinSize_3_0 1306 +#define wxSizer_SetItemMinSize_2_0 1307 +#define wxSizer_SetSizeHints 1308 +#define wxSizer_SetVirtualSizeHints 1309 +#define wxSizer_Show_2_2 1310 +#define wxSizer_Show_2_1 1311 +#define wxSizer_Show_2_0 1312 +#define wxSizer_Show_1 1313 +#define wxSizerFlags_new 1314 +#define wxSizerFlags_Align 1315 +#define wxSizerFlags_Border_2 1316 +#define wxSizerFlags_Border_1 1317 +#define wxSizerFlags_Center 1318 +#define wxSizerFlags_Centre 1319 +#define wxSizerFlags_Expand 1320 +#define wxSizerFlags_Left 1321 +#define wxSizerFlags_Proportion 1322 +#define wxSizerFlags_Right 1323 +#define wxSizerFlags_destroy 1324 +#define wxSizerItem_new_5_1 1325 +#define wxSizerItem_new_2_1 1326 +#define wxSizerItem_new_5_0 1327 +#define wxSizerItem_new_2_0 1328 +#define wxSizerItem_new_6 1329 +#define wxSizerItem_new_3 1330 +#define wxSizerItem_new_0 1331 +#define wxSizerItem_destruct 1332 +#define wxSizerItem_CalcMin 1333 +#define wxSizerItem_DeleteWindows 1334 +#define wxSizerItem_DetachSizer 1335 +#define wxSizerItem_GetBorder 1336 +#define wxSizerItem_GetFlag 1337 +#define wxSizerItem_GetMinSize 1338 +#define wxSizerItem_GetPosition 1339 +#define wxSizerItem_GetProportion 1340 +#define wxSizerItem_GetRatio 1341 +#define wxSizerItem_GetRect 1342 +#define wxSizerItem_GetSize 1343 +#define wxSizerItem_GetSizer 1344 +#define wxSizerItem_GetSpacer 1345 +#define wxSizerItem_GetUserData 1346 +#define wxSizerItem_GetWindow 1347 +#define wxSizerItem_IsSizer 1348 +#define wxSizerItem_IsShown 1349 +#define wxSizerItem_IsSpacer 1350 +#define wxSizerItem_IsWindow 1351 +#define wxSizerItem_SetBorder 1352 +#define wxSizerItem_SetDimension 1353 +#define wxSizerItem_SetFlag 1354 +#define wxSizerItem_SetInitSize 1355 +#define wxSizerItem_SetMinSize_1 1356 +#define wxSizerItem_SetMinSize_2 1357 +#define wxSizerItem_SetProportion 1358 +#define wxSizerItem_SetRatio_2 1359 +#define wxSizerItem_SetRatio_1_1 1360 +#define wxSizerItem_SetRatio_1_0 1361 +#define wxSizerItem_SetSizer 1362 +#define wxSizerItem_SetSpacer_1 1363 +#define wxSizerItem_SetSpacer_2 1364 +#define wxSizerItem_SetWindow 1365 +#define wxSizerItem_Show 1366 +#define wxBoxSizer_new 1367 +#define wxBoxSizer_GetOrientation 1368 +#define wxBoxSizer_destroy 1369 +#define wxStaticBoxSizer_new_2 1370 +#define wxStaticBoxSizer_new_3 1371 +#define wxStaticBoxSizer_GetStaticBox 1372 +#define wxStaticBoxSizer_destroy 1373 +#define wxGridSizer_new_4 1374 +#define wxGridSizer_new_2 1375 +#define wxGridSizer_GetCols 1376 +#define wxGridSizer_GetHGap 1377 +#define wxGridSizer_GetRows 1378 +#define wxGridSizer_GetVGap 1379 +#define wxGridSizer_SetCols 1380 +#define wxGridSizer_SetHGap 1381 +#define wxGridSizer_SetRows 1382 +#define wxGridSizer_SetVGap 1383 +#define wxGridSizer_destroy 1384 +#define wxFlexGridSizer_new_4 1385 +#define wxFlexGridSizer_new_2 1386 +#define wxFlexGridSizer_AddGrowableCol 1387 +#define wxFlexGridSizer_AddGrowableRow 1388 +#define wxFlexGridSizer_GetFlexibleDirection 1389 +#define wxFlexGridSizer_GetNonFlexibleGrowMode 1390 +#define wxFlexGridSizer_RemoveGrowableCol 1391 +#define wxFlexGridSizer_RemoveGrowableRow 1392 +#define wxFlexGridSizer_SetFlexibleDirection 1393 +#define wxFlexGridSizer_SetNonFlexibleGrowMode 1394 +#define wxFlexGridSizer_destroy 1395 +#define wxGridBagSizer_new 1396 +#define wxGridBagSizer_Add_3_2 1397 +#define wxGridBagSizer_Add_3_1 1398 +#define wxGridBagSizer_Add_4 1399 +#define wxGridBagSizer_Add_1_0 1400 +#define wxGridBagSizer_Add_2_1 1401 +#define wxGridBagSizer_Add_2_0 1402 +#define wxGridBagSizer_Add_3_0 1403 +#define wxGridBagSizer_Add_1_1 1404 +#define wxGridBagSizer_CalcMin 1405 +#define wxGridBagSizer_CheckForIntersection_2 1406 +#define wxGridBagSizer_CheckForIntersection_3 1407 +#define wxGridBagSizer_FindItem_1_1 1408 +#define wxGridBagSizer_FindItem_1_0 1409 +#define wxGridBagSizer_FindItemAtPoint 1410 +#define wxGridBagSizer_FindItemAtPosition 1411 +#define wxGridBagSizer_FindItemWithData 1412 +#define wxGridBagSizer_GetCellSize 1413 +#define wxGridBagSizer_GetEmptyCellSize 1414 +#define wxGridBagSizer_GetItemPosition_1_2 1415 +#define wxGridBagSizer_GetItemPosition_1_1 1416 +#define wxGridBagSizer_GetItemPosition_1_0 1417 +#define wxGridBagSizer_GetItemSpan_1_2 1418 +#define wxGridBagSizer_GetItemSpan_1_1 1419 +#define wxGridBagSizer_GetItemSpan_1_0 1420 +#define wxGridBagSizer_SetEmptyCellSize 1421 +#define wxGridBagSizer_SetItemPosition_2_2 1422 +#define wxGridBagSizer_SetItemPosition_2_1 1423 +#define wxGridBagSizer_SetItemPosition_2_0 1424 +#define wxGridBagSizer_SetItemSpan_2_2 1425 +#define wxGridBagSizer_SetItemSpan_2_1 1426 +#define wxGridBagSizer_SetItemSpan_2_0 1427 +#define wxGridBagSizer_destroy 1428 +#define wxStdDialogButtonSizer_new 1429 +#define wxStdDialogButtonSizer_AddButton 1430 +#define wxStdDialogButtonSizer_Realize 1431 +#define wxStdDialogButtonSizer_SetAffirmativeButton 1432 +#define wxStdDialogButtonSizer_SetCancelButton 1433 +#define wxStdDialogButtonSizer_SetNegativeButton 1434 +#define wxStdDialogButtonSizer_destroy 1435 +#define wxFont_new_0 1436 +#define wxFont_new_1 1437 +#define wxFont_new_5 1438 +#define wxFont_destruct 1440 +#define wxFont_IsFixedWidth 1441 +#define wxFont_GetDefaultEncoding 1442 +#define wxFont_GetFaceName 1443 +#define wxFont_GetFamily 1444 +#define wxFont_GetNativeFontInfoDesc 1445 +#define wxFont_GetNativeFontInfoUserDesc 1446 +#define wxFont_GetPointSize 1447 +#define wxFont_GetStyle 1448 +#define wxFont_GetUnderlined 1449 +#define wxFont_GetWeight 1450 +#define wxFont_Ok 1451 +#define wxFont_SetDefaultEncoding 1452 +#define wxFont_SetFaceName 1453 +#define wxFont_SetFamily 1454 +#define wxFont_SetPointSize 1455 +#define wxFont_SetStyle 1456 +#define wxFont_SetUnderlined 1457 +#define wxFont_SetWeight 1458 +#define wxToolTip_Enable 1459 +#define wxToolTip_SetDelay 1460 +#define wxToolTip_new 1461 +#define wxToolTip_SetTip 1462 +#define wxToolTip_GetTip 1463 +#define wxToolTip_GetWindow 1464 +#define wxToolTip_destroy 1465 +#define wxButton_new_3 1467 +#define wxButton_new_0 1468 +#define wxButton_destruct 1469 +#define wxButton_Create 1470 +#define wxButton_GetDefaultSize 1471 +#define wxButton_SetDefault 1472 +#define wxButton_SetLabel 1473 +#define wxBitmapButton_new_4 1475 +#define wxBitmapButton_new_0 1476 +#define wxBitmapButton_Create 1477 +#define wxBitmapButton_GetBitmapDisabled 1478 +#define wxBitmapButton_GetBitmapFocus 1480 +#define wxBitmapButton_GetBitmapLabel 1482 +#define wxBitmapButton_GetBitmapSelected 1484 +#define wxBitmapButton_SetBitmapDisabled 1486 +#define wxBitmapButton_SetBitmapFocus 1487 +#define wxBitmapButton_SetBitmapLabel 1488 +#define wxBitmapButton_SetBitmapSelected 1489 +#define wxBitmapButton_destroy 1490 +#define wxToggleButton_new_0 1491 +#define wxToggleButton_new_4 1492 +#define wxToggleButton_Create 1493 +#define wxToggleButton_GetValue 1494 +#define wxToggleButton_SetValue 1495 +#define wxToggleButton_destroy 1496 +#define wxCalendarCtrl_new_0 1497 +#define wxCalendarCtrl_new_3 1498 +#define wxCalendarCtrl_Create 1499 +#define wxCalendarCtrl_destruct 1500 +#define wxCalendarCtrl_SetDate 1501 +#define wxCalendarCtrl_GetDate 1502 +#define wxCalendarCtrl_EnableYearChange 1503 +#define wxCalendarCtrl_EnableMonthChange 1504 +#define wxCalendarCtrl_EnableHolidayDisplay 1505 +#define wxCalendarCtrl_SetHeaderColours 1506 +#define wxCalendarCtrl_GetHeaderColourFg 1507 +#define wxCalendarCtrl_GetHeaderColourBg 1508 +#define wxCalendarCtrl_SetHighlightColours 1509 +#define wxCalendarCtrl_GetHighlightColourFg 1510 +#define wxCalendarCtrl_GetHighlightColourBg 1511 +#define wxCalendarCtrl_SetHolidayColours 1512 +#define wxCalendarCtrl_GetHolidayColourFg 1513 +#define wxCalendarCtrl_GetHolidayColourBg 1514 +#define wxCalendarCtrl_GetAttr 1515 +#define wxCalendarCtrl_SetAttr 1516 +#define wxCalendarCtrl_SetHoliday 1517 +#define wxCalendarCtrl_ResetAttr 1518 +#define wxCalendarCtrl_HitTest 1519 +#define wxCalendarDateAttr_new_0 1520 +#define wxCalendarDateAttr_new_2_1 1521 +#define wxCalendarDateAttr_new_2_0 1522 +#define wxCalendarDateAttr_SetTextColour 1523 +#define wxCalendarDateAttr_SetBackgroundColour 1524 +#define wxCalendarDateAttr_SetBorderColour 1525 +#define wxCalendarDateAttr_SetFont 1526 +#define wxCalendarDateAttr_SetBorder 1527 +#define wxCalendarDateAttr_SetHoliday 1528 +#define wxCalendarDateAttr_HasTextColour 1529 +#define wxCalendarDateAttr_HasBackgroundColour 1530 +#define wxCalendarDateAttr_HasBorderColour 1531 +#define wxCalendarDateAttr_HasFont 1532 +#define wxCalendarDateAttr_HasBorder 1533 +#define wxCalendarDateAttr_IsHoliday 1534 +#define wxCalendarDateAttr_GetTextColour 1535 +#define wxCalendarDateAttr_GetBackgroundColour 1536 +#define wxCalendarDateAttr_GetBorderColour 1537 +#define wxCalendarDateAttr_GetFont 1538 +#define wxCalendarDateAttr_GetBorder 1539 +#define wxCalendarDateAttr_destroy 1540 +#define wxCheckBox_new_4 1542 +#define wxCheckBox_new_0 1543 +#define wxCheckBox_Create 1544 +#define wxCheckBox_GetValue 1545 +#define wxCheckBox_Get3StateValue 1546 +#define wxCheckBox_Is3rdStateAllowedForUser 1547 +#define wxCheckBox_Is3State 1548 +#define wxCheckBox_IsChecked 1549 +#define wxCheckBox_SetValue 1550 +#define wxCheckBox_Set3StateValue 1551 +#define wxCheckBox_destroy 1552 +#define wxCheckListBox_new_0 1553 +#define wxCheckListBox_new_3 1555 +#define wxCheckListBox_Check 1556 +#define wxCheckListBox_IsChecked 1557 +#define wxCheckListBox_destroy 1558 +#define wxChoice_new_3 1561 +#define wxChoice_new_0 1562 +#define wxChoice_destruct 1564 +#define wxChoice_Create 1566 +#define wxChoice_Delete 1567 +#define wxChoice_GetColumns 1568 +#define wxChoice_SetColumns 1569 +#define wxComboBox_new_0 1570 +#define wxComboBox_new_3 1572 +#define wxComboBox_destruct 1573 +#define wxComboBox_Create 1575 +#define wxComboBox_CanCopy 1576 +#define wxComboBox_CanCut 1577 +#define wxComboBox_CanPaste 1578 +#define wxComboBox_CanRedo 1579 +#define wxComboBox_CanUndo 1580 +#define wxComboBox_Copy 1581 +#define wxComboBox_Cut 1582 +#define wxComboBox_GetInsertionPoint 1583 +#define wxComboBox_GetLastPosition 1584 +#define wxComboBox_GetValue 1585 +#define wxComboBox_Paste 1586 +#define wxComboBox_Redo 1587 +#define wxComboBox_Replace 1588 +#define wxComboBox_Remove 1589 +#define wxComboBox_SetInsertionPoint 1590 +#define wxComboBox_SetInsertionPointEnd 1591 +#define wxComboBox_SetSelection_1 1592 +#define wxComboBox_SetSelection_2 1593 +#define wxComboBox_SetValue 1594 +#define wxComboBox_Undo 1595 +#define wxGauge_new_0 1596 +#define wxGauge_new_4 1597 +#define wxGauge_Create 1598 +#define wxGauge_GetBezelFace 1599 +#define wxGauge_GetRange 1600 +#define wxGauge_GetShadowWidth 1601 +#define wxGauge_GetValue 1602 +#define wxGauge_IsVertical 1603 +#define wxGauge_SetBezelFace 1604 +#define wxGauge_SetRange 1605 +#define wxGauge_SetShadowWidth 1606 +#define wxGauge_SetValue 1607 +#define wxGauge_Pulse 1608 +#define wxGauge_destroy 1609 +#define wxGenericDirCtrl_new_0 1610 +#define wxGenericDirCtrl_new_2 1611 +#define wxGenericDirCtrl_destruct 1612 +#define wxGenericDirCtrl_Create 1613 +#define wxGenericDirCtrl_Init 1614 +#define wxGenericDirCtrl_CollapseTree 1615 +#define wxGenericDirCtrl_ExpandPath 1616 +#define wxGenericDirCtrl_GetDefaultPath 1617 +#define wxGenericDirCtrl_GetPath 1618 +#define wxGenericDirCtrl_GetFilePath 1619 +#define wxGenericDirCtrl_GetFilter 1620 +#define wxGenericDirCtrl_GetFilterIndex 1621 +#define wxGenericDirCtrl_GetRootId 1622 +#define wxGenericDirCtrl_GetTreeCtrl 1623 +#define wxGenericDirCtrl_ReCreateTree 1624 +#define wxGenericDirCtrl_SetDefaultPath 1625 +#define wxGenericDirCtrl_SetFilter 1626 +#define wxGenericDirCtrl_SetFilterIndex 1627 +#define wxGenericDirCtrl_SetPath 1628 +#define wxStaticBox_new_4 1630 +#define wxStaticBox_new_0 1631 +#define wxStaticBox_Create 1632 +#define wxStaticBox_destroy 1633 +#define wxStaticLine_new_2 1635 +#define wxStaticLine_new_0 1636 +#define wxStaticLine_Create 1637 +#define wxStaticLine_IsVertical 1638 +#define wxStaticLine_GetDefaultSize 1639 +#define wxStaticLine_destroy 1640 +#define wxListBox_new_3 1643 +#define wxListBox_new_0 1644 +#define wxListBox_destruct 1646 +#define wxListBox_Create 1648 +#define wxListBox_Deselect 1649 +#define wxListBox_GetSelections 1650 +#define wxListBox_InsertItems 1651 +#define wxListBox_IsSelected 1652 +#define wxListBox_Set 1654 +#define wxListBox_HitTest 1655 +#define wxListBox_SetFirstItem_1_0 1656 +#define wxListBox_SetFirstItem_1_1 1657 +#define wxListCtrl_new_0 1658 +#define wxListCtrl_new_2 1659 +#define wxListCtrl_Arrange 1660 +#define wxListCtrl_AssignImageList 1661 +#define wxListCtrl_ClearAll 1662 +#define wxListCtrl_Create 1663 +#define wxListCtrl_DeleteAllItems 1664 +#define wxListCtrl_DeleteColumn 1665 +#define wxListCtrl_DeleteItem 1666 +#define wxListCtrl_EditLabel 1667 +#define wxListCtrl_EnsureVisible 1668 +#define wxListCtrl_FindItem_3_0 1669 +#define wxListCtrl_FindItem_3_1 1670 +#define wxListCtrl_GetColumn 1671 +#define wxListCtrl_GetColumnCount 1672 +#define wxListCtrl_GetColumnWidth 1673 +#define wxListCtrl_GetCountPerPage 1674 +#define wxListCtrl_GetEditControl 1675 +#define wxListCtrl_GetImageList 1676 +#define wxListCtrl_GetItem 1677 +#define wxListCtrl_GetItemBackgroundColour 1678 +#define wxListCtrl_GetItemCount 1679 +#define wxListCtrl_GetItemData 1680 +#define wxListCtrl_GetItemFont 1681 +#define wxListCtrl_GetItemPosition 1682 +#define wxListCtrl_GetItemRect 1683 +#define wxListCtrl_GetItemSpacing 1684 +#define wxListCtrl_GetItemState 1685 +#define wxListCtrl_GetItemText 1686 +#define wxListCtrl_GetItemTextColour 1687 +#define wxListCtrl_GetNextItem 1688 +#define wxListCtrl_GetSelectedItemCount 1689 +#define wxListCtrl_GetTextColour 1690 +#define wxListCtrl_GetTopItem 1691 +#define wxListCtrl_GetViewRect 1692 +#define wxListCtrl_HitTest 1693 +#define wxListCtrl_InsertColumn_2 1694 +#define wxListCtrl_InsertColumn_3 1695 +#define wxListCtrl_InsertItem_1 1696 +#define wxListCtrl_InsertItem_2_1 1697 +#define wxListCtrl_InsertItem_2_0 1698 +#define wxListCtrl_InsertItem_3 1699 +#define wxListCtrl_RefreshItem 1700 +#define wxListCtrl_RefreshItems 1701 +#define wxListCtrl_ScrollList 1702 +#define wxListCtrl_SetBackgroundColour 1703 +#define wxListCtrl_SetColumn 1704 +#define wxListCtrl_SetColumnWidth 1705 +#define wxListCtrl_SetImageList 1706 +#define wxListCtrl_SetItem_1 1707 +#define wxListCtrl_SetItem_4 1708 +#define wxListCtrl_SetItemBackgroundColour 1709 +#define wxListCtrl_SetItemCount 1710 +#define wxListCtrl_SetItemData 1711 +#define wxListCtrl_SetItemFont 1712 +#define wxListCtrl_SetItemImage 1713 +#define wxListCtrl_SetItemColumnImage 1714 +#define wxListCtrl_SetItemPosition 1715 +#define wxListCtrl_SetItemState 1716 +#define wxListCtrl_SetItemText 1717 +#define wxListCtrl_SetItemTextColour 1718 +#define wxListCtrl_SetSingleStyle 1719 +#define wxListCtrl_SetTextColour 1720 +#define wxListCtrl_SetWindowStyleFlag 1721 +#define wxListCtrl_SortItems 1722 +#define wxListCtrl_destroy 1723 +#define wxListView_ClearColumnImage 1724 +#define wxListView_Focus 1725 +#define wxListView_GetFirstSelected 1726 +#define wxListView_GetFocusedItem 1727 +#define wxListView_GetNextSelected 1728 +#define wxListView_IsSelected 1729 +#define wxListView_Select 1730 +#define wxListView_SetColumnImage 1731 +#define wxListItem_new_0 1732 +#define wxListItem_new_1 1733 +#define wxListItem_destruct 1734 +#define wxListItem_Clear 1735 +#define wxListItem_GetAlign 1736 +#define wxListItem_GetBackgroundColour 1737 +#define wxListItem_GetColumn 1738 +#define wxListItem_GetFont 1739 +#define wxListItem_GetId 1740 +#define wxListItem_GetImage 1741 +#define wxListItem_GetMask 1742 +#define wxListItem_GetState 1743 +#define wxListItem_GetText 1744 +#define wxListItem_GetTextColour 1745 +#define wxListItem_GetWidth 1746 +#define wxListItem_SetAlign 1747 +#define wxListItem_SetBackgroundColour 1748 +#define wxListItem_SetColumn 1749 +#define wxListItem_SetFont 1750 +#define wxListItem_SetId 1751 +#define wxListItem_SetImage 1752 +#define wxListItem_SetMask 1753 +#define wxListItem_SetState 1754 +#define wxListItem_SetStateMask 1755 +#define wxListItem_SetText 1756 +#define wxListItem_SetTextColour 1757 +#define wxListItem_SetWidth 1758 +#define wxListItemAttr_new_0 1759 +#define wxListItemAttr_new_3 1760 +#define wxListItemAttr_GetBackgroundColour 1761 +#define wxListItemAttr_GetFont 1762 +#define wxListItemAttr_GetTextColour 1763 +#define wxListItemAttr_HasBackgroundColour 1764 +#define wxListItemAttr_HasFont 1765 +#define wxListItemAttr_HasTextColour 1766 +#define wxListItemAttr_SetBackgroundColour 1767 +#define wxListItemAttr_SetFont 1768 +#define wxListItemAttr_SetTextColour 1769 +#define wxListItemAttr_destroy 1770 +#define wxImageList_new_0 1771 +#define wxImageList_new_3 1772 +#define wxImageList_Add_1 1773 +#define wxImageList_Add_2_0 1774 +#define wxImageList_Add_2_1 1775 +#define wxImageList_Create 1776 +#define wxImageList_Draw 1778 +#define wxImageList_GetBitmap 1779 +#define wxImageList_GetIcon 1780 +#define wxImageList_GetImageCount 1781 +#define wxImageList_GetSize 1782 +#define wxImageList_Remove 1783 +#define wxImageList_RemoveAll 1784 +#define wxImageList_Replace_2 1785 +#define wxImageList_Replace_3 1786 +#define wxImageList_destroy 1787 +#define wxTextAttr_new_0 1788 +#define wxTextAttr_new_2 1789 +#define wxTextAttr_GetAlignment 1790 +#define wxTextAttr_GetBackgroundColour 1791 +#define wxTextAttr_GetFont 1792 +#define wxTextAttr_GetLeftIndent 1793 +#define wxTextAttr_GetLeftSubIndent 1794 +#define wxTextAttr_GetRightIndent 1795 +#define wxTextAttr_GetTabs 1796 +#define wxTextAttr_GetTextColour 1797 +#define wxTextAttr_HasBackgroundColour 1798 +#define wxTextAttr_HasFont 1799 +#define wxTextAttr_HasTextColour 1800 +#define wxTextAttr_GetFlags 1801 +#define wxTextAttr_IsDefault 1802 +#define wxTextAttr_SetAlignment 1803 +#define wxTextAttr_SetBackgroundColour 1804 +#define wxTextAttr_SetFlags 1805 +#define wxTextAttr_SetFont 1806 +#define wxTextAttr_SetLeftIndent 1807 +#define wxTextAttr_SetRightIndent 1808 +#define wxTextAttr_SetTabs 1809 +#define wxTextAttr_SetTextColour 1810 +#define wxTextAttr_destroy 1811 +#define wxTextCtrl_new_3 1813 +#define wxTextCtrl_new_0 1814 +#define wxTextCtrl_destruct 1816 +#define wxTextCtrl_AppendText 1817 +#define wxTextCtrl_CanCopy 1818 +#define wxTextCtrl_CanCut 1819 +#define wxTextCtrl_CanPaste 1820 +#define wxTextCtrl_CanRedo 1821 +#define wxTextCtrl_CanUndo 1822 +#define wxTextCtrl_Clear 1823 +#define wxTextCtrl_Copy 1824 +#define wxTextCtrl_Create 1825 +#define wxTextCtrl_Cut 1826 +#define wxTextCtrl_DiscardEdits 1827 +#define wxTextCtrl_EmulateKeyPress 1828 +#define wxTextCtrl_GetDefaultStyle 1829 +#define wxTextCtrl_GetInsertionPoint 1830 +#define wxTextCtrl_GetLastPosition 1831 +#define wxTextCtrl_GetLineLength 1832 +#define wxTextCtrl_GetLineText 1833 +#define wxTextCtrl_GetNumberOfLines 1834 +#define wxTextCtrl_GetRange 1835 +#define wxTextCtrl_GetSelection 1836 +#define wxTextCtrl_GetStringSelection 1837 +#define wxTextCtrl_GetStyle 1838 +#define wxTextCtrl_GetValue 1839 +#define wxTextCtrl_IsEditable 1840 +#define wxTextCtrl_IsModified 1841 +#define wxTextCtrl_IsMultiLine 1842 +#define wxTextCtrl_IsSingleLine 1843 +#define wxTextCtrl_LoadFile 1844 +#define wxTextCtrl_MarkDirty 1845 +#define wxTextCtrl_Paste 1846 +#define wxTextCtrl_PositionToXY 1847 +#define wxTextCtrl_Redo 1848 +#define wxTextCtrl_Remove 1849 +#define wxTextCtrl_Replace 1850 +#define wxTextCtrl_SaveFile 1851 +#define wxTextCtrl_SetDefaultStyle 1852 +#define wxTextCtrl_SetEditable 1853 +#define wxTextCtrl_SetInsertionPoint 1854 +#define wxTextCtrl_SetInsertionPointEnd 1855 +#define wxTextCtrl_SetMaxLength 1857 +#define wxTextCtrl_SetSelection 1858 +#define wxTextCtrl_SetStyle 1859 +#define wxTextCtrl_SetValue 1860 +#define wxTextCtrl_ShowPosition 1861 +#define wxTextCtrl_Undo 1862 +#define wxTextCtrl_WriteText 1863 +#define wxTextCtrl_XYToPosition 1864 +#define wxNotebook_new_0 1867 +#define wxNotebook_new_3 1868 +#define wxNotebook_destruct 1869 +#define wxNotebook_AddPage 1870 +#define wxNotebook_AdvanceSelection 1871 +#define wxNotebook_AssignImageList 1872 +#define wxNotebook_Create 1873 +#define wxNotebook_DeleteAllPages 1874 +#define wxNotebook_DeletePage 1875 +#define wxNotebook_RemovePage 1876 +#define wxNotebook_GetCurrentPage 1877 +#define wxNotebook_GetImageList 1878 +#define wxNotebook_GetPage 1880 +#define wxNotebook_GetPageCount 1881 +#define wxNotebook_GetPageImage 1882 +#define wxNotebook_GetPageText 1883 +#define wxNotebook_GetRowCount 1884 +#define wxNotebook_GetSelection 1885 +#define wxNotebook_GetThemeBackgroundColour 1886 +#define wxNotebook_HitTest 1888 +#define wxNotebook_InsertPage 1890 +#define wxNotebook_SetImageList 1891 +#define wxNotebook_SetPadding 1892 +#define wxNotebook_SetPageSize 1893 +#define wxNotebook_SetPageImage 1894 +#define wxNotebook_SetPageText 1895 +#define wxNotebook_SetSelection 1896 +#define wxNotebook_ChangeSelection 1897 +#define wxChoicebook_new_0 1898 +#define wxChoicebook_new_3 1899 +#define wxChoicebook_AddPage 1900 +#define wxChoicebook_AdvanceSelection 1901 +#define wxChoicebook_AssignImageList 1902 +#define wxChoicebook_Create 1903 +#define wxChoicebook_DeleteAllPages 1904 +#define wxChoicebook_DeletePage 1905 +#define wxChoicebook_RemovePage 1906 +#define wxChoicebook_GetCurrentPage 1907 +#define wxChoicebook_GetImageList 1908 +#define wxChoicebook_GetPage 1910 +#define wxChoicebook_GetPageCount 1911 +#define wxChoicebook_GetPageImage 1912 +#define wxChoicebook_GetPageText 1913 +#define wxChoicebook_GetSelection 1914 +#define wxChoicebook_HitTest 1915 +#define wxChoicebook_InsertPage 1916 +#define wxChoicebook_SetImageList 1917 +#define wxChoicebook_SetPageSize 1918 +#define wxChoicebook_SetPageImage 1919 +#define wxChoicebook_SetPageText 1920 +#define wxChoicebook_SetSelection 1921 +#define wxChoicebook_ChangeSelection 1922 +#define wxChoicebook_destroy 1923 +#define wxToolbook_new_0 1924 +#define wxToolbook_new_3 1925 +#define wxToolbook_AddPage 1926 +#define wxToolbook_AdvanceSelection 1927 +#define wxToolbook_AssignImageList 1928 +#define wxToolbook_Create 1929 +#define wxToolbook_DeleteAllPages 1930 +#define wxToolbook_DeletePage 1931 +#define wxToolbook_RemovePage 1932 +#define wxToolbook_GetCurrentPage 1933 +#define wxToolbook_GetImageList 1934 +#define wxToolbook_GetPage 1936 +#define wxToolbook_GetPageCount 1937 +#define wxToolbook_GetPageImage 1938 +#define wxToolbook_GetPageText 1939 +#define wxToolbook_GetSelection 1940 +#define wxToolbook_HitTest 1942 +#define wxToolbook_InsertPage 1943 +#define wxToolbook_SetImageList 1944 +#define wxToolbook_SetPageSize 1945 +#define wxToolbook_SetPageImage 1946 +#define wxToolbook_SetPageText 1947 +#define wxToolbook_SetSelection 1948 +#define wxToolbook_ChangeSelection 1949 +#define wxToolbook_destroy 1950 +#define wxListbook_new_0 1951 +#define wxListbook_new_3 1952 +#define wxListbook_AddPage 1953 +#define wxListbook_AdvanceSelection 1954 +#define wxListbook_AssignImageList 1955 +#define wxListbook_Create 1956 +#define wxListbook_DeleteAllPages 1957 +#define wxListbook_DeletePage 1958 +#define wxListbook_RemovePage 1959 +#define wxListbook_GetCurrentPage 1960 +#define wxListbook_GetImageList 1961 +#define wxListbook_GetPage 1963 +#define wxListbook_GetPageCount 1964 +#define wxListbook_GetPageImage 1965 +#define wxListbook_GetPageText 1966 +#define wxListbook_GetSelection 1967 +#define wxListbook_HitTest 1969 +#define wxListbook_InsertPage 1970 +#define wxListbook_SetImageList 1971 +#define wxListbook_SetPageSize 1972 +#define wxListbook_SetPageImage 1973 +#define wxListbook_SetPageText 1974 +#define wxListbook_SetSelection 1975 +#define wxListbook_ChangeSelection 1976 +#define wxListbook_destroy 1977 +#define wxTreebook_new_0 1978 +#define wxTreebook_new_3 1979 +#define wxTreebook_AddPage 1980 +#define wxTreebook_AdvanceSelection 1981 +#define wxTreebook_AssignImageList 1982 +#define wxTreebook_Create 1983 +#define wxTreebook_DeleteAllPages 1984 +#define wxTreebook_DeletePage 1985 +#define wxTreebook_RemovePage 1986 +#define wxTreebook_GetCurrentPage 1987 +#define wxTreebook_GetImageList 1988 +#define wxTreebook_GetPage 1990 +#define wxTreebook_GetPageCount 1991 +#define wxTreebook_GetPageImage 1992 +#define wxTreebook_GetPageText 1993 +#define wxTreebook_GetSelection 1994 +#define wxTreebook_ExpandNode 1995 +#define wxTreebook_IsNodeExpanded 1996 +#define wxTreebook_HitTest 1998 +#define wxTreebook_InsertPage 1999 +#define wxTreebook_InsertSubPage 2000 +#define wxTreebook_SetImageList 2001 +#define wxTreebook_SetPageSize 2002 +#define wxTreebook_SetPageImage 2003 +#define wxTreebook_SetPageText 2004 +#define wxTreebook_SetSelection 2005 +#define wxTreebook_ChangeSelection 2006 +#define wxTreebook_destroy 2007 +#define wxTreeCtrl_new_2 2010 +#define wxTreeCtrl_new_0 2011 +#define wxTreeCtrl_destruct 2013 +#define wxTreeCtrl_AddRoot 2014 +#define wxTreeCtrl_AppendItem 2015 +#define wxTreeCtrl_AssignImageList 2016 +#define wxTreeCtrl_AssignStateImageList 2017 +#define wxTreeCtrl_Collapse 2018 +#define wxTreeCtrl_CollapseAndReset 2019 +#define wxTreeCtrl_Create 2020 +#define wxTreeCtrl_Delete 2021 +#define wxTreeCtrl_DeleteAllItems 2022 +#define wxTreeCtrl_DeleteChildren 2023 +#define wxTreeCtrl_EditLabel 2024 +#define wxTreeCtrl_EnsureVisible 2025 +#define wxTreeCtrl_Expand 2026 +#define wxTreeCtrl_GetBoundingRect 2027 +#define wxTreeCtrl_GetChildrenCount 2029 +#define wxTreeCtrl_GetCount 2030 +#define wxTreeCtrl_GetEditControl 2031 +#define wxTreeCtrl_GetFirstChild 2032 +#define wxTreeCtrl_GetNextChild 2033 +#define wxTreeCtrl_GetFirstVisibleItem 2034 +#define wxTreeCtrl_GetImageList 2035 +#define wxTreeCtrl_GetIndent 2036 +#define wxTreeCtrl_GetItemBackgroundColour 2037 +#define wxTreeCtrl_GetItemData 2038 +#define wxTreeCtrl_GetItemFont 2039 +#define wxTreeCtrl_GetItemImage_1 2040 +#define wxTreeCtrl_GetItemImage_2 2041 +#define wxTreeCtrl_GetItemText 2042 +#define wxTreeCtrl_GetItemTextColour 2043 +#define wxTreeCtrl_GetLastChild 2044 +#define wxTreeCtrl_GetNextSibling 2045 +#define wxTreeCtrl_GetNextVisible 2046 +#define wxTreeCtrl_GetItemParent 2047 +#define wxTreeCtrl_GetPrevSibling 2048 +#define wxTreeCtrl_GetPrevVisible 2049 +#define wxTreeCtrl_GetRootItem 2050 +#define wxTreeCtrl_GetSelection 2051 +#define wxTreeCtrl_GetSelections 2052 +#define wxTreeCtrl_GetStateImageList 2053 +#define wxTreeCtrl_HitTest 2054 +#define wxTreeCtrl_InsertItem 2056 +#define wxTreeCtrl_IsBold 2057 +#define wxTreeCtrl_IsExpanded 2058 +#define wxTreeCtrl_IsSelected 2059 +#define wxTreeCtrl_IsVisible 2060 +#define wxTreeCtrl_ItemHasChildren 2061 +#define wxTreeCtrl_IsTreeItemIdOk 2062 +#define wxTreeCtrl_PrependItem 2063 +#define wxTreeCtrl_ScrollTo 2064 +#define wxTreeCtrl_SelectItem_1 2065 +#define wxTreeCtrl_SelectItem_2 2066 +#define wxTreeCtrl_SetIndent 2067 +#define wxTreeCtrl_SetImageList 2068 +#define wxTreeCtrl_SetItemBackgroundColour 2069 +#define wxTreeCtrl_SetItemBold 2070 +#define wxTreeCtrl_SetItemData 2071 +#define wxTreeCtrl_SetItemDropHighlight 2072 +#define wxTreeCtrl_SetItemFont 2073 +#define wxTreeCtrl_SetItemHasChildren 2074 +#define wxTreeCtrl_SetItemImage_2 2075 +#define wxTreeCtrl_SetItemImage_3 2076 +#define wxTreeCtrl_SetItemText 2077 +#define wxTreeCtrl_SetItemTextColour 2078 +#define wxTreeCtrl_SetStateImageList 2079 +#define wxTreeCtrl_SetWindowStyle 2080 +#define wxTreeCtrl_SortChildren 2081 +#define wxTreeCtrl_Toggle 2082 +#define wxTreeCtrl_ToggleItemSelection 2083 +#define wxTreeCtrl_Unselect 2084 +#define wxTreeCtrl_UnselectAll 2085 +#define wxTreeCtrl_UnselectItem 2086 +#define wxScrollBar_new_0 2087 +#define wxScrollBar_new_3 2088 +#define wxScrollBar_destruct 2089 +#define wxScrollBar_Create 2090 +#define wxScrollBar_GetRange 2091 +#define wxScrollBar_GetPageSize 2092 +#define wxScrollBar_GetThumbPosition 2093 +#define wxScrollBar_GetThumbSize 2094 +#define wxScrollBar_SetThumbPosition 2095 +#define wxScrollBar_SetScrollbar 2096 +#define wxSpinButton_new_2 2098 +#define wxSpinButton_new_0 2099 +#define wxSpinButton_Create 2100 +#define wxSpinButton_GetMax 2101 +#define wxSpinButton_GetMin 2102 +#define wxSpinButton_GetValue 2103 +#define wxSpinButton_SetRange 2104 +#define wxSpinButton_SetValue 2105 +#define wxSpinButton_destroy 2106 +#define wxSpinCtrl_new_0 2107 +#define wxSpinCtrl_new_2 2108 +#define wxSpinCtrl_Create 2110 +#define wxSpinCtrl_SetValue_1_1 2113 +#define wxSpinCtrl_SetValue_1_0 2114 +#define wxSpinCtrl_GetValue 2116 +#define wxSpinCtrl_SetRange 2118 +#define wxSpinCtrl_SetSelection 2119 +#define wxSpinCtrl_GetMin 2121 +#define wxSpinCtrl_GetMax 2123 +#define wxSpinCtrl_destroy 2124 +#define wxStaticText_new_0 2125 +#define wxStaticText_new_4 2126 +#define wxStaticText_Create 2127 +#define wxStaticText_GetLabel 2128 +#define wxStaticText_SetLabel 2129 +#define wxStaticText_Wrap 2130 +#define wxStaticText_destroy 2131 +#define wxStaticBitmap_new_0 2132 +#define wxStaticBitmap_new_4 2133 +#define wxStaticBitmap_Create 2134 +#define wxStaticBitmap_GetBitmap 2135 +#define wxStaticBitmap_SetBitmap 2136 +#define wxStaticBitmap_destroy 2137 +#define wxRadioBox_new 2138 +#define wxRadioBox_destruct 2140 +#define wxRadioBox_Create 2141 +#define wxRadioBox_Enable_2 2142 +#define wxRadioBox_Enable_1 2143 +#define wxRadioBox_GetSelection 2144 +#define wxRadioBox_GetString 2145 +#define wxRadioBox_SetSelection 2146 +#define wxRadioBox_Show_2 2147 +#define wxRadioBox_Show_1 2148 +#define wxRadioBox_GetColumnCount 2149 +#define wxRadioBox_GetItemHelpText 2150 +#define wxRadioBox_GetItemToolTip 2151 +#define wxRadioBox_GetItemFromPoint 2153 +#define wxRadioBox_GetRowCount 2154 +#define wxRadioBox_IsItemEnabled 2155 +#define wxRadioBox_IsItemShown 2156 +#define wxRadioBox_SetItemHelpText 2157 +#define wxRadioBox_SetItemToolTip 2158 +#define wxRadioButton_new_0 2159 +#define wxRadioButton_new_4 2160 +#define wxRadioButton_Create 2161 +#define wxRadioButton_GetValue 2162 +#define wxRadioButton_SetValue 2163 +#define wxRadioButton_destroy 2164 +#define wxSlider_new_6 2166 +#define wxSlider_new_0 2167 +#define wxSlider_Create 2168 +#define wxSlider_GetLineSize 2169 +#define wxSlider_GetMax 2170 +#define wxSlider_GetMin 2171 +#define wxSlider_GetPageSize 2172 +#define wxSlider_GetThumbLength 2173 +#define wxSlider_GetValue 2174 +#define wxSlider_SetLineSize 2175 +#define wxSlider_SetPageSize 2176 +#define wxSlider_SetRange 2177 +#define wxSlider_SetThumbLength 2178 +#define wxSlider_SetValue 2179 +#define wxSlider_destroy 2180 +#define wxDialog_new_4 2182 +#define wxDialog_new_0 2183 +#define wxDialog_destruct 2185 +#define wxDialog_Create 2186 +#define wxDialog_CreateButtonSizer 2187 +#define wxDialog_CreateStdDialogButtonSizer 2188 +#define wxDialog_EndModal 2189 +#define wxDialog_GetAffirmativeId 2190 +#define wxDialog_GetReturnCode 2191 +#define wxDialog_IsModal 2192 +#define wxDialog_SetAffirmativeId 2193 +#define wxDialog_SetReturnCode 2194 +#define wxDialog_Show 2195 +#define wxDialog_ShowModal 2196 +#define wxColourDialog_new_0 2197 +#define wxColourDialog_new_2 2198 +#define wxColourDialog_destruct 2199 +#define wxColourDialog_Create 2200 +#define wxColourDialog_GetColourData 2201 +#define wxColourData_new_0 2202 +#define wxColourData_new_1 2203 +#define wxColourData_destruct 2204 +#define wxColourData_GetChooseFull 2205 +#define wxColourData_GetColour 2206 +#define wxColourData_GetCustomColour 2208 +#define wxColourData_SetChooseFull 2209 +#define wxColourData_SetColour 2210 +#define wxColourData_SetCustomColour 2211 +#define wxPalette_new_0 2212 +#define wxPalette_new_4 2213 +#define wxPalette_destruct 2215 +#define wxPalette_Create 2216 +#define wxPalette_GetColoursCount 2217 +#define wxPalette_GetPixel 2218 +#define wxPalette_GetRGB 2219 +#define wxPalette_IsOk 2220 +#define wxDirDialog_new 2224 +#define wxDirDialog_destruct 2225 +#define wxDirDialog_GetPath 2226 +#define wxDirDialog_GetMessage 2227 +#define wxDirDialog_SetMessage 2228 +#define wxDirDialog_SetPath 2229 +#define wxFileDialog_new 2233 +#define wxFileDialog_destruct 2234 +#define wxFileDialog_GetDirectory 2235 +#define wxFileDialog_GetFilename 2236 +#define wxFileDialog_GetFilenames 2237 +#define wxFileDialog_GetFilterIndex 2238 +#define wxFileDialog_GetMessage 2239 +#define wxFileDialog_GetPath 2240 +#define wxFileDialog_GetPaths 2241 +#define wxFileDialog_GetWildcard 2242 +#define wxFileDialog_SetDirectory 2243 +#define wxFileDialog_SetFilename 2244 +#define wxFileDialog_SetFilterIndex 2245 +#define wxFileDialog_SetMessage 2246 +#define wxFileDialog_SetPath 2247 +#define wxFileDialog_SetWildcard 2248 +#define wxPickerBase_SetInternalMargin 2249 +#define wxPickerBase_GetInternalMargin 2250 +#define wxPickerBase_SetTextCtrlProportion 2251 +#define wxPickerBase_SetPickerCtrlProportion 2252 +#define wxPickerBase_GetTextCtrlProportion 2253 +#define wxPickerBase_GetPickerCtrlProportion 2254 +#define wxPickerBase_HasTextCtrl 2255 +#define wxPickerBase_GetTextCtrl 2256 +#define wxPickerBase_IsTextCtrlGrowable 2257 +#define wxPickerBase_SetPickerCtrlGrowable 2258 +#define wxPickerBase_SetTextCtrlGrowable 2259 +#define wxPickerBase_IsPickerCtrlGrowable 2260 +#define wxFilePickerCtrl_new_0 2261 +#define wxFilePickerCtrl_new_3 2262 +#define wxFilePickerCtrl_Create 2263 +#define wxFilePickerCtrl_GetPath 2264 +#define wxFilePickerCtrl_SetPath 2265 +#define wxFilePickerCtrl_destroy 2266 +#define wxDirPickerCtrl_new_0 2267 +#define wxDirPickerCtrl_new_3 2268 +#define wxDirPickerCtrl_Create 2269 +#define wxDirPickerCtrl_GetPath 2270 +#define wxDirPickerCtrl_SetPath 2271 +#define wxDirPickerCtrl_destroy 2272 +#define wxColourPickerCtrl_new_0 2273 +#define wxColourPickerCtrl_new_3 2274 +#define wxColourPickerCtrl_Create 2275 +#define wxColourPickerCtrl_GetColour 2276 +#define wxColourPickerCtrl_SetColour_1_1 2277 +#define wxColourPickerCtrl_SetColour_1_0 2278 +#define wxColourPickerCtrl_destroy 2279 +#define wxDatePickerCtrl_new_0 2280 +#define wxDatePickerCtrl_new_3 2281 +#define wxDatePickerCtrl_GetRange 2282 +#define wxDatePickerCtrl_GetValue 2283 +#define wxDatePickerCtrl_SetRange 2284 +#define wxDatePickerCtrl_SetValue 2285 +#define wxDatePickerCtrl_destroy 2286 +#define wxFontPickerCtrl_new_0 2287 +#define wxFontPickerCtrl_new_3 2288 +#define wxFontPickerCtrl_Create 2289 +#define wxFontPickerCtrl_GetSelectedFont 2290 +#define wxFontPickerCtrl_SetSelectedFont 2291 +#define wxFontPickerCtrl_GetMaxPointSize 2292 +#define wxFontPickerCtrl_SetMaxPointSize 2293 +#define wxFontPickerCtrl_destroy 2294 +#define wxFindReplaceDialog_new_0 2297 +#define wxFindReplaceDialog_new_4 2298 +#define wxFindReplaceDialog_destruct 2299 +#define wxFindReplaceDialog_Create 2300 +#define wxFindReplaceDialog_GetData 2301 +#define wxFindReplaceData_new_0 2302 +#define wxFindReplaceData_new_1 2303 +#define wxFindReplaceData_GetFindString 2304 +#define wxFindReplaceData_GetReplaceString 2305 +#define wxFindReplaceData_GetFlags 2306 +#define wxFindReplaceData_SetFlags 2307 +#define wxFindReplaceData_SetFindString 2308 +#define wxFindReplaceData_SetReplaceString 2309 +#define wxFindReplaceData_destroy 2310 +#define wxMultiChoiceDialog_new_0 2311 +#define wxMultiChoiceDialog_new_5 2313 +#define wxMultiChoiceDialog_GetSelections 2314 +#define wxMultiChoiceDialog_SetSelections 2315 +#define wxMultiChoiceDialog_destroy 2316 +#define wxSingleChoiceDialog_new_0 2317 +#define wxSingleChoiceDialog_new_5 2319 +#define wxSingleChoiceDialog_GetSelection 2320 +#define wxSingleChoiceDialog_GetStringSelection 2321 +#define wxSingleChoiceDialog_SetSelection 2322 +#define wxSingleChoiceDialog_destroy 2323 +#define wxTextEntryDialog_new 2324 +#define wxTextEntryDialog_GetValue 2325 +#define wxTextEntryDialog_SetValue 2326 +#define wxTextEntryDialog_destroy 2327 +#define wxPasswordEntryDialog_new 2328 +#define wxPasswordEntryDialog_destroy 2329 +#define wxFontData_new_0 2330 +#define wxFontData_new_1 2331 +#define wxFontData_destruct 2332 +#define wxFontData_EnableEffects 2333 +#define wxFontData_GetAllowSymbols 2334 +#define wxFontData_GetColour 2335 +#define wxFontData_GetChosenFont 2336 +#define wxFontData_GetEnableEffects 2337 +#define wxFontData_GetInitialFont 2338 +#define wxFontData_GetShowHelp 2339 +#define wxFontData_SetAllowSymbols 2340 +#define wxFontData_SetChosenFont 2341 +#define wxFontData_SetColour 2342 +#define wxFontData_SetInitialFont 2343 +#define wxFontData_SetRange 2344 +#define wxFontData_SetShowHelp 2345 +#define wxFontDialog_new_0 2349 +#define wxFontDialog_new_2 2351 +#define wxFontDialog_Create 2353 +#define wxFontDialog_GetFontData 2354 +#define wxFontDialog_destroy 2356 +#define wxProgressDialog_new 2357 +#define wxProgressDialog_destruct 2358 +#define wxProgressDialog_Resume 2359 +#define wxProgressDialog_Update_2 2360 +#define wxProgressDialog_Update_0 2361 +#define wxMessageDialog_new 2362 +#define wxMessageDialog_destruct 2363 +#define wxPageSetupDialog_new 2364 +#define wxPageSetupDialog_destruct 2365 +#define wxPageSetupDialog_GetPageSetupData 2366 +#define wxPageSetupDialog_ShowModal 2367 +#define wxPageSetupDialogData_new_0 2368 +#define wxPageSetupDialogData_new_1_0 2369 +#define wxPageSetupDialogData_new_1_1 2370 +#define wxPageSetupDialogData_destruct 2371 +#define wxPageSetupDialogData_EnableHelp 2372 +#define wxPageSetupDialogData_EnableMargins 2373 +#define wxPageSetupDialogData_EnableOrientation 2374 +#define wxPageSetupDialogData_EnablePaper 2375 +#define wxPageSetupDialogData_EnablePrinter 2376 +#define wxPageSetupDialogData_GetDefaultMinMargins 2377 +#define wxPageSetupDialogData_GetEnableMargins 2378 +#define wxPageSetupDialogData_GetEnableOrientation 2379 +#define wxPageSetupDialogData_GetEnablePaper 2380 +#define wxPageSetupDialogData_GetEnablePrinter 2381 +#define wxPageSetupDialogData_GetEnableHelp 2382 +#define wxPageSetupDialogData_GetDefaultInfo 2383 +#define wxPageSetupDialogData_GetMarginTopLeft 2384 +#define wxPageSetupDialogData_GetMarginBottomRight 2385 +#define wxPageSetupDialogData_GetMinMarginTopLeft 2386 +#define wxPageSetupDialogData_GetMinMarginBottomRight 2387 +#define wxPageSetupDialogData_GetPaperId 2388 +#define wxPageSetupDialogData_GetPaperSize 2389 +#define wxPageSetupDialogData_GetPrintData 2391 +#define wxPageSetupDialogData_IsOk 2392 +#define wxPageSetupDialogData_SetDefaultInfo 2393 +#define wxPageSetupDialogData_SetDefaultMinMargins 2394 +#define wxPageSetupDialogData_SetMarginTopLeft 2395 +#define wxPageSetupDialogData_SetMarginBottomRight 2396 +#define wxPageSetupDialogData_SetMinMarginTopLeft 2397 +#define wxPageSetupDialogData_SetMinMarginBottomRight 2398 +#define wxPageSetupDialogData_SetPaperId 2399 +#define wxPageSetupDialogData_SetPaperSize_1_1 2400 +#define wxPageSetupDialogData_SetPaperSize_1_0 2401 +#define wxPageSetupDialogData_SetPrintData 2402 +#define wxPrintDialog_new_2_0 2403 +#define wxPrintDialog_new_2_1 2404 +#define wxPrintDialog_destruct 2405 +#define wxPrintDialog_GetPrintDialogData 2406 +#define wxPrintDialog_GetPrintDC 2407 +#define wxPrintDialogData_new_0 2408 +#define wxPrintDialogData_new_1_1 2409 +#define wxPrintDialogData_new_1_0 2410 +#define wxPrintDialogData_destruct 2411 +#define wxPrintDialogData_EnableHelp 2412 +#define wxPrintDialogData_EnablePageNumbers 2413 +#define wxPrintDialogData_EnablePrintToFile 2414 +#define wxPrintDialogData_EnableSelection 2415 +#define wxPrintDialogData_GetAllPages 2416 +#define wxPrintDialogData_GetCollate 2417 +#define wxPrintDialogData_GetFromPage 2418 +#define wxPrintDialogData_GetMaxPage 2419 +#define wxPrintDialogData_GetMinPage 2420 +#define wxPrintDialogData_GetNoCopies 2421 +#define wxPrintDialogData_GetPrintData 2422 +#define wxPrintDialogData_GetPrintToFile 2423 +#define wxPrintDialogData_GetSelection 2424 +#define wxPrintDialogData_GetToPage 2425 +#define wxPrintDialogData_IsOk 2426 +#define wxPrintDialogData_SetCollate 2427 +#define wxPrintDialogData_SetFromPage 2428 +#define wxPrintDialogData_SetMaxPage 2429 +#define wxPrintDialogData_SetMinPage 2430 +#define wxPrintDialogData_SetNoCopies 2431 +#define wxPrintDialogData_SetPrintData 2432 +#define wxPrintDialogData_SetPrintToFile 2433 +#define wxPrintDialogData_SetSelection 2434 +#define wxPrintDialogData_SetToPage 2435 +#define wxPrintData_new_0 2436 +#define wxPrintData_new_1 2437 +#define wxPrintData_destruct 2438 +#define wxPrintData_GetCollate 2439 +#define wxPrintData_GetBin 2440 +#define wxPrintData_GetColour 2441 +#define wxPrintData_GetDuplex 2442 +#define wxPrintData_GetNoCopies 2443 +#define wxPrintData_GetOrientation 2444 +#define wxPrintData_GetPaperId 2445 +#define wxPrintData_GetPrinterName 2446 +#define wxPrintData_GetQuality 2447 +#define wxPrintData_IsOk 2448 +#define wxPrintData_SetBin 2449 +#define wxPrintData_SetCollate 2450 +#define wxPrintData_SetColour 2451 +#define wxPrintData_SetDuplex 2452 +#define wxPrintData_SetNoCopies 2453 +#define wxPrintData_SetOrientation 2454 +#define wxPrintData_SetPaperId 2455 +#define wxPrintData_SetPrinterName 2456 +#define wxPrintData_SetQuality 2457 +#define wxPrintPreview_new_2 2460 +#define wxPrintPreview_new_3 2461 +#define wxPrintPreview_destruct 2463 +#define wxPrintPreview_GetCanvas 2464 +#define wxPrintPreview_GetCurrentPage 2465 +#define wxPrintPreview_GetFrame 2466 +#define wxPrintPreview_GetMaxPage 2467 +#define wxPrintPreview_GetMinPage 2468 +#define wxPrintPreview_GetPrintout 2469 +#define wxPrintPreview_GetPrintoutForPrinting 2470 +#define wxPrintPreview_IsOk 2471 +#define wxPrintPreview_PaintPage 2472 +#define wxPrintPreview_Print 2473 +#define wxPrintPreview_RenderPage 2474 +#define wxPrintPreview_SetCanvas 2475 +#define wxPrintPreview_SetCurrentPage 2476 +#define wxPrintPreview_SetFrame 2477 +#define wxPrintPreview_SetPrintout 2478 +#define wxPrintPreview_SetZoom 2479 +#define wxPreviewFrame_new 2480 +#define wxPreviewFrame_destruct 2481 +#define wxPreviewFrame_CreateControlBar 2482 +#define wxPreviewFrame_CreateCanvas 2483 +#define wxPreviewFrame_Initialize 2484 +#define wxPreviewFrame_OnCloseWindow 2485 +#define wxPreviewControlBar_new 2486 +#define wxPreviewControlBar_destruct 2487 +#define wxPreviewControlBar_CreateButtons 2488 +#define wxPreviewControlBar_GetPrintPreview 2489 +#define wxPreviewControlBar_GetZoomControl 2490 +#define wxPreviewControlBar_SetZoomControl 2491 +#define wxPrinter_new 2493 +#define wxPrinter_CreateAbortWindow 2494 +#define wxPrinter_GetAbort 2495 +#define wxPrinter_GetLastError 2496 +#define wxPrinter_GetPrintDialogData 2497 +#define wxPrinter_Print 2498 +#define wxPrinter_PrintDialog 2499 +#define wxPrinter_ReportError 2500 +#define wxPrinter_Setup 2501 +#define wxPrinter_destroy 2502 +#define wxXmlResource_new_1 2503 +#define wxXmlResource_new_2 2504 +#define wxXmlResource_destruct 2505 +#define wxXmlResource_AttachUnknownControl 2506 +#define wxXmlResource_ClearHandlers 2507 +#define wxXmlResource_CompareVersion 2508 +#define wxXmlResource_Get 2509 +#define wxXmlResource_GetFlags 2510 +#define wxXmlResource_GetVersion 2511 +#define wxXmlResource_GetXRCID 2512 +#define wxXmlResource_InitAllHandlers 2513 +#define wxXmlResource_Load 2514 +#define wxXmlResource_LoadBitmap 2515 +#define wxXmlResource_LoadDialog_2 2516 +#define wxXmlResource_LoadDialog_3 2517 +#define wxXmlResource_LoadFrame_2 2518 +#define wxXmlResource_LoadFrame_3 2519 +#define wxXmlResource_LoadIcon 2520 +#define wxXmlResource_LoadMenu 2521 +#define wxXmlResource_LoadMenuBar_2 2522 +#define wxXmlResource_LoadMenuBar_1 2523 +#define wxXmlResource_LoadPanel_2 2524 +#define wxXmlResource_LoadPanel_3 2525 +#define wxXmlResource_LoadToolBar 2526 +#define wxXmlResource_Set 2527 +#define wxXmlResource_SetFlags 2528 +#define wxXmlResource_Unload 2529 +#define wxXmlResource_xrcctrl 2530 +#define wxHtmlEasyPrinting_new 2531 +#define wxHtmlEasyPrinting_destruct 2532 +#define wxHtmlEasyPrinting_GetPrintData 2533 +#define wxHtmlEasyPrinting_GetPageSetupData 2534 +#define wxHtmlEasyPrinting_PreviewFile 2535 +#define wxHtmlEasyPrinting_PreviewText 2536 +#define wxHtmlEasyPrinting_PrintFile 2537 +#define wxHtmlEasyPrinting_PrintText 2538 +#define wxHtmlEasyPrinting_PageSetup 2539 +#define wxHtmlEasyPrinting_SetFonts 2540 +#define wxHtmlEasyPrinting_SetHeader 2541 +#define wxHtmlEasyPrinting_SetFooter 2542 +#define wxGLCanvas_new_2 2544 +#define wxGLCanvas_new_3_1 2545 +#define wxGLCanvas_new_3_0 2546 +#define wxGLCanvas_GetContext 2547 +#define wxGLCanvas_SetCurrent 2549 +#define wxGLCanvas_SwapBuffers 2550 +#define wxGLCanvas_destroy 2551 +#define wxAuiManager_new 2552 +#define wxAuiManager_destruct 2553 +#define wxAuiManager_AddPane_2_1 2554 +#define wxAuiManager_AddPane_3 2555 +#define wxAuiManager_AddPane_2_0 2556 +#define wxAuiManager_DetachPane 2557 +#define wxAuiManager_GetAllPanes 2558 +#define wxAuiManager_GetArtProvider 2559 +#define wxAuiManager_GetDockSizeConstraint 2560 +#define wxAuiManager_GetFlags 2561 +#define wxAuiManager_GetManagedWindow 2562 +#define wxAuiManager_GetManager 2563 +#define wxAuiManager_GetPane_1_1 2564 +#define wxAuiManager_GetPane_1_0 2565 +#define wxAuiManager_HideHint 2566 +#define wxAuiManager_InsertPane 2567 +#define wxAuiManager_LoadPaneInfo 2568 +#define wxAuiManager_LoadPerspective 2569 +#define wxAuiManager_SavePaneInfo 2570 +#define wxAuiManager_SavePerspective 2571 +#define wxAuiManager_SetArtProvider 2572 +#define wxAuiManager_SetDockSizeConstraint 2573 +#define wxAuiManager_SetFlags 2574 +#define wxAuiManager_SetManagedWindow 2575 +#define wxAuiManager_ShowHint 2576 +#define wxAuiManager_UnInit 2577 +#define wxAuiManager_Update 2578 +#define wxAuiPaneInfo_new_0 2579 +#define wxAuiPaneInfo_new_1 2580 +#define wxAuiPaneInfo_destruct 2581 +#define wxAuiPaneInfo_BestSize_1 2582 +#define wxAuiPaneInfo_BestSize_2 2583 +#define wxAuiPaneInfo_Bottom 2584 +#define wxAuiPaneInfo_BottomDockable 2585 +#define wxAuiPaneInfo_Caption 2586 +#define wxAuiPaneInfo_CaptionVisible 2587 +#define wxAuiPaneInfo_Centre 2588 +#define wxAuiPaneInfo_CentrePane 2589 +#define wxAuiPaneInfo_CloseButton 2590 +#define wxAuiPaneInfo_DefaultPane 2591 +#define wxAuiPaneInfo_DestroyOnClose 2592 +#define wxAuiPaneInfo_Direction 2593 +#define wxAuiPaneInfo_Dock 2594 +#define wxAuiPaneInfo_Dockable 2595 +#define wxAuiPaneInfo_Fixed 2596 +#define wxAuiPaneInfo_Float 2597 +#define wxAuiPaneInfo_Floatable 2598 +#define wxAuiPaneInfo_FloatingPosition_1 2599 +#define wxAuiPaneInfo_FloatingPosition_2 2600 +#define wxAuiPaneInfo_FloatingSize_1 2601 +#define wxAuiPaneInfo_FloatingSize_2 2602 +#define wxAuiPaneInfo_Gripper 2603 +#define wxAuiPaneInfo_GripperTop 2604 +#define wxAuiPaneInfo_HasBorder 2605 +#define wxAuiPaneInfo_HasCaption 2606 +#define wxAuiPaneInfo_HasCloseButton 2607 +#define wxAuiPaneInfo_HasFlag 2608 +#define wxAuiPaneInfo_HasGripper 2609 +#define wxAuiPaneInfo_HasGripperTop 2610 +#define wxAuiPaneInfo_HasMaximizeButton 2611 +#define wxAuiPaneInfo_HasMinimizeButton 2612 +#define wxAuiPaneInfo_HasPinButton 2613 +#define wxAuiPaneInfo_Hide 2614 +#define wxAuiPaneInfo_IsBottomDockable 2615 +#define wxAuiPaneInfo_IsDocked 2616 +#define wxAuiPaneInfo_IsFixed 2617 +#define wxAuiPaneInfo_IsFloatable 2618 +#define wxAuiPaneInfo_IsFloating 2619 +#define wxAuiPaneInfo_IsLeftDockable 2620 +#define wxAuiPaneInfo_IsMovable 2621 +#define wxAuiPaneInfo_IsOk 2622 +#define wxAuiPaneInfo_IsResizable 2623 +#define wxAuiPaneInfo_IsRightDockable 2624 +#define wxAuiPaneInfo_IsShown 2625 +#define wxAuiPaneInfo_IsToolbar 2626 +#define wxAuiPaneInfo_IsTopDockable 2627 +#define wxAuiPaneInfo_Layer 2628 +#define wxAuiPaneInfo_Left 2629 +#define wxAuiPaneInfo_LeftDockable 2630 +#define wxAuiPaneInfo_MaxSize_1 2631 +#define wxAuiPaneInfo_MaxSize_2 2632 +#define wxAuiPaneInfo_MaximizeButton 2633 +#define wxAuiPaneInfo_MinSize_1 2634 +#define wxAuiPaneInfo_MinSize_2 2635 +#define wxAuiPaneInfo_MinimizeButton 2636 +#define wxAuiPaneInfo_Movable 2637 +#define wxAuiPaneInfo_Name 2638 +#define wxAuiPaneInfo_PaneBorder 2639 +#define wxAuiPaneInfo_PinButton 2640 +#define wxAuiPaneInfo_Position 2641 +#define wxAuiPaneInfo_Resizable 2642 +#define wxAuiPaneInfo_Right 2643 +#define wxAuiPaneInfo_RightDockable 2644 +#define wxAuiPaneInfo_Row 2645 +#define wxAuiPaneInfo_SafeSet 2646 +#define wxAuiPaneInfo_SetFlag 2647 +#define wxAuiPaneInfo_Show 2648 +#define wxAuiPaneInfo_ToolbarPane 2649 +#define wxAuiPaneInfo_Top 2650 +#define wxAuiPaneInfo_TopDockable 2651 +#define wxAuiPaneInfo_Window 2652 +#define wxAuiNotebook_new_0 2653 +#define wxAuiNotebook_new_2 2654 +#define wxAuiNotebook_AddPage 2655 +#define wxAuiNotebook_Create 2656 +#define wxAuiNotebook_DeletePage 2657 +#define wxAuiNotebook_GetArtProvider 2658 +#define wxAuiNotebook_GetPage 2659 +#define wxAuiNotebook_GetPageBitmap 2660 +#define wxAuiNotebook_GetPageCount 2661 +#define wxAuiNotebook_GetPageIndex 2662 +#define wxAuiNotebook_GetPageText 2663 +#define wxAuiNotebook_GetSelection 2664 +#define wxAuiNotebook_InsertPage 2665 +#define wxAuiNotebook_RemovePage 2666 +#define wxAuiNotebook_SetArtProvider 2667 +#define wxAuiNotebook_SetFont 2668 +#define wxAuiNotebook_SetPageBitmap 2669 +#define wxAuiNotebook_SetPageText 2670 +#define wxAuiNotebook_SetSelection 2671 +#define wxAuiNotebook_SetTabCtrlHeight 2672 +#define wxAuiNotebook_SetUniformBitmapSize 2673 +#define wxAuiNotebook_destroy 2674 +#define wxMDIParentFrame_new_0 2675 +#define wxMDIParentFrame_new_4 2676 +#define wxMDIParentFrame_destruct 2677 +#define wxMDIParentFrame_ActivateNext 2678 +#define wxMDIParentFrame_ActivatePrevious 2679 +#define wxMDIParentFrame_ArrangeIcons 2680 +#define wxMDIParentFrame_Cascade 2681 +#define wxMDIParentFrame_Create 2682 +#define wxMDIParentFrame_GetActiveChild 2683 +#define wxMDIParentFrame_GetClientWindow 2684 +#define wxMDIParentFrame_Tile 2685 +#define wxMDIChildFrame_new_0 2686 +#define wxMDIChildFrame_new_4 2687 +#define wxMDIChildFrame_destruct 2688 +#define wxMDIChildFrame_Activate 2689 +#define wxMDIChildFrame_Create 2690 +#define wxMDIChildFrame_Maximize 2691 +#define wxMDIChildFrame_Restore 2692 +#define wxMDIClientWindow_new_0 2693 +#define wxMDIClientWindow_new_2 2694 +#define wxMDIClientWindow_destruct 2695 +#define wxMDIClientWindow_CreateClient 2696 +#define wxLayoutAlgorithm_new 2697 +#define wxLayoutAlgorithm_LayoutFrame 2698 +#define wxLayoutAlgorithm_LayoutMDIFrame 2699 +#define wxLayoutAlgorithm_LayoutWindow 2700 +#define wxLayoutAlgorithm_destroy 2701 +#define wxEvent_GetId 2702 +#define wxEvent_GetSkipped 2703 +#define wxEvent_GetTimestamp 2704 +#define wxEvent_IsCommandEvent 2705 +#define wxEvent_ResumePropagation 2706 +#define wxEvent_ShouldPropagate 2707 +#define wxEvent_Skip 2708 +#define wxEvent_StopPropagation 2709 +#define wxCommandEvent_getClientData 2710 +#define wxCommandEvent_GetExtraLong 2711 +#define wxCommandEvent_GetInt 2712 +#define wxCommandEvent_GetSelection 2713 +#define wxCommandEvent_GetString 2714 +#define wxCommandEvent_IsChecked 2715 +#define wxCommandEvent_IsSelection 2716 +#define wxCommandEvent_SetInt 2717 +#define wxCommandEvent_SetString 2718 +#define wxScrollEvent_GetOrientation 2719 +#define wxScrollEvent_GetPosition 2720 +#define wxScrollWinEvent_GetOrientation 2721 +#define wxScrollWinEvent_GetPosition 2722 +#define wxMouseEvent_AltDown 2723 +#define wxMouseEvent_Button 2724 +#define wxMouseEvent_ButtonDClick 2725 +#define wxMouseEvent_ButtonDown 2726 +#define wxMouseEvent_ButtonUp 2727 +#define wxMouseEvent_CmdDown 2728 +#define wxMouseEvent_ControlDown 2729 +#define wxMouseEvent_Dragging 2730 +#define wxMouseEvent_Entering 2731 +#define wxMouseEvent_GetButton 2732 +#define wxMouseEvent_GetPosition 2735 +#define wxMouseEvent_GetLogicalPosition 2736 +#define wxMouseEvent_GetLinesPerAction 2737 +#define wxMouseEvent_GetWheelRotation 2738 +#define wxMouseEvent_GetWheelDelta 2739 +#define wxMouseEvent_GetX 2740 +#define wxMouseEvent_GetY 2741 +#define wxMouseEvent_IsButton 2742 +#define wxMouseEvent_IsPageScroll 2743 +#define wxMouseEvent_Leaving 2744 +#define wxMouseEvent_LeftDClick 2745 +#define wxMouseEvent_LeftDown 2746 +#define wxMouseEvent_LeftIsDown 2747 +#define wxMouseEvent_LeftUp 2748 +#define wxMouseEvent_MetaDown 2749 +#define wxMouseEvent_MiddleDClick 2750 +#define wxMouseEvent_MiddleDown 2751 +#define wxMouseEvent_MiddleIsDown 2752 +#define wxMouseEvent_MiddleUp 2753 +#define wxMouseEvent_Moving 2754 +#define wxMouseEvent_RightDClick 2755 +#define wxMouseEvent_RightDown 2756 +#define wxMouseEvent_RightIsDown 2757 +#define wxMouseEvent_RightUp 2758 +#define wxMouseEvent_ShiftDown 2759 +#define wxSetCursorEvent_GetCursor 2760 +#define wxSetCursorEvent_GetX 2761 +#define wxSetCursorEvent_GetY 2762 +#define wxSetCursorEvent_HasCursor 2763 +#define wxSetCursorEvent_SetCursor 2764 +#define wxKeyEvent_AltDown 2765 +#define wxKeyEvent_CmdDown 2766 +#define wxKeyEvent_ControlDown 2767 +#define wxKeyEvent_GetKeyCode 2768 +#define wxKeyEvent_GetModifiers 2769 +#define wxKeyEvent_GetPosition 2772 +#define wxKeyEvent_GetRawKeyCode 2773 +#define wxKeyEvent_GetRawKeyFlags 2774 +#define wxKeyEvent_GetUnicodeKey 2775 +#define wxKeyEvent_GetX 2776 +#define wxKeyEvent_GetY 2777 +#define wxKeyEvent_HasModifiers 2778 +#define wxKeyEvent_MetaDown 2779 +#define wxKeyEvent_ShiftDown 2780 +#define wxSizeEvent_GetSize 2781 +#define wxMoveEvent_GetPosition 2782 +#define wxEraseEvent_GetDC 2783 +#define wxFocusEvent_GetWindow 2784 +#define wxChildFocusEvent_GetWindow 2785 +#define wxMenuEvent_GetMenu 2786 +#define wxMenuEvent_GetMenuId 2787 +#define wxMenuEvent_IsPopup 2788 +#define wxCloseEvent_CanVeto 2789 +#define wxCloseEvent_GetLoggingOff 2790 +#define wxCloseEvent_SetCanVeto 2791 +#define wxCloseEvent_SetLoggingOff 2792 +#define wxCloseEvent_Veto 2793 +#define wxShowEvent_SetShow 2794 +#define wxShowEvent_GetShow 2795 +#define wxIconizeEvent_Iconized 2796 +#define wxJoystickEvent_ButtonDown 2797 +#define wxJoystickEvent_ButtonIsDown 2798 +#define wxJoystickEvent_ButtonUp 2799 +#define wxJoystickEvent_GetButtonChange 2800 +#define wxJoystickEvent_GetButtonState 2801 +#define wxJoystickEvent_GetJoystick 2802 +#define wxJoystickEvent_GetPosition 2803 +#define wxJoystickEvent_GetZPosition 2804 +#define wxJoystickEvent_IsButton 2805 +#define wxJoystickEvent_IsMove 2806 +#define wxJoystickEvent_IsZMove 2807 +#define wxUpdateUIEvent_CanUpdate 2808 +#define wxUpdateUIEvent_Check 2809 +#define wxUpdateUIEvent_Enable 2810 +#define wxUpdateUIEvent_Show 2811 +#define wxUpdateUIEvent_GetChecked 2812 +#define wxUpdateUIEvent_GetEnabled 2813 +#define wxUpdateUIEvent_GetShown 2814 +#define wxUpdateUIEvent_GetSetChecked 2815 +#define wxUpdateUIEvent_GetSetEnabled 2816 +#define wxUpdateUIEvent_GetSetShown 2817 +#define wxUpdateUIEvent_GetSetText 2818 +#define wxUpdateUIEvent_GetText 2819 +#define wxUpdateUIEvent_GetMode 2820 +#define wxUpdateUIEvent_GetUpdateInterval 2821 +#define wxUpdateUIEvent_ResetUpdateTime 2822 +#define wxUpdateUIEvent_SetMode 2823 +#define wxUpdateUIEvent_SetText 2824 +#define wxUpdateUIEvent_SetUpdateInterval 2825 +#define wxMouseCaptureChangedEvent_GetCapturedWindow 2826 +#define wxPaletteChangedEvent_SetChangedWindow 2827 +#define wxPaletteChangedEvent_GetChangedWindow 2828 +#define wxQueryNewPaletteEvent_SetPaletteRealized 2829 +#define wxQueryNewPaletteEvent_GetPaletteRealized 2830 +#define wxNavigationKeyEvent_GetDirection 2831 +#define wxNavigationKeyEvent_SetDirection 2832 +#define wxNavigationKeyEvent_IsWindowChange 2833 +#define wxNavigationKeyEvent_SetWindowChange 2834 +#define wxNavigationKeyEvent_IsFromTab 2835 +#define wxNavigationKeyEvent_SetFromTab 2836 +#define wxNavigationKeyEvent_GetCurrentFocus 2837 +#define wxNavigationKeyEvent_SetCurrentFocus 2838 +#define wxHelpEvent_GetOrigin 2839 +#define wxHelpEvent_GetPosition 2840 +#define wxHelpEvent_SetOrigin 2841 +#define wxHelpEvent_SetPosition 2842 +#define wxContextMenuEvent_GetPosition 2843 +#define wxContextMenuEvent_SetPosition 2844 +#define wxIdleEvent_CanSend 2845 +#define wxIdleEvent_GetMode 2846 +#define wxIdleEvent_RequestMore 2847 +#define wxIdleEvent_MoreRequested 2848 +#define wxIdleEvent_SetMode 2849 +#define wxGridEvent_AltDown 2850 +#define wxGridEvent_ControlDown 2851 +#define wxGridEvent_GetCol 2852 +#define wxGridEvent_GetPosition 2853 +#define wxGridEvent_GetRow 2854 +#define wxGridEvent_MetaDown 2855 +#define wxGridEvent_Selecting 2856 +#define wxGridEvent_ShiftDown 2857 +#define wxNotifyEvent_Allow 2858 +#define wxNotifyEvent_IsAllowed 2859 +#define wxNotifyEvent_Veto 2860 +#define wxSashEvent_GetEdge 2861 +#define wxSashEvent_GetDragRect 2862 +#define wxSashEvent_GetDragStatus 2863 +#define wxListEvent_GetCacheFrom 2864 +#define wxListEvent_GetCacheTo 2865 +#define wxListEvent_GetKeyCode 2866 +#define wxListEvent_GetIndex 2867 +#define wxListEvent_GetColumn 2868 +#define wxListEvent_GetPoint 2869 +#define wxListEvent_GetLabel 2870 +#define wxListEvent_GetText 2871 +#define wxListEvent_GetImage 2872 +#define wxListEvent_GetData 2873 +#define wxListEvent_GetMask 2874 +#define wxListEvent_GetItem 2875 +#define wxListEvent_IsEditCancelled 2876 +#define wxDateEvent_GetDate 2877 +#define wxCalendarEvent_GetWeekDay 2878 +#define wxFileDirPickerEvent_GetPath 2879 +#define wxColourPickerEvent_GetColour 2880 +#define wxFontPickerEvent_GetFont 2881 +#define wxStyledTextEvent_GetPosition 2882 +#define wxStyledTextEvent_GetKey 2883 +#define wxStyledTextEvent_GetModifiers 2884 +#define wxStyledTextEvent_GetModificationType 2885 +#define wxStyledTextEvent_GetText 2886 +#define wxStyledTextEvent_GetLength 2887 +#define wxStyledTextEvent_GetLinesAdded 2888 +#define wxStyledTextEvent_GetLine 2889 +#define wxStyledTextEvent_GetFoldLevelNow 2890 +#define wxStyledTextEvent_GetFoldLevelPrev 2891 +#define wxStyledTextEvent_GetMargin 2892 +#define wxStyledTextEvent_GetMessage 2893 +#define wxStyledTextEvent_GetWParam 2894 +#define wxStyledTextEvent_GetLParam 2895 +#define wxStyledTextEvent_GetListType 2896 +#define wxStyledTextEvent_GetX 2897 +#define wxStyledTextEvent_GetY 2898 +#define wxStyledTextEvent_GetDragText 2899 +#define wxStyledTextEvent_GetDragAllowMove 2900 +#define wxStyledTextEvent_GetDragResult 2901 +#define wxStyledTextEvent_GetShift 2902 +#define wxStyledTextEvent_GetControl 2903 +#define wxStyledTextEvent_GetAlt 2904 +#define utils_wxGetKeyState 2905 +#define utils_wxGetMousePosition 2906 +#define utils_wxGetMouseState 2907 +#define utils_wxSetDetectableAutoRepeat 2908 +#define utils_wxBell 2909 +#define utils_wxFindMenuItemId 2910 +#define utils_wxGenericFindWindowAtPoint 2911 +#define utils_wxFindWindowAtPoint 2912 +#define utils_wxBeginBusyCursor 2913 +#define utils_wxEndBusyCursor 2914 +#define utils_wxIsBusy 2915 +#define utils_wxShutdown 2916 +#define utils_wxShell 2917 +#define utils_wxLaunchDefaultBrowser 2918 +#define utils_wxGetEmailAddress 2919 +#define utils_wxGetUserId 2920 +#define utils_wxGetHomeDir 2921 +#define utils_wxNewId 2922 +#define utils_wxRegisterId 2923 +#define utils_wxGetCurrentId 2924 +#define utils_wxGetOsDescription 2925 +#define utils_wxIsPlatformLittleEndian 2926 +#define utils_wxIsPlatform64Bit 2927 +#define wxPrintout_new 2928 +#define wxPrintout_destruct 2929 +#define wxPrintout_GetDC 2930 +#define wxPrintout_GetPageSizeMM 2931 +#define wxPrintout_GetPageSizePixels 2932 +#define wxPrintout_GetPaperRectPixels 2933 +#define wxPrintout_GetPPIPrinter 2934 +#define wxPrintout_GetPPIScreen 2935 +#define wxPrintout_GetTitle 2936 +#define wxPrintout_IsPreview 2937 +#define wxPrintout_FitThisSizeToPaper 2938 +#define wxPrintout_FitThisSizeToPage 2939 +#define wxPrintout_FitThisSizeToPageMargins 2940 +#define wxPrintout_MapScreenSizeToPaper 2941 +#define wxPrintout_MapScreenSizeToPage 2942 +#define wxPrintout_MapScreenSizeToPageMargins 2943 +#define wxPrintout_MapScreenSizeToDevice 2944 +#define wxPrintout_GetLogicalPaperRect 2945 +#define wxPrintout_GetLogicalPageRect 2946 +#define wxPrintout_GetLogicalPageMarginsRect 2947 +#define wxPrintout_SetLogicalOrigin 2948 +#define wxPrintout_OffsetLogicalOrigin 2949 +#define wxStyledTextCtrl_new_2 2950 +#define wxStyledTextCtrl_new_0 2951 +#define wxStyledTextCtrl_destruct 2952 +#define wxStyledTextCtrl_Create 2953 +#define wxStyledTextCtrl_AddText 2954 +#define wxStyledTextCtrl_AddStyledText 2955 +#define wxStyledTextCtrl_InsertText 2956 +#define wxStyledTextCtrl_ClearAll 2957 +#define wxStyledTextCtrl_ClearDocumentStyle 2958 +#define wxStyledTextCtrl_GetLength 2959 +#define wxStyledTextCtrl_GetCharAt 2960 +#define wxStyledTextCtrl_GetCurrentPos 2961 +#define wxStyledTextCtrl_GetAnchor 2962 +#define wxStyledTextCtrl_GetStyleAt 2963 +#define wxStyledTextCtrl_Redo 2964 +#define wxStyledTextCtrl_SetUndoCollection 2965 +#define wxStyledTextCtrl_SelectAll 2966 +#define wxStyledTextCtrl_SetSavePoint 2967 +#define wxStyledTextCtrl_GetStyledText 2968 +#define wxStyledTextCtrl_CanRedo 2969 +#define wxStyledTextCtrl_MarkerLineFromHandle 2970 +#define wxStyledTextCtrl_MarkerDeleteHandle 2971 +#define wxStyledTextCtrl_GetUndoCollection 2972 +#define wxStyledTextCtrl_GetViewWhiteSpace 2973 +#define wxStyledTextCtrl_SetViewWhiteSpace 2974 +#define wxStyledTextCtrl_PositionFromPoint 2975 +#define wxStyledTextCtrl_PositionFromPointClose 2976 +#define wxStyledTextCtrl_GotoLine 2977 +#define wxStyledTextCtrl_GotoPos 2978 +#define wxStyledTextCtrl_SetAnchor 2979 +#define wxStyledTextCtrl_GetCurLine 2980 +#define wxStyledTextCtrl_GetEndStyled 2981 +#define wxStyledTextCtrl_ConvertEOLs 2982 +#define wxStyledTextCtrl_GetEOLMode 2983 +#define wxStyledTextCtrl_SetEOLMode 2984 +#define wxStyledTextCtrl_StartStyling 2985 +#define wxStyledTextCtrl_SetStyling 2986 +#define wxStyledTextCtrl_GetBufferedDraw 2987 +#define wxStyledTextCtrl_SetBufferedDraw 2988 +#define wxStyledTextCtrl_SetTabWidth 2989 +#define wxStyledTextCtrl_GetTabWidth 2990 +#define wxStyledTextCtrl_SetCodePage 2991 +#define wxStyledTextCtrl_MarkerDefine 2992 +#define wxStyledTextCtrl_MarkerSetForeground 2993 +#define wxStyledTextCtrl_MarkerSetBackground 2994 +#define wxStyledTextCtrl_MarkerAdd 2995 +#define wxStyledTextCtrl_MarkerDelete 2996 +#define wxStyledTextCtrl_MarkerDeleteAll 2997 +#define wxStyledTextCtrl_MarkerGet 2998 +#define wxStyledTextCtrl_MarkerNext 2999 +#define wxStyledTextCtrl_MarkerPrevious 3000 +#define wxStyledTextCtrl_MarkerDefineBitmap 3001 +#define wxStyledTextCtrl_MarkerAddSet 3002 +#define wxStyledTextCtrl_MarkerSetAlpha 3003 +#define wxStyledTextCtrl_SetMarginType 3004 +#define wxStyledTextCtrl_GetMarginType 3005 +#define wxStyledTextCtrl_SetMarginWidth 3006 +#define wxStyledTextCtrl_GetMarginWidth 3007 +#define wxStyledTextCtrl_SetMarginMask 3008 +#define wxStyledTextCtrl_GetMarginMask 3009 +#define wxStyledTextCtrl_SetMarginSensitive 3010 +#define wxStyledTextCtrl_GetMarginSensitive 3011 +#define wxStyledTextCtrl_StyleClearAll 3012 +#define wxStyledTextCtrl_StyleSetForeground 3013 +#define wxStyledTextCtrl_StyleSetBackground 3014 +#define wxStyledTextCtrl_StyleSetBold 3015 +#define wxStyledTextCtrl_StyleSetItalic 3016 +#define wxStyledTextCtrl_StyleSetSize 3017 +#define wxStyledTextCtrl_StyleSetFaceName 3018 +#define wxStyledTextCtrl_StyleSetEOLFilled 3019 +#define wxStyledTextCtrl_StyleResetDefault 3020 +#define wxStyledTextCtrl_StyleSetUnderline 3021 +#define wxStyledTextCtrl_StyleSetCase 3022 +#define wxStyledTextCtrl_StyleSetHotSpot 3023 +#define wxStyledTextCtrl_SetSelForeground 3024 +#define wxStyledTextCtrl_SetSelBackground 3025 +#define wxStyledTextCtrl_GetSelAlpha 3026 +#define wxStyledTextCtrl_SetSelAlpha 3027 +#define wxStyledTextCtrl_SetCaretForeground 3028 +#define wxStyledTextCtrl_CmdKeyAssign 3029 +#define wxStyledTextCtrl_CmdKeyClear 3030 +#define wxStyledTextCtrl_CmdKeyClearAll 3031 +#define wxStyledTextCtrl_SetStyleBytes 3032 +#define wxStyledTextCtrl_StyleSetVisible 3033 +#define wxStyledTextCtrl_GetCaretPeriod 3034 +#define wxStyledTextCtrl_SetCaretPeriod 3035 +#define wxStyledTextCtrl_SetWordChars 3036 +#define wxStyledTextCtrl_BeginUndoAction 3037 +#define wxStyledTextCtrl_EndUndoAction 3038 +#define wxStyledTextCtrl_IndicatorSetStyle 3039 +#define wxStyledTextCtrl_IndicatorGetStyle 3040 +#define wxStyledTextCtrl_IndicatorSetForeground 3041 +#define wxStyledTextCtrl_IndicatorGetForeground 3042 +#define wxStyledTextCtrl_SetWhitespaceForeground 3043 +#define wxStyledTextCtrl_SetWhitespaceBackground 3044 +#define wxStyledTextCtrl_GetStyleBits 3045 +#define wxStyledTextCtrl_SetLineState 3046 +#define wxStyledTextCtrl_GetLineState 3047 +#define wxStyledTextCtrl_GetMaxLineState 3048 +#define wxStyledTextCtrl_GetCaretLineVisible 3049 +#define wxStyledTextCtrl_SetCaretLineVisible 3050 +#define wxStyledTextCtrl_GetCaretLineBackground 3051 +#define wxStyledTextCtrl_SetCaretLineBackground 3052 +#define wxStyledTextCtrl_AutoCompShow 3053 +#define wxStyledTextCtrl_AutoCompCancel 3054 +#define wxStyledTextCtrl_AutoCompActive 3055 +#define wxStyledTextCtrl_AutoCompPosStart 3056 +#define wxStyledTextCtrl_AutoCompComplete 3057 +#define wxStyledTextCtrl_AutoCompStops 3058 +#define wxStyledTextCtrl_AutoCompSetSeparator 3059 +#define wxStyledTextCtrl_AutoCompGetSeparator 3060 +#define wxStyledTextCtrl_AutoCompSelect 3061 +#define wxStyledTextCtrl_AutoCompSetCancelAtStart 3062 +#define wxStyledTextCtrl_AutoCompGetCancelAtStart 3063 +#define wxStyledTextCtrl_AutoCompSetFillUps 3064 +#define wxStyledTextCtrl_AutoCompSetChooseSingle 3065 +#define wxStyledTextCtrl_AutoCompGetChooseSingle 3066 +#define wxStyledTextCtrl_AutoCompSetIgnoreCase 3067 +#define wxStyledTextCtrl_AutoCompGetIgnoreCase 3068 +#define wxStyledTextCtrl_UserListShow 3069 +#define wxStyledTextCtrl_AutoCompSetAutoHide 3070 +#define wxStyledTextCtrl_AutoCompGetAutoHide 3071 +#define wxStyledTextCtrl_AutoCompSetDropRestOfWord 3072 +#define wxStyledTextCtrl_AutoCompGetDropRestOfWord 3073 +#define wxStyledTextCtrl_RegisterImage 3074 +#define wxStyledTextCtrl_ClearRegisteredImages 3075 +#define wxStyledTextCtrl_AutoCompGetTypeSeparator 3076 +#define wxStyledTextCtrl_AutoCompSetTypeSeparator 3077 +#define wxStyledTextCtrl_AutoCompSetMaxWidth 3078 +#define wxStyledTextCtrl_AutoCompGetMaxWidth 3079 +#define wxStyledTextCtrl_AutoCompSetMaxHeight 3080 +#define wxStyledTextCtrl_AutoCompGetMaxHeight 3081 +#define wxStyledTextCtrl_SetIndent 3082 +#define wxStyledTextCtrl_GetIndent 3083 +#define wxStyledTextCtrl_SetUseTabs 3084 +#define wxStyledTextCtrl_GetUseTabs 3085 +#define wxStyledTextCtrl_SetLineIndentation 3086 +#define wxStyledTextCtrl_GetLineIndentation 3087 +#define wxStyledTextCtrl_GetLineIndentPosition 3088 +#define wxStyledTextCtrl_GetColumn 3089 +#define wxStyledTextCtrl_SetUseHorizontalScrollBar 3090 +#define wxStyledTextCtrl_GetUseHorizontalScrollBar 3091 +#define wxStyledTextCtrl_SetIndentationGuides 3092 +#define wxStyledTextCtrl_GetIndentationGuides 3093 +#define wxStyledTextCtrl_SetHighlightGuide 3094 +#define wxStyledTextCtrl_GetHighlightGuide 3095 +#define wxStyledTextCtrl_GetLineEndPosition 3096 +#define wxStyledTextCtrl_GetCodePage 3097 +#define wxStyledTextCtrl_GetCaretForeground 3098 +#define wxStyledTextCtrl_GetReadOnly 3099 +#define wxStyledTextCtrl_SetCurrentPos 3100 +#define wxStyledTextCtrl_SetSelectionStart 3101 +#define wxStyledTextCtrl_GetSelectionStart 3102 +#define wxStyledTextCtrl_SetSelectionEnd 3103 +#define wxStyledTextCtrl_GetSelectionEnd 3104 +#define wxStyledTextCtrl_SetPrintMagnification 3105 +#define wxStyledTextCtrl_GetPrintMagnification 3106 +#define wxStyledTextCtrl_SetPrintColourMode 3107 +#define wxStyledTextCtrl_GetPrintColourMode 3108 +#define wxStyledTextCtrl_FindText 3109 +#define wxStyledTextCtrl_FormatRange 3110 +#define wxStyledTextCtrl_GetFirstVisibleLine 3111 +#define wxStyledTextCtrl_GetLine 3112 +#define wxStyledTextCtrl_GetLineCount 3113 +#define wxStyledTextCtrl_SetMarginLeft 3114 +#define wxStyledTextCtrl_GetMarginLeft 3115 +#define wxStyledTextCtrl_SetMarginRight 3116 +#define wxStyledTextCtrl_GetMarginRight 3117 +#define wxStyledTextCtrl_GetModify 3118 +#define wxStyledTextCtrl_SetSelection 3119 +#define wxStyledTextCtrl_GetSelectedText 3120 +#define wxStyledTextCtrl_GetTextRange 3121 +#define wxStyledTextCtrl_HideSelection 3122 +#define wxStyledTextCtrl_LineFromPosition 3123 +#define wxStyledTextCtrl_PositionFromLine 3124 +#define wxStyledTextCtrl_LineScroll 3125 +#define wxStyledTextCtrl_EnsureCaretVisible 3126 +#define wxStyledTextCtrl_ReplaceSelection 3127 +#define wxStyledTextCtrl_SetReadOnly 3128 +#define wxStyledTextCtrl_CanPaste 3129 +#define wxStyledTextCtrl_CanUndo 3130 +#define wxStyledTextCtrl_EmptyUndoBuffer 3131 +#define wxStyledTextCtrl_Undo 3132 +#define wxStyledTextCtrl_Cut 3133 +#define wxStyledTextCtrl_Copy 3134 +#define wxStyledTextCtrl_Paste 3135 +#define wxStyledTextCtrl_Clear 3136 +#define wxStyledTextCtrl_SetText 3137 +#define wxStyledTextCtrl_GetText 3138 +#define wxStyledTextCtrl_GetTextLength 3139 +#define wxStyledTextCtrl_GetOvertype 3140 +#define wxStyledTextCtrl_SetCaretWidth 3141 +#define wxStyledTextCtrl_GetCaretWidth 3142 +#define wxStyledTextCtrl_SetTargetStart 3143 +#define wxStyledTextCtrl_GetTargetStart 3144 +#define wxStyledTextCtrl_SetTargetEnd 3145 +#define wxStyledTextCtrl_GetTargetEnd 3146 +#define wxStyledTextCtrl_ReplaceTarget 3147 +#define wxStyledTextCtrl_SearchInTarget 3148 +#define wxStyledTextCtrl_SetSearchFlags 3149 +#define wxStyledTextCtrl_GetSearchFlags 3150 +#define wxStyledTextCtrl_CallTipShow 3151 +#define wxStyledTextCtrl_CallTipCancel 3152 +#define wxStyledTextCtrl_CallTipActive 3153 +#define wxStyledTextCtrl_CallTipPosAtStart 3154 +#define wxStyledTextCtrl_CallTipSetHighlight 3155 +#define wxStyledTextCtrl_CallTipSetBackground 3156 +#define wxStyledTextCtrl_CallTipSetForeground 3157 +#define wxStyledTextCtrl_CallTipSetForegroundHighlight 3158 +#define wxStyledTextCtrl_CallTipUseStyle 3159 +#define wxStyledTextCtrl_VisibleFromDocLine 3160 +#define wxStyledTextCtrl_DocLineFromVisible 3161 +#define wxStyledTextCtrl_WrapCount 3162 +#define wxStyledTextCtrl_SetFoldLevel 3163 +#define wxStyledTextCtrl_GetFoldLevel 3164 +#define wxStyledTextCtrl_GetLastChild 3165 +#define wxStyledTextCtrl_GetFoldParent 3166 +#define wxStyledTextCtrl_ShowLines 3167 +#define wxStyledTextCtrl_HideLines 3168 +#define wxStyledTextCtrl_GetLineVisible 3169 +#define wxStyledTextCtrl_SetFoldExpanded 3170 +#define wxStyledTextCtrl_GetFoldExpanded 3171 +#define wxStyledTextCtrl_ToggleFold 3172 +#define wxStyledTextCtrl_EnsureVisible 3173 +#define wxStyledTextCtrl_SetFoldFlags 3174 +#define wxStyledTextCtrl_EnsureVisibleEnforcePolicy 3175 +#define wxStyledTextCtrl_SetTabIndents 3176 +#define wxStyledTextCtrl_GetTabIndents 3177 +#define wxStyledTextCtrl_SetBackSpaceUnIndents 3178 +#define wxStyledTextCtrl_GetBackSpaceUnIndents 3179 +#define wxStyledTextCtrl_SetMouseDwellTime 3180 +#define wxStyledTextCtrl_GetMouseDwellTime 3181 +#define wxStyledTextCtrl_WordStartPosition 3182 +#define wxStyledTextCtrl_WordEndPosition 3183 +#define wxStyledTextCtrl_SetWrapMode 3184 +#define wxStyledTextCtrl_GetWrapMode 3185 +#define wxStyledTextCtrl_SetWrapVisualFlags 3186 +#define wxStyledTextCtrl_GetWrapVisualFlags 3187 +#define wxStyledTextCtrl_SetWrapVisualFlagsLocation 3188 +#define wxStyledTextCtrl_GetWrapVisualFlagsLocation 3189 +#define wxStyledTextCtrl_SetWrapStartIndent 3190 +#define wxStyledTextCtrl_GetWrapStartIndent 3191 +#define wxStyledTextCtrl_SetLayoutCache 3192 +#define wxStyledTextCtrl_GetLayoutCache 3193 +#define wxStyledTextCtrl_SetScrollWidth 3194 +#define wxStyledTextCtrl_GetScrollWidth 3195 +#define wxStyledTextCtrl_TextWidth 3196 +#define wxStyledTextCtrl_GetEndAtLastLine 3197 +#define wxStyledTextCtrl_TextHeight 3198 +#define wxStyledTextCtrl_SetUseVerticalScrollBar 3199 +#define wxStyledTextCtrl_GetUseVerticalScrollBar 3200 +#define wxStyledTextCtrl_AppendText 3201 +#define wxStyledTextCtrl_GetTwoPhaseDraw 3202 +#define wxStyledTextCtrl_SetTwoPhaseDraw 3203 +#define wxStyledTextCtrl_TargetFromSelection 3204 +#define wxStyledTextCtrl_LinesJoin 3205 +#define wxStyledTextCtrl_LinesSplit 3206 +#define wxStyledTextCtrl_SetFoldMarginColour 3207 +#define wxStyledTextCtrl_SetFoldMarginHiColour 3208 +#define wxStyledTextCtrl_LineDown 3209 +#define wxStyledTextCtrl_LineDownExtend 3210 +#define wxStyledTextCtrl_LineUp 3211 +#define wxStyledTextCtrl_LineUpExtend 3212 +#define wxStyledTextCtrl_CharLeft 3213 +#define wxStyledTextCtrl_CharLeftExtend 3214 +#define wxStyledTextCtrl_CharRight 3215 +#define wxStyledTextCtrl_CharRightExtend 3216 +#define wxStyledTextCtrl_WordLeft 3217 +#define wxStyledTextCtrl_WordLeftExtend 3218 +#define wxStyledTextCtrl_WordRight 3219 +#define wxStyledTextCtrl_WordRightExtend 3220 +#define wxStyledTextCtrl_Home 3221 +#define wxStyledTextCtrl_HomeExtend 3222 +#define wxStyledTextCtrl_LineEnd 3223 +#define wxStyledTextCtrl_LineEndExtend 3224 +#define wxStyledTextCtrl_DocumentStart 3225 +#define wxStyledTextCtrl_DocumentStartExtend 3226 +#define wxStyledTextCtrl_DocumentEnd 3227 +#define wxStyledTextCtrl_DocumentEndExtend 3228 +#define wxStyledTextCtrl_PageUp 3229 +#define wxStyledTextCtrl_PageUpExtend 3230 +#define wxStyledTextCtrl_PageDown 3231 +#define wxStyledTextCtrl_PageDownExtend 3232 +#define wxStyledTextCtrl_EditToggleOvertype 3233 +#define wxStyledTextCtrl_Cancel 3234 +#define wxStyledTextCtrl_DeleteBack 3235 +#define wxStyledTextCtrl_Tab 3236 +#define wxStyledTextCtrl_BackTab 3237 +#define wxStyledTextCtrl_NewLine 3238 +#define wxStyledTextCtrl_FormFeed 3239 +#define wxStyledTextCtrl_VCHome 3240 +#define wxStyledTextCtrl_VCHomeExtend 3241 +#define wxStyledTextCtrl_ZoomIn 3242 +#define wxStyledTextCtrl_ZoomOut 3243 +#define wxStyledTextCtrl_DelWordLeft 3244 +#define wxStyledTextCtrl_DelWordRight 3245 +#define wxStyledTextCtrl_LineCut 3246 +#define wxStyledTextCtrl_LineDelete 3247 +#define wxStyledTextCtrl_LineTranspose 3248 +#define wxStyledTextCtrl_LineDuplicate 3249 +#define wxStyledTextCtrl_LowerCase 3250 +#define wxStyledTextCtrl_UpperCase 3251 +#define wxStyledTextCtrl_LineScrollDown 3252 +#define wxStyledTextCtrl_LineScrollUp 3253 +#define wxStyledTextCtrl_DeleteBackNotLine 3254 +#define wxStyledTextCtrl_HomeDisplay 3255 +#define wxStyledTextCtrl_HomeDisplayExtend 3256 +#define wxStyledTextCtrl_LineEndDisplay 3257 +#define wxStyledTextCtrl_LineEndDisplayExtend 3258 +#define wxStyledTextCtrl_HomeWrapExtend 3259 +#define wxStyledTextCtrl_LineEndWrap 3260 +#define wxStyledTextCtrl_LineEndWrapExtend 3261 +#define wxStyledTextCtrl_VCHomeWrap 3262 +#define wxStyledTextCtrl_VCHomeWrapExtend 3263 +#define wxStyledTextCtrl_LineCopy 3264 +#define wxStyledTextCtrl_MoveCaretInsideView 3265 +#define wxStyledTextCtrl_LineLength 3266 +#define wxStyledTextCtrl_BraceHighlight 3267 +#define wxStyledTextCtrl_BraceBadLight 3268 +#define wxStyledTextCtrl_BraceMatch 3269 +#define wxStyledTextCtrl_GetViewEOL 3270 +#define wxStyledTextCtrl_SetViewEOL 3271 +#define wxStyledTextCtrl_SetModEventMask 3272 +#define wxStyledTextCtrl_GetEdgeColumn 3273 +#define wxStyledTextCtrl_SetEdgeColumn 3274 +#define wxStyledTextCtrl_SetEdgeMode 3275 +#define wxStyledTextCtrl_GetEdgeMode 3276 +#define wxStyledTextCtrl_GetEdgeColour 3277 +#define wxStyledTextCtrl_SetEdgeColour 3278 +#define wxStyledTextCtrl_SearchAnchor 3279 +#define wxStyledTextCtrl_SearchNext 3280 +#define wxStyledTextCtrl_SearchPrev 3281 +#define wxStyledTextCtrl_LinesOnScreen 3282 +#define wxStyledTextCtrl_UsePopUp 3283 +#define wxStyledTextCtrl_SelectionIsRectangle 3284 +#define wxStyledTextCtrl_SetZoom 3285 +#define wxStyledTextCtrl_GetZoom 3286 +#define wxStyledTextCtrl_GetModEventMask 3287 +#define wxStyledTextCtrl_SetSTCFocus 3288 +#define wxStyledTextCtrl_GetSTCFocus 3289 +#define wxStyledTextCtrl_SetStatus 3290 +#define wxStyledTextCtrl_GetStatus 3291 +#define wxStyledTextCtrl_SetMouseDownCaptures 3292 +#define wxStyledTextCtrl_GetMouseDownCaptures 3293 +#define wxStyledTextCtrl_SetSTCCursor 3294 +#define wxStyledTextCtrl_GetSTCCursor 3295 +#define wxStyledTextCtrl_SetControlCharSymbol 3296 +#define wxStyledTextCtrl_GetControlCharSymbol 3297 +#define wxStyledTextCtrl_WordPartLeft 3298 +#define wxStyledTextCtrl_WordPartLeftExtend 3299 +#define wxStyledTextCtrl_WordPartRight 3300 +#define wxStyledTextCtrl_WordPartRightExtend 3301 +#define wxStyledTextCtrl_SetVisiblePolicy 3302 +#define wxStyledTextCtrl_DelLineLeft 3303 +#define wxStyledTextCtrl_DelLineRight 3304 +#define wxStyledTextCtrl_GetXOffset 3305 +#define wxStyledTextCtrl_ChooseCaretX 3306 +#define wxStyledTextCtrl_SetXCaretPolicy 3307 +#define wxStyledTextCtrl_SetYCaretPolicy 3308 +#define wxStyledTextCtrl_GetPrintWrapMode 3309 +#define wxStyledTextCtrl_SetHotspotActiveForeground 3310 +#define wxStyledTextCtrl_SetHotspotActiveBackground 3311 +#define wxStyledTextCtrl_SetHotspotActiveUnderline 3312 +#define wxStyledTextCtrl_SetHotspotSingleLine 3313 +#define wxStyledTextCtrl_ParaDownExtend 3314 +#define wxStyledTextCtrl_ParaUp 3315 +#define wxStyledTextCtrl_ParaUpExtend 3316 +#define wxStyledTextCtrl_PositionBefore 3317 +#define wxStyledTextCtrl_PositionAfter 3318 +#define wxStyledTextCtrl_CopyRange 3319 +#define wxStyledTextCtrl_CopyText 3320 +#define wxStyledTextCtrl_SetSelectionMode 3321 +#define wxStyledTextCtrl_GetSelectionMode 3322 +#define wxStyledTextCtrl_LineDownRectExtend 3323 +#define wxStyledTextCtrl_LineUpRectExtend 3324 +#define wxStyledTextCtrl_CharLeftRectExtend 3325 +#define wxStyledTextCtrl_CharRightRectExtend 3326 +#define wxStyledTextCtrl_HomeRectExtend 3327 +#define wxStyledTextCtrl_VCHomeRectExtend 3328 +#define wxStyledTextCtrl_LineEndRectExtend 3329 +#define wxStyledTextCtrl_PageUpRectExtend 3330 +#define wxStyledTextCtrl_PageDownRectExtend 3331 +#define wxStyledTextCtrl_StutteredPageUp 3332 +#define wxStyledTextCtrl_StutteredPageUpExtend 3333 +#define wxStyledTextCtrl_StutteredPageDown 3334 +#define wxStyledTextCtrl_StutteredPageDownExtend 3335 +#define wxStyledTextCtrl_WordLeftEnd 3336 +#define wxStyledTextCtrl_WordLeftEndExtend 3337 +#define wxStyledTextCtrl_WordRightEnd 3338 +#define wxStyledTextCtrl_WordRightEndExtend 3339 +#define wxStyledTextCtrl_SetWhitespaceChars 3340 +#define wxStyledTextCtrl_SetCharsDefault 3341 +#define wxStyledTextCtrl_AutoCompGetCurrent 3342 +#define wxStyledTextCtrl_Allocate 3343 +#define wxStyledTextCtrl_FindColumn 3344 +#define wxStyledTextCtrl_GetCaretSticky 3345 +#define wxStyledTextCtrl_SetCaretSticky 3346 +#define wxStyledTextCtrl_ToggleCaretSticky 3347 +#define wxStyledTextCtrl_SetPasteConvertEndings 3348 +#define wxStyledTextCtrl_GetPasteConvertEndings 3349 +#define wxStyledTextCtrl_SelectionDuplicate 3350 +#define wxStyledTextCtrl_SetCaretLineBackAlpha 3351 +#define wxStyledTextCtrl_GetCaretLineBackAlpha 3352 +#define wxStyledTextCtrl_StartRecord 3353 +#define wxStyledTextCtrl_StopRecord 3354 +#define wxStyledTextCtrl_SetLexer 3355 +#define wxStyledTextCtrl_GetLexer 3356 +#define wxStyledTextCtrl_Colourise 3357 +#define wxStyledTextCtrl_SetProperty 3358 +#define wxStyledTextCtrl_SetKeyWords 3359 +#define wxStyledTextCtrl_SetLexerLanguage 3360 +#define wxStyledTextCtrl_GetProperty 3361 +#define wxStyledTextCtrl_GetStyleBitsNeeded 3362 +#define wxStyledTextCtrl_GetCurrentLine 3363 +#define wxStyledTextCtrl_StyleSetSpec 3364 +#define wxStyledTextCtrl_StyleSetFont 3365 +#define wxStyledTextCtrl_StyleSetFontAttr 3366 +#define wxStyledTextCtrl_StyleSetCharacterSet 3367 +#define wxStyledTextCtrl_StyleSetFontEncoding 3368 +#define wxStyledTextCtrl_CmdKeyExecute 3369 +#define wxStyledTextCtrl_SetMargins 3370 +#define wxStyledTextCtrl_GetSelection 3371 +#define wxStyledTextCtrl_PointFromPosition 3372 +#define wxStyledTextCtrl_ScrollToLine 3373 +#define wxStyledTextCtrl_ScrollToColumn 3374 +#define wxStyledTextCtrl_SetVScrollBar 3375 +#define wxStyledTextCtrl_SetHScrollBar 3376 +#define wxStyledTextCtrl_GetLastKeydownProcessed 3377 +#define wxStyledTextCtrl_SetLastKeydownProcessed 3378 +#define wxStyledTextCtrl_SaveFile 3379 +#define wxStyledTextCtrl_LoadFile 3380 +#define wxStyledTextCtrl_DoDragOver 3381 +#define wxStyledTextCtrl_DoDropText 3382 +#define wxStyledTextCtrl_GetUseAntiAliasing 3383 +#define wxStyledTextCtrl_AddTextRaw 3384 +#define wxStyledTextCtrl_InsertTextRaw 3385 +#define wxStyledTextCtrl_GetCurLineRaw 3386 +#define wxStyledTextCtrl_GetLineRaw 3387 +#define wxStyledTextCtrl_GetSelectedTextRaw 3388 +#define wxStyledTextCtrl_GetTextRangeRaw 3389 +#define wxStyledTextCtrl_SetTextRaw 3390 +#define wxStyledTextCtrl_GetTextRaw 3391 +#define wxStyledTextCtrl_AppendTextRaw 3392 +#define wxArtProvider_GetBitmap 3393 +#define wxArtProvider_GetIcon 3394 +#define wxTreeEvent_GetKeyCode 3395 +#define wxTreeEvent_GetItem 3396 +#define wxTreeEvent_GetKeyEvent 3397 +#define wxTreeEvent_GetLabel 3398 +#define wxTreeEvent_GetOldItem 3399 +#define wxTreeEvent_GetPoint 3400 +#define wxTreeEvent_IsEditCancelled 3401 +#define wxTreeEvent_SetToolTip 3402 +#define wxNotebookEvent_GetOldSelection 3403 +#define wxNotebookEvent_GetSelection 3404 +#define wxNotebookEvent_SetOldSelection 3405 +#define wxNotebookEvent_SetSelection 3406 +#define wxFileDataObject_new 3407 +#define wxFileDataObject_AddFile 3408 +#define wxFileDataObject_GetFilenames 3409 +#define wxFileDataObject_destroy 3410 +#define wxTextDataObject_new 3411 +#define wxTextDataObject_GetTextLength 3412 +#define wxTextDataObject_GetText 3413 +#define wxTextDataObject_SetText 3414 +#define wxTextDataObject_destroy 3415 +#define wxBitmapDataObject_new_1_1 3416 +#define wxBitmapDataObject_new_1_0 3417 +#define wxBitmapDataObject_GetBitmap 3418 +#define wxBitmapDataObject_SetBitmap 3419 +#define wxBitmapDataObject_destroy 3420 +#define wxClipboard_new 3422 +#define wxClipboard_destruct 3423 +#define wxClipboard_AddData 3424 +#define wxClipboard_Clear 3425 +#define wxClipboard_Close 3426 +#define wxClipboard_Flush 3427 +#define wxClipboard_GetData 3428 +#define wxClipboard_IsOpened 3429 +#define wxClipboard_Open 3430 +#define wxClipboard_SetData 3431 +#define wxClipboard_UsePrimarySelection 3433 +#define wxClipboard_IsSupported 3434 +#define wxClipboard_Get 3435 +#define wxSpinEvent_GetPosition 3436 +#define wxSpinEvent_SetPosition 3437 +#define wxSplitterWindow_new_0 3438 +#define wxSplitterWindow_new_2 3439 +#define wxSplitterWindow_destruct 3440 +#define wxSplitterWindow_Create 3441 +#define wxSplitterWindow_GetMinimumPaneSize 3442 +#define wxSplitterWindow_GetSashGravity 3443 +#define wxSplitterWindow_GetSashPosition 3444 +#define wxSplitterWindow_GetSplitMode 3445 +#define wxSplitterWindow_GetWindow1 3446 +#define wxSplitterWindow_GetWindow2 3447 +#define wxSplitterWindow_Initialize 3448 +#define wxSplitterWindow_IsSplit 3449 +#define wxSplitterWindow_ReplaceWindow 3450 +#define wxSplitterWindow_SetSashGravity 3451 +#define wxSplitterWindow_SetSashPosition 3452 +#define wxSplitterWindow_SetSashSize 3453 +#define wxSplitterWindow_SetMinimumPaneSize 3454 +#define wxSplitterWindow_SetSplitMode 3455 +#define wxSplitterWindow_SplitHorizontally 3456 +#define wxSplitterWindow_SplitVertically 3457 +#define wxSplitterWindow_Unsplit 3458 +#define wxSplitterWindow_UpdateSize 3459 +#define wxSplitterEvent_GetSashPosition 3460 +#define wxSplitterEvent_GetX 3461 +#define wxSplitterEvent_GetY 3462 +#define wxSplitterEvent_GetWindowBeingRemoved 3463 +#define wxSplitterEvent_SetSashPosition 3464 +#define wxHtmlWindow_new_0 3465 +#define wxHtmlWindow_new_2 3466 +#define wxHtmlWindow_AppendToPage 3467 +#define wxHtmlWindow_GetOpenedAnchor 3468 +#define wxHtmlWindow_GetOpenedPage 3469 +#define wxHtmlWindow_GetOpenedPageTitle 3470 +#define wxHtmlWindow_GetRelatedFrame 3471 +#define wxHtmlWindow_HistoryBack 3472 +#define wxHtmlWindow_HistoryCanBack 3473 +#define wxHtmlWindow_HistoryCanForward 3474 +#define wxHtmlWindow_HistoryClear 3475 +#define wxHtmlWindow_HistoryForward 3476 +#define wxHtmlWindow_LoadFile 3477 +#define wxHtmlWindow_LoadPage 3478 +#define wxHtmlWindow_SelectAll 3479 +#define wxHtmlWindow_SelectionToText 3480 +#define wxHtmlWindow_SelectLine 3481 +#define wxHtmlWindow_SelectWord 3482 +#define wxHtmlWindow_SetBorders 3483 +#define wxHtmlWindow_SetFonts 3484 +#define wxHtmlWindow_SetPage 3485 +#define wxHtmlWindow_SetRelatedFrame 3486 +#define wxHtmlWindow_SetRelatedStatusBar 3487 +#define wxHtmlWindow_ToText 3488 +#define wxHtmlWindow_destroy 3489 +#define wxHtmlLinkEvent_GetLinkInfo 3490 +#define wxSystemSettings_GetColour 3491 +#define wxSystemSettings_GetFont 3492 +#define wxSystemSettings_GetMetric 3493 +#define wxSystemSettings_GetScreenType 3494 +#define wxSystemOptions_GetOption 3495 +#define wxSystemOptions_GetOptionInt 3496 +#define wxSystemOptions_HasOption 3497 +#define wxSystemOptions_IsFalse 3498 +#define wxSystemOptions_SetOption_2_1 3499 +#define wxSystemOptions_SetOption_2_0 3500 +#define wxAuiNotebookEvent_SetSelection 3501 +#define wxAuiNotebookEvent_GetSelection 3502 +#define wxAuiNotebookEvent_SetOldSelection 3503 +#define wxAuiNotebookEvent_GetOldSelection 3504 +#define wxAuiNotebookEvent_SetDragSource 3505 +#define wxAuiNotebookEvent_GetDragSource 3506 +#define wxAuiManagerEvent_SetManager 3507 +#define wxAuiManagerEvent_GetManager 3508 +#define wxAuiManagerEvent_SetPane 3509 +#define wxAuiManagerEvent_GetPane 3510 +#define wxAuiManagerEvent_SetButton 3511 +#define wxAuiManagerEvent_GetButton 3512 +#define wxAuiManagerEvent_SetDC 3513 +#define wxAuiManagerEvent_GetDC 3514 +#define wxAuiManagerEvent_Veto 3515 +#define wxAuiManagerEvent_GetVeto 3516 +#define wxAuiManagerEvent_SetCanVeto 3517 +#define wxAuiManagerEvent_CanVeto 3518 +#define wxLogNull_new 3519 +#define wxLogNull_destroy 3520 +#define wxTaskBarIcon_new 3521 +#define wxTaskBarIcon_destruct 3522 +#define wxTaskBarIcon_PopupMenu 3523 +#define wxTaskBarIcon_RemoveIcon 3524 +#define wxTaskBarIcon_SetIcon 3525 diff --git a/lib/wx/include/wx.hrl b/lib/wx/include/wx.hrl index a48c756dea..aa1c81ac0f 100644 --- a/lib/wx/include/wx.hrl +++ b/lib/wx/include/wx.hrl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2012. All Rights Reserved. +%% Copyright Ericsson AB 2008-2013. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -255,6 +255,10 @@ -type wxMouseEventType() :: left_down | left_up | middle_down | middle_up | right_down | right_up | motion | enter_window | leave_window | left_dclick | middle_dclick | right_dclick | mousewheel. -type wxMouse() :: #wxMouse{}. %% Callback event: {@link wxMouseEvent} +-record(wxClipboardText, {type :: wxClipboardTextEventType()}). %% Callback event: {@link wxClipboardTextEvent} +-type wxClipboardTextEventType() :: command_text_copy | command_text_cut | command_text_paste. +-type wxClipboardText() :: #wxClipboardText{}. %% Callback event: {@link wxClipboardTextEvent} + -record(wxWindowCreate, {type :: wxWindowCreateEventType()}). %% Callback event: {@link wxWindowCreateEvent} -type wxWindowCreateEventType() :: create. -type wxWindowCreate() :: #wxWindowCreate{}. %% Callback event: {@link wxWindowCreateEvent} @@ -308,8 +312,8 @@ -type wxTreeEventType() :: command_tree_begin_drag | command_tree_begin_rdrag | command_tree_begin_label_edit | command_tree_end_label_edit | command_tree_delete_item | command_tree_get_info | command_tree_set_info | command_tree_item_expanded | command_tree_item_expanding | command_tree_item_collapsed | command_tree_item_collapsing | command_tree_sel_changed | command_tree_sel_changing | command_tree_key_down | command_tree_item_activated | command_tree_item_right_click | command_tree_item_middle_click | command_tree_end_drag | command_tree_state_image_click | command_tree_item_gettooltip | command_tree_item_menu. -type wxTree() :: #wxTree{}. %% Callback event: {@link wxTreeEvent} --type event() :: wxAuiManager() | wxAuiNotebook() | wxCalendar() | wxChildFocus() | wxClose() | wxColourPicker() | wxCommand() | wxContextMenu() | wxDate() | wxDisplayChanged() | wxErase() | wxFileDirPicker() | wxFocus() | wxFontPicker() | wxGrid() | wxHelp() | wxHtmlLink() | wxIconize() | wxIdle() | wxJoystick() | wxKey() | wxList() | wxMaximize() | wxMenu() | wxMouse() | wxMouseCaptureChanged() | wxMove() | wxNavigationKey() | wxNotebook() | wxPaint() | wxPaletteChanged() | wxQueryNewPalette() | wxSash() | wxScroll() | wxScrollWin() | wxSetCursor() | wxShow() | wxSize() | wxSpin() | wxSplitter() | wxStyledText() | wxSysColourChanged() | wxTaskBarIcon() | wxTree() | wxUpdateUI() | wxWindowCreate() | wxWindowDestroy(). --type wxEventType() :: wxAuiManagerEventType() | wxAuiNotebookEventType() | wxCalendarEventType() | wxChildFocusEventType() | wxCloseEventType() | wxColourPickerEventType() | wxCommandEventType() | wxContextMenuEventType() | wxDateEventType() | wxDisplayChangedEventType() | wxEraseEventType() | wxFileDirPickerEventType() | wxFocusEventType() | wxFontPickerEventType() | wxGridEventType() | wxHelpEventType() | wxHtmlLinkEventType() | wxIconizeEventType() | wxIdleEventType() | wxJoystickEventType() | wxKeyEventType() | wxListEventType() | wxMaximizeEventType() | wxMenuEventType() | wxMouseCaptureChangedEventType() | wxMouseEventType() | wxMoveEventType() | wxNavigationKeyEventType() | wxNotebookEventType() | wxPaintEventType() | wxPaletteChangedEventType() | wxQueryNewPaletteEventType() | wxSashEventType() | wxScrollEventType() | wxScrollWinEventType() | wxSetCursorEventType() | wxShowEventType() | wxSizeEventType() | wxSpinEventType() | wxSplitterEventType() | wxStyledTextEventType() | wxSysColourChangedEventType() | wxTaskBarIconEventType() | wxTreeEventType() | wxUpdateUIEventType() | wxWindowCreateEventType() | wxWindowDestroyEventType(). +-type event() :: wxAuiManager() | wxAuiNotebook() | wxCalendar() | wxChildFocus() | wxClipboardText() | wxClose() | wxColourPicker() | wxCommand() | wxContextMenu() | wxDate() | wxDisplayChanged() | wxErase() | wxFileDirPicker() | wxFocus() | wxFontPicker() | wxGrid() | wxHelp() | wxHtmlLink() | wxIconize() | wxIdle() | wxJoystick() | wxKey() | wxList() | wxMaximize() | wxMenu() | wxMouse() | wxMouseCaptureChanged() | wxMove() | wxNavigationKey() | wxNotebook() | wxPaint() | wxPaletteChanged() | wxQueryNewPalette() | wxSash() | wxScroll() | wxScrollWin() | wxSetCursor() | wxShow() | wxSize() | wxSpin() | wxSplitter() | wxStyledText() | wxSysColourChanged() | wxTaskBarIcon() | wxTree() | wxUpdateUI() | wxWindowCreate() | wxWindowDestroy(). +-type wxEventType() :: wxAuiManagerEventType() | wxAuiNotebookEventType() | wxCalendarEventType() | wxChildFocusEventType() | wxClipboardTextEventType() | wxCloseEventType() | wxColourPickerEventType() | wxCommandEventType() | wxContextMenuEventType() | wxDateEventType() | wxDisplayChangedEventType() | wxEraseEventType() | wxFileDirPickerEventType() | wxFocusEventType() | wxFontPickerEventType() | wxGridEventType() | wxHelpEventType() | wxHtmlLinkEventType() | wxIconizeEventType() | wxIdleEventType() | wxJoystickEventType() | wxKeyEventType() | wxListEventType() | wxMaximizeEventType() | wxMenuEventType() | wxMouseCaptureChangedEventType() | wxMouseEventType() | wxMoveEventType() | wxNavigationKeyEventType() | wxNotebookEventType() | wxPaintEventType() | wxPaletteChangedEventType() | wxQueryNewPaletteEventType() | wxSashEventType() | wxScrollEventType() | wxScrollWinEventType() | wxSetCursorEventType() | wxShowEventType() | wxSizeEventType() | wxSpinEventType() | wxSplitterEventType() | wxStyledTextEventType() | wxSysColourChangedEventType() | wxTaskBarIconEventType() | wxTreeEventType() | wxUpdateUIEventType() | wxWindowCreateEventType() | wxWindowDestroyEventType(). %% Hardcoded Records -record(wxMouseState, {x :: integer(), y :: integer(), diff --git a/lib/wx/src/gen/wxClipboardTextEvent.erl b/lib/wx/src/gen/wxClipboardTextEvent.erl new file mode 100644 index 0000000000..ff040ce7fd --- /dev/null +++ b/lib/wx/src/gen/wxClipboardTextEvent.erl @@ -0,0 +1,87 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2008-2013. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% This file is generated DO NOT EDIT + +%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxclipboardtextevent.html">wxClipboardTextEvent</a>. +%% <dl><dt>Use {@link wxEvtHandler:connect/3.} with EventType:</dt> +%% <dd><em>command_text_copy</em>, <em>command_text_cut</em>, <em>command_text_paste</em></dd></dl> +%% See also the message variant {@link wxEvtHandler:wxClipboardText(). #wxClipboardText{}} event record type. +%% +%% <p>This class is derived (and can use functions) from: +%% <br />{@link wxCommandEvent} +%% <br />{@link wxEvent} +%% </p> +%% @type wxClipboardTextEvent(). An object reference, The representation is internal +%% and can be changed without notice. It can't be used for comparsion +%% stored on disc or distributed for use on other nodes. + +-module(wxClipboardTextEvent). +-include("wxe.hrl"). +-export([]). + +%% inherited exports +-export([getClientData/1,getExtraLong/1,getId/1,getInt/1,getSelection/1,getSkipped/1, + getString/1,getTimestamp/1,isChecked/1,isCommandEvent/1,isSelection/1, + parent_class/1,resumePropagation/2,setInt/2,setString/2,shouldPropagate/1, + skip/1,skip/2,stopPropagation/1]). + +-export_type([wxClipboardTextEvent/0]). +%% @hidden +parent_class(wxCommandEvent) -> true; +parent_class(wxEvent) -> true; +parent_class(_Class) -> erlang:error({badtype, ?MODULE}). + +-type wxClipboardTextEvent() :: wx:wx_object(). + %% From wxCommandEvent +%% @hidden +setString(This,S) -> wxCommandEvent:setString(This,S). +%% @hidden +setInt(This,I) -> wxCommandEvent:setInt(This,I). +%% @hidden +isSelection(This) -> wxCommandEvent:isSelection(This). +%% @hidden +isChecked(This) -> wxCommandEvent:isChecked(This). +%% @hidden +getString(This) -> wxCommandEvent:getString(This). +%% @hidden +getSelection(This) -> wxCommandEvent:getSelection(This). +%% @hidden +getInt(This) -> wxCommandEvent:getInt(This). +%% @hidden +getExtraLong(This) -> wxCommandEvent:getExtraLong(This). +%% @hidden +getClientData(This) -> wxCommandEvent:getClientData(This). + %% From wxEvent +%% @hidden +stopPropagation(This) -> wxEvent:stopPropagation(This). +%% @hidden +skip(This, Options) -> wxEvent:skip(This, Options). +%% @hidden +skip(This) -> wxEvent:skip(This). +%% @hidden +shouldPropagate(This) -> wxEvent:shouldPropagate(This). +%% @hidden +resumePropagation(This,PropagationLevel) -> wxEvent:resumePropagation(This,PropagationLevel). +%% @hidden +isCommandEvent(This) -> wxEvent:isCommandEvent(This). +%% @hidden +getTimestamp(This) -> wxEvent:getTimestamp(This). +%% @hidden +getSkipped(This) -> wxEvent:getSkipped(This). +%% @hidden +getId(This) -> wxEvent:getId(This). diff --git a/lib/wx/src/gen/wxGrid.erl b/lib/wx/src/gen/wxGrid.erl index 2f4b45b1bc..39cb084e2f 100644 --- a/lib/wx/src/gen/wxGrid.erl +++ b/lib/wx/src/gen/wxGrid.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2012. All Rights Reserved. +%% Copyright Ericsson AB 2008-2013. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -112,13 +112,13 @@ scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,setAutoLayout/2, setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2, setClientSize/3,setContainingSizer/2,setCursor/2,setDropTarget/2, - setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,setForegroundColour/2, - setHelpText/2,setId/2,setLabel/2,setMaxSize/2,setMinSize/2,setName/2, - setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,setPalette/2, - setScrollPos/3,setScrollPos/4,setScrollRate/3,setScrollbar/5,setScrollbar/6, - setScrollbars/5,setScrollbars/6,setSize/2,setSize/3,setSize/5,setSize/6, - setSizeHints/2,setSizeHints/3,setSizeHints/4,setSizer/2,setSizer/3, - setSizerAndFit/2,setSizerAndFit/3,setTargetWindow/2,setThemeEnabled/2, + setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFocusIgnoringChildren/1, + setFont/2,setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2, + setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2, + setPalette/2,setScrollPos/3,setScrollPos/4,setScrollRate/3,setScrollbar/5, + setScrollbar/6,setScrollbars/5,setScrollbars/6,setSize/2,setSize/3, + setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,setSizeHints/4,setSizer/2, + setSizer/3,setSizerAndFit/2,setSizerAndFit/3,setTargetWindow/2,setThemeEnabled/2, setToolTip/2,setVirtualSize/2,setVirtualSize/3,setVirtualSizeHints/2, setVirtualSizeHints/3,setVirtualSizeHints/4,setWindowStyle/2,setWindowStyleFlag/2, setWindowVariant/2,shouldInheritColours/1,show/1,show/2,thaw/1,transferDataFromWindow/1, @@ -2151,6 +2151,8 @@ calcScrolledPosition(This,X,Y) -> wxScrolledWindow:calcScrolledPosition(This,X,Y calcScrolledPosition(This,Pt) -> wxScrolledWindow:calcScrolledPosition(This,Pt). %% From wxPanel %% @hidden +setFocusIgnoringChildren(This) -> wxPanel:setFocusIgnoringChildren(This). +%% @hidden initDialog(This) -> wxPanel:initDialog(This). %% From wxWindow %% @hidden diff --git a/lib/wx/src/gen/wxHtmlWindow.erl b/lib/wx/src/gen/wxHtmlWindow.erl index 4820f7d075..bbe1445463 100644 --- a/lib/wx/src/gen/wxHtmlWindow.erl +++ b/lib/wx/src/gen/wxHtmlWindow.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2009-2012. All Rights Reserved. +%% Copyright Ericsson AB 2009-2013. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -66,13 +66,13 @@ scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,setAutoLayout/2, setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2, setClientSize/3,setContainingSizer/2,setCursor/2,setDropTarget/2, - setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,setForegroundColour/2, - setHelpText/2,setId/2,setLabel/2,setMaxSize/2,setMinSize/2,setName/2, - setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,setPalette/2, - setScrollPos/3,setScrollPos/4,setScrollRate/3,setScrollbar/5,setScrollbar/6, - setScrollbars/5,setScrollbars/6,setSize/2,setSize/3,setSize/5,setSize/6, - setSizeHints/2,setSizeHints/3,setSizeHints/4,setSizer/2,setSizer/3, - setSizerAndFit/2,setSizerAndFit/3,setTargetWindow/2,setThemeEnabled/2, + setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFocusIgnoringChildren/1, + setFont/2,setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2, + setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2, + setPalette/2,setScrollPos/3,setScrollPos/4,setScrollRate/3,setScrollbar/5, + setScrollbar/6,setScrollbars/5,setScrollbars/6,setSize/2,setSize/3, + setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,setSizeHints/4,setSizer/2, + setSizer/3,setSizerAndFit/2,setSizerAndFit/3,setTargetWindow/2,setThemeEnabled/2, setToolTip/2,setVirtualSize/2,setVirtualSize/3,setVirtualSizeHints/2, setVirtualSizeHints/3,setVirtualSizeHints/4,setWindowStyle/2,setWindowStyleFlag/2, setWindowVariant/2,shouldInheritColours/1,show/1,show/2,thaw/1,transferDataFromWindow/1, @@ -364,6 +364,8 @@ calcScrolledPosition(This,X,Y) -> wxScrolledWindow:calcScrolledPosition(This,X,Y calcScrolledPosition(This,Pt) -> wxScrolledWindow:calcScrolledPosition(This,Pt). %% From wxPanel %% @hidden +setFocusIgnoringChildren(This) -> wxPanel:setFocusIgnoringChildren(This). +%% @hidden initDialog(This) -> wxPanel:initDialog(This). %% From wxWindow %% @hidden diff --git a/lib/wx/src/gen/wxPanel.erl b/lib/wx/src/gen/wxPanel.erl index 88c1b119a8..30a0e32ffc 100644 --- a/lib/wx/src/gen/wxPanel.erl +++ b/lib/wx/src/gen/wxPanel.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2012. All Rights Reserved. +%% Copyright Ericsson AB 2008-2013. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -28,7 +28,7 @@ -module(wxPanel). -include("wxe.hrl"). --export([destroy/1,initDialog/1,new/0,new/1,new/2,new/5,new/6]). +-export([destroy/1,initDialog/1,new/0,new/1,new/2,new/5,new/6,setFocusIgnoringChildren/1]). %% inherited exports -export([cacheBestSize/2,captureMouse/1,center/1,center/2,centerOnParent/1, @@ -137,6 +137,14 @@ initDialog(#wx_ref{type=ThisT,ref=ThisRef}) -> wxe_util:cast(?wxPanel_InitDialog, <<ThisRef:32/?UI>>). +%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxpanel.html#wxpanelsetfocusignoringchildren">external documentation</a>. +-spec setFocusIgnoringChildren(This) -> ok when + This::wxPanel(). +setFocusIgnoringChildren(#wx_ref{type=ThisT,ref=ThisRef}) -> + ?CLASS(ThisT,wxPanel), + wxe_util:cast(?wxPanel_SetFocusIgnoringChildren, + <<ThisRef:32/?UI>>). + %% @doc Destroys this object, do not use object again -spec destroy(This::wxPanel()) -> ok. destroy(Obj=#wx_ref{type=Type}) -> diff --git a/lib/wx/src/gen/wxPreviewCanvas.erl b/lib/wx/src/gen/wxPreviewCanvas.erl index cc9f43e5e4..7d25ee4bc4 100644 --- a/lib/wx/src/gen/wxPreviewCanvas.erl +++ b/lib/wx/src/gen/wxPreviewCanvas.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2012. All Rights Reserved. +%% Copyright Ericsson AB 2008-2013. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -61,13 +61,13 @@ scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,setAutoLayout/2, setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2, setClientSize/3,setContainingSizer/2,setCursor/2,setDropTarget/2, - setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,setForegroundColour/2, - setHelpText/2,setId/2,setLabel/2,setMaxSize/2,setMinSize/2,setName/2, - setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,setPalette/2, - setScrollPos/3,setScrollPos/4,setScrollRate/3,setScrollbar/5,setScrollbar/6, - setScrollbars/5,setScrollbars/6,setSize/2,setSize/3,setSize/5,setSize/6, - setSizeHints/2,setSizeHints/3,setSizeHints/4,setSizer/2,setSizer/3, - setSizerAndFit/2,setSizerAndFit/3,setTargetWindow/2,setThemeEnabled/2, + setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFocusIgnoringChildren/1, + setFont/2,setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2, + setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2, + setPalette/2,setScrollPos/3,setScrollPos/4,setScrollRate/3,setScrollbar/5, + setScrollbar/6,setScrollbars/5,setScrollbars/6,setSize/2,setSize/3, + setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,setSizeHints/4,setSizer/2, + setSizer/3,setSizerAndFit/2,setSizerAndFit/3,setTargetWindow/2,setThemeEnabled/2, setToolTip/2,setVirtualSize/2,setVirtualSize/3,setVirtualSizeHints/2, setVirtualSizeHints/3,setVirtualSizeHints/4,setWindowStyle/2,setWindowStyleFlag/2, setWindowVariant/2,shouldInheritColours/1,show/1,show/2,thaw/1,transferDataFromWindow/1, @@ -114,6 +114,8 @@ calcScrolledPosition(This,X,Y) -> wxScrolledWindow:calcScrolledPosition(This,X,Y calcScrolledPosition(This,Pt) -> wxScrolledWindow:calcScrolledPosition(This,Pt). %% From wxPanel %% @hidden +setFocusIgnoringChildren(This) -> wxPanel:setFocusIgnoringChildren(This). +%% @hidden initDialog(This) -> wxPanel:initDialog(This). %% From wxWindow %% @hidden diff --git a/lib/wx/src/gen/wxPreviewControlBar.erl b/lib/wx/src/gen/wxPreviewControlBar.erl index dce3feb9ea..a56adf9ebe 100644 --- a/lib/wx/src/gen/wxPreviewControlBar.erl +++ b/lib/wx/src/gen/wxPreviewControlBar.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2012. All Rights Reserved. +%% Copyright Ericsson AB 2008-2013. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -58,8 +58,8 @@ screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4, setAcceleratorTable/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2, setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2, - setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2, - setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2, + setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFocusIgnoringChildren/1, + setFont/2,setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2, setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2, setPalette/2,setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6, setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3, @@ -145,6 +145,8 @@ destroy(Obj=#wx_ref{type=Type}) -> ok. %% From wxPanel %% @hidden +setFocusIgnoringChildren(This) -> wxPanel:setFocusIgnoringChildren(This). +%% @hidden initDialog(This) -> wxPanel:initDialog(This). %% From wxWindow %% @hidden diff --git a/lib/wx/src/gen/wxScrolledWindow.erl b/lib/wx/src/gen/wxScrolledWindow.erl index 9141487a8c..dbc5eb010e 100644 --- a/lib/wx/src/gen/wxScrolledWindow.erl +++ b/lib/wx/src/gen/wxScrolledWindow.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2012. All Rights Reserved. +%% Copyright Ericsson AB 2008-2013. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -60,8 +60,8 @@ screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4, setAcceleratorTable/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2, setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2, - setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2, - setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2, + setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFocusIgnoringChildren/1, + setFont/2,setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2, setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2, setPalette/2,setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6, setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3, @@ -252,6 +252,8 @@ destroy(Obj=#wx_ref{type=Type}) -> ok. %% From wxPanel %% @hidden +setFocusIgnoringChildren(This) -> wxPanel:setFocusIgnoringChildren(This). +%% @hidden initDialog(This) -> wxPanel:initDialog(This). %% From wxWindow %% @hidden diff --git a/lib/wx/src/gen/wxStatusBar.erl b/lib/wx/src/gen/wxStatusBar.erl index 31dab03b56..5e8a707c22 100644 --- a/lib/wx/src/gen/wxStatusBar.erl +++ b/lib/wx/src/gen/wxStatusBar.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2012. All Rights Reserved. +%% Copyright Ericsson AB 2008-2013. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -28,7 +28,7 @@ -module(wxStatusBar). -include("wxe.hrl"). --export([create/2,create/3,destroy/1,getFieldRect/3,getFieldsCount/1,getStatusText/1, +-export([create/2,create/3,destroy/1,getFieldRect/2,getFieldsCount/1,getStatusText/1, getStatusText/2,new/0,new/1,new/2,popStatusText/1,popStatusText/2,pushStatusText/2, pushStatusText/3,setFieldsCount/2,setFieldsCount/3,setMinHeight/2, setStatusStyles/2,setStatusText/2,setStatusText/3,setStatusWidths/2]). @@ -132,13 +132,14 @@ create(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=ParentT,ref=ParentRef}, Opti <<ThisRef:32/?UI,ParentRef:32/?UI, BinOpt/binary>>). %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxstatusbar.html#wxstatusbargetfieldrect">external documentation</a>. --spec getFieldRect(This, I, Rect) -> boolean() when - This::wxStatusBar(), I::integer(), Rect::{X::integer(), Y::integer(), W::integer(), H::integer()}. -getFieldRect(#wx_ref{type=ThisT,ref=ThisRef},I,{RectX,RectY,RectW,RectH}) - when is_integer(I),is_integer(RectX),is_integer(RectY),is_integer(RectW),is_integer(RectH) -> +-spec getFieldRect(This, I) -> Result when + Result ::{Res ::boolean(), Rect::{X::integer(), Y::integer(), W::integer(), H::integer()}}, + This::wxStatusBar(), I::integer(). +getFieldRect(#wx_ref{type=ThisT,ref=ThisRef},I) + when is_integer(I) -> ?CLASS(ThisT,wxStatusBar), wxe_util:call(?wxStatusBar_GetFieldRect, - <<ThisRef:32/?UI,I:32/?UI,RectX:32/?UI,RectY:32/?UI,RectW:32/?UI,RectH:32/?UI>>). + <<ThisRef:32/?UI,I:32/?UI>>). %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxstatusbar.html#wxstatusbargetfieldscount">external documentation</a>. -spec getFieldsCount(This) -> integer() when diff --git a/lib/wx/src/gen/wxe_debug.hrl b/lib/wx/src/gen/wxe_debug.hrl index 29cb2b05e6..eb1f89b845 100644 --- a/lib/wx/src/gen/wxe_debug.hrl +++ b/lib/wx/src/gen/wxe_debug.hrl @@ -241,3069 +241,3070 @@ wxdebug_table() -> {334, {wxPanel, new_2, 2}}, {335, {wxPanel, destruct, 0}}, {336, {wxPanel, initDialog, 0}}, - {337, {wxScrolledWindow, new_0, 0}}, - {338, {wxScrolledWindow, new_2, 2}}, - {339, {wxScrolledWindow, destruct, 0}}, - {340, {wxScrolledWindow, calcScrolledPosition_4, 4}}, - {341, {wxScrolledWindow, calcScrolledPosition_1, 1}}, - {342, {wxScrolledWindow, calcUnscrolledPosition_4, 4}}, - {343, {wxScrolledWindow, calcUnscrolledPosition_1, 1}}, - {344, {wxScrolledWindow, enableScrolling, 2}}, - {345, {wxScrolledWindow, getScrollPixelsPerUnit, 2}}, - {346, {wxScrolledWindow, getViewStart, 2}}, - {347, {wxScrolledWindow, doPrepareDC, 1}}, - {348, {wxScrolledWindow, prepareDC, 1}}, - {349, {wxScrolledWindow, scroll, 2}}, - {350, {wxScrolledWindow, setScrollbars, 5}}, - {351, {wxScrolledWindow, setScrollRate, 2}}, - {352, {wxScrolledWindow, setTargetWindow, 1}}, - {353, {wxSashWindow, new_0, 0}}, - {354, {wxSashWindow, new_2, 2}}, - {355, {wxSashWindow, destruct, 0}}, - {356, {wxSashWindow, getSashVisible, 1}}, - {357, {wxSashWindow, getMaximumSizeX, 0}}, - {358, {wxSashWindow, getMaximumSizeY, 0}}, - {359, {wxSashWindow, getMinimumSizeX, 0}}, - {360, {wxSashWindow, getMinimumSizeY, 0}}, - {361, {wxSashWindow, setMaximumSizeX, 1}}, - {362, {wxSashWindow, setMaximumSizeY, 1}}, - {363, {wxSashWindow, setMinimumSizeX, 1}}, - {364, {wxSashWindow, setMinimumSizeY, 1}}, - {365, {wxSashWindow, setSashVisible, 2}}, - {366, {wxSashLayoutWindow, new_0, 0}}, - {367, {wxSashLayoutWindow, new_2, 2}}, - {368, {wxSashLayoutWindow, create, 2}}, - {369, {wxSashLayoutWindow, getAlignment, 0}}, - {370, {wxSashLayoutWindow, getOrientation, 0}}, - {371, {wxSashLayoutWindow, setAlignment, 1}}, - {372, {wxSashLayoutWindow, setDefaultSize, 1}}, - {373, {wxSashLayoutWindow, setOrientation, 1}}, - {374, {wxSashLayoutWindow, 'Destroy', undefined}}, - {375, {wxGrid, new_0, 0}}, - {376, {wxGrid, new_3, 3}}, - {377, {wxGrid, new_4, 4}}, - {378, {wxGrid, destruct, 0}}, - {379, {wxGrid, appendCols, 1}}, - {380, {wxGrid, appendRows, 1}}, - {381, {wxGrid, autoSize, 0}}, - {382, {wxGrid, autoSizeColumn, 2}}, - {383, {wxGrid, autoSizeColumns, 1}}, - {384, {wxGrid, autoSizeRow, 2}}, - {385, {wxGrid, autoSizeRows, 1}}, - {386, {wxGrid, beginBatch, 0}}, - {387, {wxGrid, blockToDeviceRect, 2}}, - {388, {wxGrid, canDragColSize, 0}}, - {389, {wxGrid, canDragRowSize, 0}}, - {390, {wxGrid, canDragGridSize, 0}}, - {391, {wxGrid, canEnableCellControl, 0}}, - {392, {wxGrid, cellToRect_2, 2}}, - {393, {wxGrid, cellToRect_1, 1}}, - {394, {wxGrid, clearGrid, 0}}, - {395, {wxGrid, clearSelection, 0}}, - {396, {wxGrid, createGrid, 3}}, - {397, {wxGrid, deleteCols, 1}}, - {398, {wxGrid, deleteRows, 1}}, - {399, {wxGrid, disableCellEditControl, 0}}, - {400, {wxGrid, disableDragColSize, 0}}, - {401, {wxGrid, disableDragGridSize, 0}}, - {402, {wxGrid, disableDragRowSize, 0}}, - {403, {wxGrid, enableCellEditControl, 1}}, - {404, {wxGrid, enableDragColSize, 1}}, - {405, {wxGrid, enableDragGridSize, 1}}, - {406, {wxGrid, enableDragRowSize, 1}}, - {407, {wxGrid, enableEditing, 1}}, - {408, {wxGrid, enableGridLines, 1}}, - {409, {wxGrid, endBatch, 0}}, - {410, {wxGrid, fit, 0}}, - {411, {wxGrid, forceRefresh, 0}}, - {412, {wxGrid, getBatchCount, 0}}, - {413, {wxGrid, getCellAlignment, 4}}, - {414, {wxGrid, getCellBackgroundColour, 2}}, - {415, {wxGrid, getCellEditor, 2}}, - {416, {wxGrid, getCellFont, 2}}, - {417, {wxGrid, getCellRenderer, 2}}, - {418, {wxGrid, getCellTextColour, 2}}, - {419, {wxGrid, getCellValue_2, 2}}, - {420, {wxGrid, getCellValue_1, 1}}, - {421, {wxGrid, getColLabelAlignment, 2}}, - {422, {wxGrid, getColLabelSize, 0}}, - {423, {wxGrid, getColLabelValue, 1}}, - {424, {wxGrid, getColMinimalAcceptableWidth, 0}}, - {425, {wxGrid, getDefaultCellAlignment, 2}}, - {426, {wxGrid, getDefaultCellBackgroundColour, 0}}, - {427, {wxGrid, getDefaultCellFont, 0}}, - {428, {wxGrid, getDefaultCellTextColour, 0}}, - {429, {wxGrid, getDefaultColLabelSize, 0}}, - {430, {wxGrid, getDefaultColSize, 0}}, - {431, {wxGrid, getDefaultEditor, 0}}, - {432, {wxGrid, getDefaultEditorForCell_2, 2}}, - {433, {wxGrid, getDefaultEditorForCell_1, 1}}, - {434, {wxGrid, getDefaultEditorForType, 1}}, - {435, {wxGrid, getDefaultRenderer, 0}}, - {436, {wxGrid, getDefaultRendererForCell, 2}}, - {437, {wxGrid, getDefaultRendererForType, 1}}, - {438, {wxGrid, getDefaultRowLabelSize, 0}}, - {439, {wxGrid, getDefaultRowSize, 0}}, - {440, {wxGrid, getGridCursorCol, 0}}, - {441, {wxGrid, getGridCursorRow, 0}}, - {442, {wxGrid, getGridLineColour, 0}}, - {443, {wxGrid, gridLinesEnabled, 0}}, - {444, {wxGrid, getLabelBackgroundColour, 0}}, - {445, {wxGrid, getLabelFont, 0}}, - {446, {wxGrid, getLabelTextColour, 0}}, - {447, {wxGrid, getNumberCols, 0}}, - {448, {wxGrid, getNumberRows, 0}}, - {449, {wxGrid, getOrCreateCellAttr, 2}}, - {450, {wxGrid, getRowMinimalAcceptableHeight, 0}}, - {451, {wxGrid, getRowLabelAlignment, 2}}, - {452, {wxGrid, getRowLabelSize, 0}}, - {453, {wxGrid, getRowLabelValue, 1}}, - {454, {wxGrid, getRowSize, 1}}, - {455, {wxGrid, getScrollLineX, 0}}, - {456, {wxGrid, getScrollLineY, 0}}, - {457, {wxGrid, getSelectedCells, 0}}, - {458, {wxGrid, getSelectedCols, 0}}, - {459, {wxGrid, getSelectedRows, 0}}, - {460, {wxGrid, getSelectionBackground, 0}}, - {461, {wxGrid, getSelectionBlockTopLeft, 0}}, - {462, {wxGrid, getSelectionBlockBottomRight, 0}}, - {463, {wxGrid, getSelectionForeground, 0}}, - {464, {wxGrid, getViewWidth, 0}}, - {465, {wxGrid, getGridWindow, 0}}, - {466, {wxGrid, getGridRowLabelWindow, 0}}, - {467, {wxGrid, getGridColLabelWindow, 0}}, - {468, {wxGrid, getGridCornerLabelWindow, 0}}, - {469, {wxGrid, hideCellEditControl, 0}}, - {470, {wxGrid, insertCols, 1}}, - {471, {wxGrid, insertRows, 1}}, - {472, {wxGrid, isCellEditControlEnabled, 0}}, - {473, {wxGrid, isCurrentCellReadOnly, 0}}, - {474, {wxGrid, isEditable, 0}}, - {475, {wxGrid, isInSelection_2, 2}}, - {476, {wxGrid, isInSelection_1, 1}}, - {477, {wxGrid, isReadOnly, 2}}, - {478, {wxGrid, isSelection, 0}}, - {479, {wxGrid, isVisible_3, 3}}, - {480, {wxGrid, isVisible_2, 2}}, - {481, {wxGrid, makeCellVisible_2, 2}}, - {482, {wxGrid, makeCellVisible_1, 1}}, - {483, {wxGrid, moveCursorDown, 1}}, - {484, {wxGrid, moveCursorLeft, 1}}, - {485, {wxGrid, moveCursorRight, 1}}, - {486, {wxGrid, moveCursorUp, 1}}, - {487, {wxGrid, moveCursorDownBlock, 1}}, - {488, {wxGrid, moveCursorLeftBlock, 1}}, - {489, {wxGrid, moveCursorRightBlock, 1}}, - {490, {wxGrid, moveCursorUpBlock, 1}}, - {491, {wxGrid, movePageDown, 0}}, - {492, {wxGrid, movePageUp, 0}}, - {493, {wxGrid, registerDataType, 3}}, - {494, {wxGrid, saveEditControlValue, 0}}, - {495, {wxGrid, selectAll, 0}}, - {496, {wxGrid, selectBlock_5, 5}}, - {497, {wxGrid, selectBlock_3, 3}}, - {498, {wxGrid, selectCol, 2}}, - {499, {wxGrid, selectRow, 2}}, - {500, {wxGrid, setCellAlignment_4, 4}}, - {501, {wxGrid, setCellAlignment_3, 3}}, - {502, {wxGrid, setCellAlignment_1, 1}}, - {503, {wxGrid, setCellBackgroundColour_3_0, 3}}, - {504, {wxGrid, setCellBackgroundColour_1, 1}}, - {505, {wxGrid, setCellBackgroundColour_3_1, 3}}, - {506, {wxGrid, setCellEditor, 3}}, - {507, {wxGrid, setCellFont, 3}}, - {508, {wxGrid, setCellRenderer, 3}}, - {509, {wxGrid, setCellTextColour_3_0, 3}}, - {510, {wxGrid, setCellTextColour_3_1, 3}}, - {511, {wxGrid, setCellTextColour_1, 1}}, - {512, {wxGrid, setCellValue_3_0, 3}}, - {513, {wxGrid, setCellValue_2, 2}}, - {514, {wxGrid, setCellValue_3_1, 3}}, - {515, {wxGrid, setColAttr, 2}}, - {516, {wxGrid, setColFormatBool, 1}}, - {517, {wxGrid, setColFormatNumber, 1}}, - {518, {wxGrid, setColFormatFloat, 2}}, - {519, {wxGrid, setColFormatCustom, 2}}, - {520, {wxGrid, setColLabelAlignment, 2}}, - {521, {wxGrid, setColLabelSize, 1}}, - {522, {wxGrid, setColLabelValue, 2}}, - {523, {wxGrid, setColMinimalWidth, 2}}, - {524, {wxGrid, setColMinimalAcceptableWidth, 1}}, - {525, {wxGrid, setColSize, 2}}, - {526, {wxGrid, setDefaultCellAlignment, 2}}, - {527, {wxGrid, setDefaultCellBackgroundColour, 1}}, - {528, {wxGrid, setDefaultCellFont, 1}}, - {529, {wxGrid, setDefaultCellTextColour, 1}}, - {530, {wxGrid, setDefaultEditor, 1}}, - {531, {wxGrid, setDefaultRenderer, 1}}, - {532, {wxGrid, setDefaultColSize, 2}}, - {533, {wxGrid, setDefaultRowSize, 2}}, - {534, {wxGrid, setGridCursor, 2}}, - {535, {wxGrid, setGridLineColour, 1}}, - {536, {wxGrid, setLabelBackgroundColour, 1}}, - {537, {wxGrid, setLabelFont, 1}}, - {538, {wxGrid, setLabelTextColour, 1}}, - {539, {wxGrid, setMargins, 2}}, - {540, {wxGrid, setReadOnly, 3}}, - {541, {wxGrid, setRowAttr, 2}}, - {542, {wxGrid, setRowLabelAlignment, 2}}, - {543, {wxGrid, setRowLabelSize, 1}}, - {544, {wxGrid, setRowLabelValue, 2}}, - {545, {wxGrid, setRowMinimalHeight, 2}}, - {546, {wxGrid, setRowMinimalAcceptableHeight, 1}}, - {547, {wxGrid, setRowSize, 2}}, - {548, {wxGrid, setScrollLineX, 1}}, - {549, {wxGrid, setScrollLineY, 1}}, - {550, {wxGrid, setSelectionBackground, 1}}, - {551, {wxGrid, setSelectionForeground, 1}}, - {552, {wxGrid, setSelectionMode, 1}}, - {553, {wxGrid, showCellEditControl, 0}}, - {554, {wxGrid, xToCol, 2}}, - {555, {wxGrid, xToEdgeOfCol, 1}}, - {556, {wxGrid, yToEdgeOfRow, 1}}, - {557, {wxGrid, yToRow, 1}}, - {558, {wxGridCellRenderer, draw, 7}}, - {559, {wxGridCellRenderer, getBestSize, 5}}, - {560, {wxGridCellEditor, create, 3}}, - {561, {wxGridCellEditor, isCreated, 0}}, - {562, {wxGridCellEditor, setSize, 1}}, - {563, {wxGridCellEditor, show, 2}}, - {564, {wxGridCellEditor, paintBackground, 2}}, - {565, {wxGridCellEditor, beginEdit, 3}}, - {566, {wxGridCellEditor, endEdit, 3}}, - {567, {wxGridCellEditor, reset, 0}}, - {568, {wxGridCellEditor, startingKey, 1}}, - {569, {wxGridCellEditor, startingClick, 0}}, - {570, {wxGridCellEditor, handleReturn, 1}}, - {571, {wxGridCellBoolRenderer, new, 0}}, - {572, {wxGridCellBoolRenderer, 'Destroy', undefined}}, - {573, {wxGridCellBoolEditor, new, 0}}, - {574, {wxGridCellBoolEditor, isTrueValue, 1}}, - {575, {wxGridCellBoolEditor, useStringValues, 1}}, - {576, {wxGridCellBoolEditor, 'Destroy', undefined}}, - {577, {wxGridCellFloatRenderer, new, 1}}, - {578, {wxGridCellFloatRenderer, getPrecision, 0}}, - {579, {wxGridCellFloatRenderer, getWidth, 0}}, - {580, {wxGridCellFloatRenderer, setParameters, 1}}, - {581, {wxGridCellFloatRenderer, setPrecision, 1}}, - {582, {wxGridCellFloatRenderer, setWidth, 1}}, - {583, {wxGridCellFloatRenderer, 'Destroy', undefined}}, - {584, {wxGridCellFloatEditor, new, 1}}, - {585, {wxGridCellFloatEditor, setParameters, 1}}, - {586, {wxGridCellFloatEditor, 'Destroy', undefined}}, - {587, {wxGridCellStringRenderer, new, 0}}, - {588, {wxGridCellStringRenderer, 'Destroy', undefined}}, - {589, {wxGridCellTextEditor, new, 0}}, - {590, {wxGridCellTextEditor, setParameters, 1}}, - {591, {wxGridCellTextEditor, 'Destroy', undefined}}, - {593, {wxGridCellChoiceEditor, new, 2}}, - {594, {wxGridCellChoiceEditor, setParameters, 1}}, - {595, {wxGridCellChoiceEditor, 'Destroy', undefined}}, - {596, {wxGridCellNumberRenderer, new, 0}}, - {597, {wxGridCellNumberRenderer, 'Destroy', undefined}}, - {598, {wxGridCellNumberEditor, new, 1}}, - {599, {wxGridCellNumberEditor, getValue, 0}}, - {600, {wxGridCellNumberEditor, setParameters, 1}}, - {601, {wxGridCellNumberEditor, 'Destroy', undefined}}, - {602, {wxGridCellAttr, setTextColour, 1}}, - {603, {wxGridCellAttr, setBackgroundColour, 1}}, - {604, {wxGridCellAttr, setFont, 1}}, - {605, {wxGridCellAttr, setAlignment, 2}}, - {606, {wxGridCellAttr, setReadOnly, 1}}, - {607, {wxGridCellAttr, setRenderer, 1}}, - {608, {wxGridCellAttr, setEditor, 1}}, - {609, {wxGridCellAttr, hasTextColour, 0}}, - {610, {wxGridCellAttr, hasBackgroundColour, 0}}, - {611, {wxGridCellAttr, hasFont, 0}}, - {612, {wxGridCellAttr, hasAlignment, 0}}, - {613, {wxGridCellAttr, hasRenderer, 0}}, - {614, {wxGridCellAttr, hasEditor, 0}}, - {615, {wxGridCellAttr, getTextColour, 0}}, - {616, {wxGridCellAttr, getBackgroundColour, 0}}, - {617, {wxGridCellAttr, getFont, 0}}, - {618, {wxGridCellAttr, getAlignment, 2}}, - {619, {wxGridCellAttr, getRenderer, 3}}, - {620, {wxGridCellAttr, getEditor, 3}}, - {621, {wxGridCellAttr, isReadOnly, 0}}, - {622, {wxGridCellAttr, setDefAttr, 1}}, - {623, {wxDC, blit, 5}}, - {624, {wxDC, calcBoundingBox, 2}}, - {625, {wxDC, clear, 0}}, - {626, {wxDC, computeScaleAndOrigin, 0}}, - {627, {wxDC, crossHair, 1}}, - {628, {wxDC, destroyClippingRegion, 0}}, - {629, {wxDC, deviceToLogicalX, 1}}, - {630, {wxDC, deviceToLogicalXRel, 1}}, - {631, {wxDC, deviceToLogicalY, 1}}, - {632, {wxDC, deviceToLogicalYRel, 1}}, - {633, {wxDC, drawArc, 3}}, - {634, {wxDC, drawBitmap, 3}}, - {635, {wxDC, drawCheckMark, 1}}, - {636, {wxDC, drawCircle, 2}}, - {638, {wxDC, drawEllipse_2, 2}}, - {639, {wxDC, drawEllipse_1, 1}}, - {640, {wxDC, drawEllipticArc, 4}}, - {641, {wxDC, drawIcon, 2}}, - {642, {wxDC, drawLabel, 3}}, - {643, {wxDC, drawLine, 2}}, - {644, {wxDC, drawLines, 3}}, - {646, {wxDC, drawPolygon, 3}}, - {648, {wxDC, drawPoint, 1}}, - {650, {wxDC, drawRectangle_2, 2}}, - {651, {wxDC, drawRectangle_1, 1}}, - {652, {wxDC, drawRotatedText, 3}}, - {654, {wxDC, drawRoundedRectangle_3, 3}}, - {655, {wxDC, drawRoundedRectangle_2, 2}}, - {656, {wxDC, drawText, 2}}, - {657, {wxDC, endDoc, 0}}, - {658, {wxDC, endPage, 0}}, - {659, {wxDC, floodFill, 3}}, - {660, {wxDC, getBackground, 0}}, - {661, {wxDC, getBackgroundMode, 0}}, - {662, {wxDC, getBrush, 0}}, - {663, {wxDC, getCharHeight, 0}}, - {664, {wxDC, getCharWidth, 0}}, - {665, {wxDC, getClippingBox, 4}}, - {667, {wxDC, getFont, 0}}, - {668, {wxDC, getLayoutDirection, 0}}, - {669, {wxDC, getLogicalFunction, 0}}, - {670, {wxDC, getMapMode, 0}}, - {671, {wxDC, getMultiLineTextExtent_4, 4}}, - {672, {wxDC, getMultiLineTextExtent_1, 1}}, - {673, {wxDC, getPartialTextExtents, 2}}, - {674, {wxDC, getPen, 0}}, - {675, {wxDC, getPixel, 2}}, - {676, {wxDC, getPPI, 0}}, - {678, {wxDC, getSize, 0}}, - {680, {wxDC, getSizeMM, 0}}, - {681, {wxDC, getTextBackground, 0}}, - {682, {wxDC, getTextExtent_4, 4}}, - {683, {wxDC, getTextExtent_1, 1}}, - {685, {wxDC, getTextForeground, 0}}, - {686, {wxDC, getUserScale, 2}}, - {687, {wxDC, gradientFillConcentric_3, 3}}, - {688, {wxDC, gradientFillConcentric_4, 4}}, - {689, {wxDC, gradientFillLinear, 4}}, - {690, {wxDC, logicalToDeviceX, 1}}, - {691, {wxDC, logicalToDeviceXRel, 1}}, - {692, {wxDC, logicalToDeviceY, 1}}, - {693, {wxDC, logicalToDeviceYRel, 1}}, - {694, {wxDC, maxX, 0}}, - {695, {wxDC, maxY, 0}}, - {696, {wxDC, minX, 0}}, - {697, {wxDC, minY, 0}}, - {698, {wxDC, isOk, 0}}, - {699, {wxDC, resetBoundingBox, 0}}, - {700, {wxDC, setAxisOrientation, 2}}, - {701, {wxDC, setBackground, 1}}, - {702, {wxDC, setBackgroundMode, 1}}, - {703, {wxDC, setBrush, 1}}, - {705, {wxDC, setClippingRegion_2, 2}}, - {706, {wxDC, setClippingRegion_1_1, 1}}, - {707, {wxDC, setClippingRegion_1_0, 1}}, - {708, {wxDC, setDeviceOrigin, 2}}, - {709, {wxDC, setFont, 1}}, - {710, {wxDC, setLayoutDirection, 1}}, - {711, {wxDC, setLogicalFunction, 1}}, - {712, {wxDC, setMapMode, 1}}, - {713, {wxDC, setPalette, 1}}, - {714, {wxDC, setPen, 1}}, - {715, {wxDC, setTextBackground, 1}}, - {716, {wxDC, setTextForeground, 1}}, - {717, {wxDC, setUserScale, 2}}, - {718, {wxDC, startDoc, 1}}, - {719, {wxDC, startPage, 0}}, - {720, {wxMirrorDC, new, 2}}, - {721, {wxMirrorDC, 'Destroy', undefined}}, - {722, {wxScreenDC, new, 0}}, - {723, {wxScreenDC, destruct, 0}}, - {724, {wxPostScriptDC, new_0, 0}}, - {725, {wxPostScriptDC, new_1, 1}}, - {726, {wxPostScriptDC, destruct, 0}}, - {727, {wxPostScriptDC, setResolution, 1}}, - {728, {wxPostScriptDC, getResolution, 0}}, - {729, {wxWindowDC, new_0, 0}}, - {730, {wxWindowDC, new_1, 1}}, - {731, {wxWindowDC, destruct, 0}}, - {732, {wxClientDC, new_0, 0}}, - {733, {wxClientDC, new_1, 1}}, - {734, {wxClientDC, 'Destroy', undefined}}, - {735, {wxPaintDC, new_0, 0}}, - {736, {wxPaintDC, new_1, 1}}, - {737, {wxPaintDC, 'Destroy', undefined}}, - {739, {wxMemoryDC, new_1_0, 1}}, - {740, {wxMemoryDC, new_1_1, 1}}, - {741, {wxMemoryDC, new_0, 0}}, - {743, {wxMemoryDC, destruct, 0}}, - {744, {wxMemoryDC, selectObject, 1}}, - {745, {wxMemoryDC, selectObjectAsSource, 1}}, - {746, {wxBufferedDC, new_0, 0}}, - {747, {wxBufferedDC, new_2, 2}}, - {748, {wxBufferedDC, new_3, 3}}, - {749, {wxBufferedDC, destruct, 0}}, - {750, {wxBufferedDC, init_2, 2}}, - {751, {wxBufferedDC, init_3, 3}}, - {752, {wxBufferedPaintDC, new_3, 3}}, - {753, {wxBufferedPaintDC, new_2, 2}}, - {754, {wxBufferedPaintDC, destruct, 0}}, - {755, {wxGraphicsObject, destruct, 0}}, - {756, {wxGraphicsObject, getRenderer, 0}}, - {757, {wxGraphicsObject, isNull, 0}}, - {758, {wxGraphicsContext, destruct, 0}}, - {759, {wxGraphicsContext, create_1_1, 1}}, - {760, {wxGraphicsContext, create_1_0, 1}}, - {761, {wxGraphicsContext, create_0, 0}}, - {762, {wxGraphicsContext, createPen, 1}}, - {763, {wxGraphicsContext, createBrush, 1}}, - {764, {wxGraphicsContext, createRadialGradientBrush, 7}}, - {765, {wxGraphicsContext, createLinearGradientBrush, 6}}, - {766, {wxGraphicsContext, createFont, 2}}, - {767, {wxGraphicsContext, createMatrix, 1}}, - {768, {wxGraphicsContext, createPath, 0}}, - {769, {wxGraphicsContext, clip_1, 1}}, - {770, {wxGraphicsContext, clip_4, 4}}, - {771, {wxGraphicsContext, resetClip, 0}}, - {772, {wxGraphicsContext, drawBitmap, 5}}, - {773, {wxGraphicsContext, drawEllipse, 4}}, - {774, {wxGraphicsContext, drawIcon, 5}}, - {775, {wxGraphicsContext, drawLines, 3}}, - {776, {wxGraphicsContext, drawPath, 2}}, - {777, {wxGraphicsContext, drawRectangle, 4}}, - {778, {wxGraphicsContext, drawRoundedRectangle, 5}}, - {779, {wxGraphicsContext, drawText_3, 3}}, - {780, {wxGraphicsContext, drawText_4_0, 4}}, - {781, {wxGraphicsContext, drawText_4_1, 4}}, - {782, {wxGraphicsContext, drawText_5, 5}}, - {783, {wxGraphicsContext, fillPath, 2}}, - {784, {wxGraphicsContext, strokePath, 1}}, - {785, {wxGraphicsContext, getPartialTextExtents, 2}}, - {786, {wxGraphicsContext, getTextExtent, 5}}, - {787, {wxGraphicsContext, rotate, 1}}, - {788, {wxGraphicsContext, scale, 2}}, - {789, {wxGraphicsContext, translate, 2}}, - {790, {wxGraphicsContext, getTransform, 0}}, - {791, {wxGraphicsContext, setTransform, 1}}, - {792, {wxGraphicsContext, concatTransform, 1}}, - {793, {wxGraphicsContext, setBrush_1_1, 1}}, - {794, {wxGraphicsContext, setBrush_1_0, 1}}, - {795, {wxGraphicsContext, setFont_1, 1}}, - {796, {wxGraphicsContext, setFont_2, 2}}, - {797, {wxGraphicsContext, setPen_1_0, 1}}, - {798, {wxGraphicsContext, setPen_1_1, 1}}, - {799, {wxGraphicsContext, strokeLine, 4}}, - {800, {wxGraphicsContext, strokeLines, 2}}, - {802, {wxGraphicsMatrix, concat, 1}}, - {804, {wxGraphicsMatrix, get, 1}}, - {805, {wxGraphicsMatrix, invert, 0}}, - {806, {wxGraphicsMatrix, isEqual, 1}}, - {808, {wxGraphicsMatrix, isIdentity, 0}}, - {809, {wxGraphicsMatrix, rotate, 1}}, - {810, {wxGraphicsMatrix, scale, 2}}, - {811, {wxGraphicsMatrix, translate, 2}}, - {812, {wxGraphicsMatrix, set, 1}}, - {813, {wxGraphicsMatrix, transformPoint, 2}}, - {814, {wxGraphicsMatrix, transformDistance, 2}}, - {815, {wxGraphicsPath, moveToPoint_2, 2}}, - {816, {wxGraphicsPath, moveToPoint_1, 1}}, - {817, {wxGraphicsPath, addArc_6, 6}}, - {818, {wxGraphicsPath, addArc_5, 5}}, - {819, {wxGraphicsPath, addArcToPoint, 5}}, - {820, {wxGraphicsPath, addCircle, 3}}, - {821, {wxGraphicsPath, addCurveToPoint_6, 6}}, - {822, {wxGraphicsPath, addCurveToPoint_3, 3}}, - {823, {wxGraphicsPath, addEllipse, 4}}, - {824, {wxGraphicsPath, addLineToPoint_2, 2}}, - {825, {wxGraphicsPath, addLineToPoint_1, 1}}, - {826, {wxGraphicsPath, addPath, 1}}, - {827, {wxGraphicsPath, addQuadCurveToPoint, 4}}, - {828, {wxGraphicsPath, addRectangle, 4}}, - {829, {wxGraphicsPath, addRoundedRectangle, 5}}, - {830, {wxGraphicsPath, closeSubpath, 0}}, - {831, {wxGraphicsPath, contains_3, 3}}, - {832, {wxGraphicsPath, contains_2, 2}}, - {834, {wxGraphicsPath, getBox, 0}}, - {836, {wxGraphicsPath, getCurrentPoint, 0}}, - {837, {wxGraphicsPath, transform, 1}}, - {838, {wxGraphicsRenderer, getDefaultRenderer, 0}}, - {839, {wxGraphicsRenderer, createContext_1_1, 1}}, - {840, {wxGraphicsRenderer, createContext_1_0, 1}}, - {841, {wxGraphicsRenderer, createPen, 1}}, - {842, {wxGraphicsRenderer, createBrush, 1}}, - {843, {wxGraphicsRenderer, createLinearGradientBrush, 6}}, - {844, {wxGraphicsRenderer, createRadialGradientBrush, 7}}, - {845, {wxGraphicsRenderer, createFont, 2}}, - {846, {wxGraphicsRenderer, createMatrix, 1}}, - {847, {wxGraphicsRenderer, createPath, 0}}, - {849, {wxMenuBar, new_1, 1}}, - {851, {wxMenuBar, new_0, 0}}, - {853, {wxMenuBar, destruct, 0}}, - {854, {wxMenuBar, append, 2}}, - {855, {wxMenuBar, check, 2}}, - {856, {wxMenuBar, enable_2, 2}}, - {857, {wxMenuBar, enable_1, 1}}, - {858, {wxMenuBar, enableTop, 2}}, - {859, {wxMenuBar, findMenu, 1}}, - {860, {wxMenuBar, findMenuItem, 2}}, - {861, {wxMenuBar, findItem, 2}}, - {862, {wxMenuBar, getHelpString, 1}}, - {863, {wxMenuBar, getLabel_1, 1}}, - {864, {wxMenuBar, getLabel_0, 0}}, - {865, {wxMenuBar, getLabelTop, 1}}, - {866, {wxMenuBar, getMenu, 1}}, - {867, {wxMenuBar, getMenuCount, 0}}, - {868, {wxMenuBar, insert, 3}}, - {869, {wxMenuBar, isChecked, 1}}, - {870, {wxMenuBar, isEnabled_1, 1}}, - {871, {wxMenuBar, isEnabled_0, 0}}, - {872, {wxMenuBar, remove, 1}}, - {873, {wxMenuBar, replace, 3}}, - {874, {wxMenuBar, setHelpString, 2}}, - {875, {wxMenuBar, setLabel_2, 2}}, - {876, {wxMenuBar, setLabel_1, 1}}, - {877, {wxMenuBar, setLabelTop, 2}}, - {878, {wxControl, getLabel, 0}}, - {879, {wxControl, setLabel, 1}}, - {880, {wxControlWithItems, append_1, 1}}, - {881, {wxControlWithItems, append_2, 2}}, - {882, {wxControlWithItems, appendStrings_1, 1}}, - {883, {wxControlWithItems, clear, 0}}, - {884, {wxControlWithItems, delete, 1}}, - {885, {wxControlWithItems, findString, 2}}, - {886, {wxControlWithItems, getClientData, 1}}, - {887, {wxControlWithItems, setClientData, 2}}, - {888, {wxControlWithItems, getCount, 0}}, - {889, {wxControlWithItems, getSelection, 0}}, - {890, {wxControlWithItems, getString, 1}}, - {891, {wxControlWithItems, getStringSelection, 0}}, - {892, {wxControlWithItems, insert_2, 2}}, - {893, {wxControlWithItems, insert_3, 3}}, - {894, {wxControlWithItems, isEmpty, 0}}, - {895, {wxControlWithItems, select, 1}}, - {896, {wxControlWithItems, setSelection, 1}}, - {897, {wxControlWithItems, setString, 2}}, - {898, {wxControlWithItems, setStringSelection, 1}}, - {901, {wxMenu, new_2, 2}}, - {902, {wxMenu, new_1, 1}}, - {904, {wxMenu, destruct, 0}}, - {905, {wxMenu, append_3, 3}}, - {906, {wxMenu, append_1, 1}}, - {907, {wxMenu, append_4_0, 4}}, - {908, {wxMenu, append_4_1, 4}}, - {909, {wxMenu, appendCheckItem, 3}}, - {910, {wxMenu, appendRadioItem, 3}}, - {911, {wxMenu, appendSeparator, 0}}, - {912, {wxMenu, break, 0}}, - {913, {wxMenu, check, 2}}, - {914, {wxMenu, delete_1_0, 1}}, - {915, {wxMenu, delete_1_1, 1}}, - {916, {wxMenu, destroy_1_0, 1}}, - {917, {wxMenu, destroy_1_1, 1}}, - {918, {wxMenu, enable, 2}}, - {919, {wxMenu, findItem_1, 1}}, - {920, {wxMenu, findItem_2, 2}}, - {921, {wxMenu, findItemByPosition, 1}}, - {922, {wxMenu, getHelpString, 1}}, - {923, {wxMenu, getLabel, 1}}, - {924, {wxMenu, getMenuItemCount, 0}}, - {925, {wxMenu, getMenuItems, 0}}, - {927, {wxMenu, getTitle, 0}}, - {928, {wxMenu, insert_2, 2}}, - {929, {wxMenu, insert_3, 3}}, - {930, {wxMenu, insert_5_1, 5}}, - {931, {wxMenu, insert_5_0, 5}}, - {932, {wxMenu, insertCheckItem, 4}}, - {933, {wxMenu, insertRadioItem, 4}}, - {934, {wxMenu, insertSeparator, 1}}, - {935, {wxMenu, isChecked, 1}}, - {936, {wxMenu, isEnabled, 1}}, - {937, {wxMenu, prepend_1, 1}}, - {938, {wxMenu, prepend_2, 2}}, - {939, {wxMenu, prepend_4_1, 4}}, - {940, {wxMenu, prepend_4_0, 4}}, - {941, {wxMenu, prependCheckItem, 3}}, - {942, {wxMenu, prependRadioItem, 3}}, - {943, {wxMenu, prependSeparator, 0}}, - {944, {wxMenu, remove_1_0, 1}}, - {945, {wxMenu, remove_1_1, 1}}, - {946, {wxMenu, setHelpString, 2}}, - {947, {wxMenu, setLabel, 2}}, - {948, {wxMenu, setTitle, 1}}, - {949, {wxMenuItem, new, 1}}, - {951, {wxMenuItem, destruct, 0}}, - {952, {wxMenuItem, check, 1}}, - {953, {wxMenuItem, enable, 1}}, - {954, {wxMenuItem, getBitmap, 0}}, - {955, {wxMenuItem, getHelp, 0}}, - {956, {wxMenuItem, getId, 0}}, - {957, {wxMenuItem, getKind, 0}}, - {958, {wxMenuItem, getLabel, 0}}, - {959, {wxMenuItem, getLabelFromText, 1}}, - {960, {wxMenuItem, getMenu, 0}}, - {961, {wxMenuItem, getText, 0}}, - {962, {wxMenuItem, getSubMenu, 0}}, - {963, {wxMenuItem, isCheckable, 0}}, - {964, {wxMenuItem, isChecked, 0}}, - {965, {wxMenuItem, isEnabled, 0}}, - {966, {wxMenuItem, isSeparator, 0}}, - {967, {wxMenuItem, isSubMenu, 0}}, - {968, {wxMenuItem, setBitmap, 1}}, - {969, {wxMenuItem, setHelp, 1}}, - {970, {wxMenuItem, setMenu, 1}}, - {971, {wxMenuItem, setSubMenu, 1}}, - {972, {wxMenuItem, setText, 1}}, - {973, {wxToolBar, addControl, 1}}, - {974, {wxToolBar, addSeparator, 0}}, - {975, {wxToolBar, addTool_5, 5}}, - {976, {wxToolBar, addTool_4_0, 4}}, - {977, {wxToolBar, addTool_1, 1}}, - {978, {wxToolBar, addTool_4_1, 4}}, - {979, {wxToolBar, addTool_3, 3}}, - {980, {wxToolBar, addTool_6, 6}}, - {981, {wxToolBar, addCheckTool, 4}}, - {982, {wxToolBar, addRadioTool, 4}}, - {983, {wxToolBar, deleteTool, 1}}, - {984, {wxToolBar, deleteToolByPos, 1}}, - {985, {wxToolBar, enableTool, 2}}, - {986, {wxToolBar, findById, 1}}, - {987, {wxToolBar, findControl, 1}}, - {988, {wxToolBar, findToolForPosition, 2}}, - {989, {wxToolBar, getToolSize, 0}}, - {990, {wxToolBar, getToolBitmapSize, 0}}, - {991, {wxToolBar, getMargins, 0}}, - {992, {wxToolBar, getToolEnabled, 1}}, - {993, {wxToolBar, getToolLongHelp, 1}}, - {994, {wxToolBar, getToolPacking, 0}}, - {995, {wxToolBar, getToolPos, 1}}, - {996, {wxToolBar, getToolSeparation, 0}}, - {997, {wxToolBar, getToolShortHelp, 1}}, - {998, {wxToolBar, getToolState, 1}}, - {999, {wxToolBar, insertControl, 2}}, - {1000, {wxToolBar, insertSeparator, 1}}, - {1001, {wxToolBar, insertTool_5, 5}}, - {1002, {wxToolBar, insertTool_2, 2}}, - {1003, {wxToolBar, insertTool_4, 4}}, - {1004, {wxToolBar, realize, 0}}, - {1005, {wxToolBar, removeTool, 1}}, - {1006, {wxToolBar, setMargins, 2}}, - {1007, {wxToolBar, setToolBitmapSize, 1}}, - {1008, {wxToolBar, setToolLongHelp, 2}}, - {1009, {wxToolBar, setToolPacking, 1}}, - {1010, {wxToolBar, setToolShortHelp, 2}}, - {1011, {wxToolBar, setToolSeparation, 1}}, - {1012, {wxToolBar, toggleTool, 2}}, - {1014, {wxStatusBar, new_0, 0}}, - {1015, {wxStatusBar, new_2, 2}}, - {1017, {wxStatusBar, destruct, 0}}, - {1018, {wxStatusBar, create, 2}}, - {1019, {wxStatusBar, getFieldRect, 2}}, - {1020, {wxStatusBar, getFieldsCount, 0}}, - {1021, {wxStatusBar, getStatusText, 1}}, - {1022, {wxStatusBar, popStatusText, 1}}, - {1023, {wxStatusBar, pushStatusText, 2}}, - {1024, {wxStatusBar, setFieldsCount, 2}}, - {1025, {wxStatusBar, setMinHeight, 1}}, - {1026, {wxStatusBar, setStatusText, 2}}, - {1027, {wxStatusBar, setStatusWidths, 2}}, - {1028, {wxStatusBar, setStatusStyles, 2}}, - {1029, {wxBitmap, new_0, 0}}, - {1030, {wxBitmap, new_3, 3}}, - {1031, {wxBitmap, new_4, 4}}, - {1032, {wxBitmap, new_2_0, 2}}, - {1033, {wxBitmap, new_2_1, 2}}, - {1034, {wxBitmap, destruct, 0}}, - {1035, {wxBitmap, convertToImage, 0}}, - {1036, {wxBitmap, copyFromIcon, 1}}, - {1037, {wxBitmap, create, 3}}, - {1038, {wxBitmap, getDepth, 0}}, - {1039, {wxBitmap, getHeight, 0}}, - {1040, {wxBitmap, getPalette, 0}}, - {1041, {wxBitmap, getMask, 0}}, - {1042, {wxBitmap, getWidth, 0}}, - {1043, {wxBitmap, getSubBitmap, 1}}, - {1044, {wxBitmap, loadFile, 2}}, - {1045, {wxBitmap, ok, 0}}, - {1046, {wxBitmap, saveFile, 3}}, - {1047, {wxBitmap, setDepth, 1}}, - {1048, {wxBitmap, setHeight, 1}}, - {1049, {wxBitmap, setMask, 1}}, - {1050, {wxBitmap, setPalette, 1}}, - {1051, {wxBitmap, setWidth, 1}}, - {1052, {wxIcon, new_0, 0}}, - {1053, {wxIcon, new_2, 2}}, - {1054, {wxIcon, new_1, 1}}, - {1055, {wxIcon, copyFromBitmap, 1}}, - {1056, {wxIcon, 'Destroy', undefined}}, - {1057, {wxIconBundle, new_0, 0}}, - {1058, {wxIconBundle, new_2, 2}}, - {1059, {wxIconBundle, new_1_0, 1}}, - {1060, {wxIconBundle, new_1_1, 1}}, - {1061, {wxIconBundle, destruct, 0}}, - {1062, {wxIconBundle, addIcon_2, 2}}, - {1063, {wxIconBundle, addIcon_1, 1}}, - {1064, {wxIconBundle, getIcon_1_1, 1}}, - {1065, {wxIconBundle, getIcon_1_0, 1}}, - {1066, {wxCursor, new_0, 0}}, - {1067, {wxCursor, new_1_0, 1}}, - {1068, {wxCursor, new_1_1, 1}}, - {1069, {wxCursor, new_4, 4}}, - {1070, {wxCursor, destruct, 0}}, - {1071, {wxCursor, ok, 0}}, - {1072, {wxMask, new_0, 0}}, - {1073, {wxMask, new_2_1, 2}}, - {1074, {wxMask, new_2_0, 2}}, - {1075, {wxMask, new_1, 1}}, - {1076, {wxMask, destruct, 0}}, - {1077, {wxMask, create_2_1, 2}}, - {1078, {wxMask, create_2_0, 2}}, - {1079, {wxMask, create_1, 1}}, - {1080, {wxImage, new_0, 0}}, - {1081, {wxImage, new_3_0, 3}}, - {1082, {wxImage, new_4, 4}}, - {1083, {wxImage, new_5, 5}}, - {1084, {wxImage, new_2, 2}}, - {1085, {wxImage, new_3_1, 3}}, - {1086, {wxImage, blur, 1}}, - {1087, {wxImage, blurHorizontal, 1}}, - {1088, {wxImage, blurVertical, 1}}, - {1089, {wxImage, convertAlphaToMask, 1}}, - {1090, {wxImage, convertToGreyscale, 1}}, - {1091, {wxImage, convertToMono, 3}}, - {1092, {wxImage, copy, 0}}, - {1093, {wxImage, create_3, 3}}, - {1094, {wxImage, create_4, 4}}, - {1095, {wxImage, create_5, 5}}, - {1096, {wxImage, 'Destroy', 0}}, - {1097, {wxImage, findFirstUnusedColour, 4}}, - {1098, {wxImage, getImageExtWildcard, 0}}, - {1099, {wxImage, getAlpha_2, 2}}, - {1100, {wxImage, getAlpha_0, 0}}, - {1101, {wxImage, getBlue, 2}}, - {1102, {wxImage, getData, 0}}, - {1103, {wxImage, getGreen, 2}}, - {1104, {wxImage, getImageCount, 2}}, - {1105, {wxImage, getHeight, 0}}, - {1106, {wxImage, getMaskBlue, 0}}, - {1107, {wxImage, getMaskGreen, 0}}, - {1108, {wxImage, getMaskRed, 0}}, - {1109, {wxImage, getOrFindMaskColour, 3}}, - {1110, {wxImage, getPalette, 0}}, - {1111, {wxImage, getRed, 2}}, - {1112, {wxImage, getSubImage, 1}}, - {1113, {wxImage, getWidth, 0}}, - {1114, {wxImage, hasAlpha, 0}}, - {1115, {wxImage, hasMask, 0}}, - {1116, {wxImage, getOption, 1}}, - {1117, {wxImage, getOptionInt, 1}}, - {1118, {wxImage, hasOption, 1}}, - {1119, {wxImage, initAlpha, 0}}, - {1120, {wxImage, initStandardHandlers, 0}}, - {1121, {wxImage, isTransparent, 3}}, - {1122, {wxImage, loadFile_2, 2}}, - {1123, {wxImage, loadFile_3, 3}}, - {1124, {wxImage, ok, 0}}, - {1125, {wxImage, removeHandler, 1}}, - {1126, {wxImage, mirror, 1}}, - {1127, {wxImage, replace, 6}}, - {1128, {wxImage, rescale, 3}}, - {1129, {wxImage, resize, 3}}, - {1130, {wxImage, rotate, 3}}, - {1131, {wxImage, rotateHue, 1}}, - {1132, {wxImage, rotate90, 1}}, - {1133, {wxImage, saveFile_1, 1}}, - {1134, {wxImage, saveFile_2_0, 2}}, - {1135, {wxImage, saveFile_2_1, 2}}, - {1136, {wxImage, scale, 3}}, - {1137, {wxImage, size, 3}}, - {1138, {wxImage, setAlpha_3, 3}}, - {1139, {wxImage, setAlpha_2, 2}}, - {1140, {wxImage, setData_2, 2}}, - {1141, {wxImage, setData_4, 4}}, - {1142, {wxImage, setMask, 1}}, - {1143, {wxImage, setMaskColour, 3}}, - {1144, {wxImage, setMaskFromImage, 4}}, - {1145, {wxImage, setOption_2_1, 2}}, - {1146, {wxImage, setOption_2_0, 2}}, - {1147, {wxImage, setPalette, 1}}, - {1148, {wxImage, setRGB_5, 5}}, - {1149, {wxImage, setRGB_4, 4}}, - {1150, {wxImage, 'Destroy', undefined}}, - {1151, {wxBrush, new_0, 0}}, - {1152, {wxBrush, new_2, 2}}, - {1153, {wxBrush, new_1, 1}}, - {1155, {wxBrush, destruct, 0}}, - {1156, {wxBrush, getColour, 0}}, - {1157, {wxBrush, getStipple, 0}}, - {1158, {wxBrush, getStyle, 0}}, - {1159, {wxBrush, isHatch, 0}}, - {1160, {wxBrush, isOk, 0}}, - {1161, {wxBrush, setColour_1, 1}}, - {1162, {wxBrush, setColour_3, 3}}, - {1163, {wxBrush, setStipple, 1}}, - {1164, {wxBrush, setStyle, 1}}, - {1165, {wxPen, new_0, 0}}, - {1166, {wxPen, new_2, 2}}, - {1167, {wxPen, destruct, 0}}, - {1168, {wxPen, getCap, 0}}, - {1169, {wxPen, getColour, 0}}, - {1170, {wxPen, getJoin, 0}}, - {1171, {wxPen, getStyle, 0}}, - {1172, {wxPen, getWidth, 0}}, - {1173, {wxPen, isOk, 0}}, - {1174, {wxPen, setCap, 1}}, - {1175, {wxPen, setColour_1, 1}}, - {1176, {wxPen, setColour_3, 3}}, - {1177, {wxPen, setJoin, 1}}, - {1178, {wxPen, setStyle, 1}}, - {1179, {wxPen, setWidth, 1}}, - {1180, {wxRegion, new_0, 0}}, - {1181, {wxRegion, new_4, 4}}, - {1182, {wxRegion, new_2, 2}}, - {1183, {wxRegion, new_1_1, 1}}, - {1185, {wxRegion, new_1_0, 1}}, - {1187, {wxRegion, destruct, 0}}, - {1188, {wxRegion, clear, 0}}, - {1189, {wxRegion, contains_2, 2}}, - {1190, {wxRegion, contains_1_0, 1}}, - {1191, {wxRegion, contains_4, 4}}, - {1192, {wxRegion, contains_1_1, 1}}, - {1193, {wxRegion, convertToBitmap, 0}}, - {1194, {wxRegion, getBox, 0}}, - {1195, {wxRegion, intersect_4, 4}}, - {1196, {wxRegion, intersect_1_1, 1}}, - {1197, {wxRegion, intersect_1_0, 1}}, - {1198, {wxRegion, isEmpty, 0}}, - {1199, {wxRegion, subtract_4, 4}}, - {1200, {wxRegion, subtract_1_1, 1}}, - {1201, {wxRegion, subtract_1_0, 1}}, - {1202, {wxRegion, offset_2, 2}}, - {1203, {wxRegion, offset_1, 1}}, - {1204, {wxRegion, union_4, 4}}, - {1205, {wxRegion, union_1_2, 1}}, - {1206, {wxRegion, union_1_1, 1}}, - {1207, {wxRegion, union_1_0, 1}}, - {1208, {wxRegion, union_3, 3}}, - {1209, {wxRegion, xor_4, 4}}, - {1210, {wxRegion, xor_1_1, 1}}, - {1211, {wxRegion, xor_1_0, 1}}, - {1212, {wxAcceleratorTable, new_0, 0}}, - {1213, {wxAcceleratorTable, new_2, 2}}, - {1214, {wxAcceleratorTable, destruct, 0}}, - {1215, {wxAcceleratorTable, ok, 0}}, - {1216, {wxAcceleratorEntry, new_1_0, 1}}, - {1217, {wxAcceleratorEntry, new_1_1, 1}}, - {1218, {wxAcceleratorEntry, getCommand, 0}}, - {1219, {wxAcceleratorEntry, getFlags, 0}}, - {1220, {wxAcceleratorEntry, getKeyCode, 0}}, - {1221, {wxAcceleratorEntry, set, 4}}, - {1222, {wxAcceleratorEntry, 'Destroy', undefined}}, - {1227, {wxCaret, new_3, 3}}, - {1228, {wxCaret, new_2, 2}}, - {1230, {wxCaret, destruct, 0}}, - {1231, {wxCaret, create_3, 3}}, - {1232, {wxCaret, create_2, 2}}, - {1233, {wxCaret, getBlinkTime, 0}}, - {1235, {wxCaret, getPosition, 0}}, - {1237, {wxCaret, getSize, 0}}, - {1238, {wxCaret, getWindow, 0}}, - {1239, {wxCaret, hide, 0}}, - {1240, {wxCaret, isOk, 0}}, - {1241, {wxCaret, isVisible, 0}}, - {1242, {wxCaret, move_2, 2}}, - {1243, {wxCaret, move_1, 1}}, - {1244, {wxCaret, setBlinkTime, 1}}, - {1245, {wxCaret, setSize_2, 2}}, - {1246, {wxCaret, setSize_1, 1}}, - {1247, {wxCaret, show, 1}}, - {1248, {wxSizer, add_2_1, 2}}, - {1249, {wxSizer, add_2_0, 2}}, - {1250, {wxSizer, add_3, 3}}, - {1251, {wxSizer, add_2_3, 2}}, - {1252, {wxSizer, add_2_2, 2}}, - {1253, {wxSizer, addSpacer, 1}}, - {1254, {wxSizer, addStretchSpacer, 1}}, - {1255, {wxSizer, calcMin, 0}}, - {1256, {wxSizer, clear, 1}}, - {1257, {wxSizer, detach_1_2, 1}}, - {1258, {wxSizer, detach_1_1, 1}}, - {1259, {wxSizer, detach_1_0, 1}}, - {1260, {wxSizer, fit, 1}}, - {1261, {wxSizer, fitInside, 1}}, - {1262, {wxSizer, getChildren, 0}}, - {1263, {wxSizer, getItem_2_1, 2}}, - {1264, {wxSizer, getItem_2_0, 2}}, - {1265, {wxSizer, getItem_1, 1}}, - {1266, {wxSizer, getSize, 0}}, - {1267, {wxSizer, getPosition, 0}}, - {1268, {wxSizer, getMinSize, 0}}, - {1269, {wxSizer, hide_2_0, 2}}, - {1270, {wxSizer, hide_2_1, 2}}, - {1271, {wxSizer, hide_1, 1}}, - {1272, {wxSizer, insert_3_1, 3}}, - {1273, {wxSizer, insert_3_0, 3}}, - {1274, {wxSizer, insert_4, 4}}, - {1275, {wxSizer, insert_3_3, 3}}, - {1276, {wxSizer, insert_3_2, 3}}, - {1277, {wxSizer, insert_2, 2}}, - {1278, {wxSizer, insertSpacer, 2}}, - {1279, {wxSizer, insertStretchSpacer, 2}}, - {1280, {wxSizer, isShown_1_2, 1}}, - {1281, {wxSizer, isShown_1_1, 1}}, - {1282, {wxSizer, isShown_1_0, 1}}, - {1283, {wxSizer, layout, 0}}, - {1284, {wxSizer, prepend_2_1, 2}}, - {1285, {wxSizer, prepend_2_0, 2}}, - {1286, {wxSizer, prepend_3, 3}}, - {1287, {wxSizer, prepend_2_3, 2}}, - {1288, {wxSizer, prepend_2_2, 2}}, - {1289, {wxSizer, prepend_1, 1}}, - {1290, {wxSizer, prependSpacer, 1}}, - {1291, {wxSizer, prependStretchSpacer, 1}}, - {1292, {wxSizer, recalcSizes, 0}}, - {1293, {wxSizer, remove_1_1, 1}}, - {1294, {wxSizer, remove_1_0, 1}}, - {1295, {wxSizer, replace_3_1, 3}}, - {1296, {wxSizer, replace_3_0, 3}}, - {1297, {wxSizer, replace_2, 2}}, - {1298, {wxSizer, setDimension, 4}}, - {1299, {wxSizer, setMinSize_2, 2}}, - {1300, {wxSizer, setMinSize_1, 1}}, - {1301, {wxSizer, setItemMinSize_3_2, 3}}, - {1302, {wxSizer, setItemMinSize_2_2, 2}}, - {1303, {wxSizer, setItemMinSize_3_1, 3}}, - {1304, {wxSizer, setItemMinSize_2_1, 2}}, - {1305, {wxSizer, setItemMinSize_3_0, 3}}, - {1306, {wxSizer, setItemMinSize_2_0, 2}}, - {1307, {wxSizer, setSizeHints, 1}}, - {1308, {wxSizer, setVirtualSizeHints, 1}}, - {1309, {wxSizer, show_2_2, 2}}, - {1310, {wxSizer, show_2_1, 2}}, - {1311, {wxSizer, show_2_0, 2}}, - {1312, {wxSizer, show_1, 1}}, - {1313, {wxSizerFlags, new, 1}}, - {1314, {wxSizerFlags, align, 1}}, - {1315, {wxSizerFlags, border_2, 2}}, - {1316, {wxSizerFlags, border_1, 1}}, - {1317, {wxSizerFlags, center, 0}}, - {1318, {wxSizerFlags, centre, 0}}, - {1319, {wxSizerFlags, expand, 0}}, - {1320, {wxSizerFlags, left, 0}}, - {1321, {wxSizerFlags, proportion, 1}}, - {1322, {wxSizerFlags, right, 0}}, - {1323, {wxSizerFlags, 'Destroy', undefined}}, - {1324, {wxSizerItem, new_5_1, 5}}, - {1325, {wxSizerItem, new_2_1, 2}}, - {1326, {wxSizerItem, new_5_0, 5}}, - {1327, {wxSizerItem, new_2_0, 2}}, - {1328, {wxSizerItem, new_6, 6}}, - {1329, {wxSizerItem, new_3, 3}}, - {1330, {wxSizerItem, new_0, 0}}, - {1331, {wxSizerItem, destruct, 0}}, - {1332, {wxSizerItem, calcMin, 0}}, - {1333, {wxSizerItem, deleteWindows, 0}}, - {1334, {wxSizerItem, detachSizer, 0}}, - {1335, {wxSizerItem, getBorder, 0}}, - {1336, {wxSizerItem, getFlag, 0}}, - {1337, {wxSizerItem, getMinSize, 0}}, - {1338, {wxSizerItem, getPosition, 0}}, - {1339, {wxSizerItem, getProportion, 0}}, - {1340, {wxSizerItem, getRatio, 0}}, - {1341, {wxSizerItem, getRect, 0}}, - {1342, {wxSizerItem, getSize, 0}}, - {1343, {wxSizerItem, getSizer, 0}}, - {1344, {wxSizerItem, getSpacer, 0}}, - {1345, {wxSizerItem, getUserData, 0}}, - {1346, {wxSizerItem, getWindow, 0}}, - {1347, {wxSizerItem, isSizer, 0}}, - {1348, {wxSizerItem, isShown, 0}}, - {1349, {wxSizerItem, isSpacer, 0}}, - {1350, {wxSizerItem, isWindow, 0}}, - {1351, {wxSizerItem, setBorder, 1}}, - {1352, {wxSizerItem, setDimension, 2}}, - {1353, {wxSizerItem, setFlag, 1}}, - {1354, {wxSizerItem, setInitSize, 2}}, - {1355, {wxSizerItem, setMinSize_1, 1}}, - {1356, {wxSizerItem, setMinSize_2, 2}}, - {1357, {wxSizerItem, setProportion, 1}}, - {1358, {wxSizerItem, setRatio_2, 2}}, - {1359, {wxSizerItem, setRatio_1_1, 1}}, - {1360, {wxSizerItem, setRatio_1_0, 1}}, - {1361, {wxSizerItem, setSizer, 1}}, - {1362, {wxSizerItem, setSpacer_1, 1}}, - {1363, {wxSizerItem, setSpacer_2, 2}}, - {1364, {wxSizerItem, setWindow, 1}}, - {1365, {wxSizerItem, show, 1}}, - {1366, {wxBoxSizer, new, 1}}, - {1367, {wxBoxSizer, getOrientation, 0}}, - {1368, {wxBoxSizer, 'Destroy', undefined}}, - {1369, {wxStaticBoxSizer, new_2, 2}}, - {1370, {wxStaticBoxSizer, new_3, 3}}, - {1371, {wxStaticBoxSizer, getStaticBox, 0}}, - {1372, {wxStaticBoxSizer, 'Destroy', undefined}}, - {1373, {wxGridSizer, new_4, 4}}, - {1374, {wxGridSizer, new_2, 2}}, - {1375, {wxGridSizer, getCols, 0}}, - {1376, {wxGridSizer, getHGap, 0}}, - {1377, {wxGridSizer, getRows, 0}}, - {1378, {wxGridSizer, getVGap, 0}}, - {1379, {wxGridSizer, setCols, 1}}, - {1380, {wxGridSizer, setHGap, 1}}, - {1381, {wxGridSizer, setRows, 1}}, - {1382, {wxGridSizer, setVGap, 1}}, - {1383, {wxGridSizer, 'Destroy', undefined}}, - {1384, {wxFlexGridSizer, new_4, 4}}, - {1385, {wxFlexGridSizer, new_2, 2}}, - {1386, {wxFlexGridSizer, addGrowableCol, 2}}, - {1387, {wxFlexGridSizer, addGrowableRow, 2}}, - {1388, {wxFlexGridSizer, getFlexibleDirection, 0}}, - {1389, {wxFlexGridSizer, getNonFlexibleGrowMode, 0}}, - {1390, {wxFlexGridSizer, removeGrowableCol, 1}}, - {1391, {wxFlexGridSizer, removeGrowableRow, 1}}, - {1392, {wxFlexGridSizer, setFlexibleDirection, 1}}, - {1393, {wxFlexGridSizer, setNonFlexibleGrowMode, 1}}, - {1394, {wxFlexGridSizer, 'Destroy', undefined}}, - {1395, {wxGridBagSizer, new, 1}}, - {1396, {wxGridBagSizer, add_3_2, 3}}, - {1397, {wxGridBagSizer, add_3_1, 3}}, - {1398, {wxGridBagSizer, add_4, 4}}, - {1399, {wxGridBagSizer, add_1_0, 1}}, - {1400, {wxGridBagSizer, add_2_1, 2}}, - {1401, {wxGridBagSizer, add_2_0, 2}}, - {1402, {wxGridBagSizer, add_3_0, 3}}, - {1403, {wxGridBagSizer, add_1_1, 1}}, - {1404, {wxGridBagSizer, calcMin, 0}}, - {1405, {wxGridBagSizer, checkForIntersection_2, 2}}, - {1406, {wxGridBagSizer, checkForIntersection_3, 3}}, - {1407, {wxGridBagSizer, findItem_1_1, 1}}, - {1408, {wxGridBagSizer, findItem_1_0, 1}}, - {1409, {wxGridBagSizer, findItemAtPoint, 1}}, - {1410, {wxGridBagSizer, findItemAtPosition, 1}}, - {1411, {wxGridBagSizer, findItemWithData, 1}}, - {1412, {wxGridBagSizer, getCellSize, 2}}, - {1413, {wxGridBagSizer, getEmptyCellSize, 0}}, - {1414, {wxGridBagSizer, getItemPosition_1_2, 1}}, - {1415, {wxGridBagSizer, getItemPosition_1_1, 1}}, - {1416, {wxGridBagSizer, getItemPosition_1_0, 1}}, - {1417, {wxGridBagSizer, getItemSpan_1_2, 1}}, - {1418, {wxGridBagSizer, getItemSpan_1_1, 1}}, - {1419, {wxGridBagSizer, getItemSpan_1_0, 1}}, - {1420, {wxGridBagSizer, setEmptyCellSize, 1}}, - {1421, {wxGridBagSizer, setItemPosition_2_2, 2}}, - {1422, {wxGridBagSizer, setItemPosition_2_1, 2}}, - {1423, {wxGridBagSizer, setItemPosition_2_0, 2}}, - {1424, {wxGridBagSizer, setItemSpan_2_2, 2}}, - {1425, {wxGridBagSizer, setItemSpan_2_1, 2}}, - {1426, {wxGridBagSizer, setItemSpan_2_0, 2}}, - {1427, {wxGridBagSizer, 'Destroy', undefined}}, - {1428, {wxStdDialogButtonSizer, new, 0}}, - {1429, {wxStdDialogButtonSizer, addButton, 1}}, - {1430, {wxStdDialogButtonSizer, realize, 0}}, - {1431, {wxStdDialogButtonSizer, setAffirmativeButton, 1}}, - {1432, {wxStdDialogButtonSizer, setCancelButton, 1}}, - {1433, {wxStdDialogButtonSizer, setNegativeButton, 1}}, - {1434, {wxStdDialogButtonSizer, 'Destroy', undefined}}, - {1435, {wxFont, new_0, 0}}, - {1436, {wxFont, new_1, 1}}, - {1437, {wxFont, new_5, 5}}, - {1439, {wxFont, destruct, 0}}, - {1440, {wxFont, isFixedWidth, 0}}, - {1441, {wxFont, getDefaultEncoding, 0}}, - {1442, {wxFont, getFaceName, 0}}, - {1443, {wxFont, getFamily, 0}}, - {1444, {wxFont, getNativeFontInfoDesc, 0}}, - {1445, {wxFont, getNativeFontInfoUserDesc, 0}}, - {1446, {wxFont, getPointSize, 0}}, - {1447, {wxFont, getStyle, 0}}, - {1448, {wxFont, getUnderlined, 0}}, - {1449, {wxFont, getWeight, 0}}, - {1450, {wxFont, ok, 0}}, - {1451, {wxFont, setDefaultEncoding, 1}}, - {1452, {wxFont, setFaceName, 1}}, - {1453, {wxFont, setFamily, 1}}, - {1454, {wxFont, setPointSize, 1}}, - {1455, {wxFont, setStyle, 1}}, - {1456, {wxFont, setUnderlined, 1}}, - {1457, {wxFont, setWeight, 1}}, - {1458, {wxToolTip, enable, 1}}, - {1459, {wxToolTip, setDelay, 1}}, - {1460, {wxToolTip, new, 1}}, - {1461, {wxToolTip, setTip, 1}}, - {1462, {wxToolTip, getTip, 0}}, - {1463, {wxToolTip, getWindow, 0}}, - {1464, {wxToolTip, 'Destroy', undefined}}, - {1466, {wxButton, new_3, 3}}, - {1467, {wxButton, new_0, 0}}, - {1468, {wxButton, destruct, 0}}, - {1469, {wxButton, create, 3}}, - {1470, {wxButton, getDefaultSize, 0}}, - {1471, {wxButton, setDefault, 0}}, - {1472, {wxButton, setLabel, 1}}, - {1474, {wxBitmapButton, new_4, 4}}, - {1475, {wxBitmapButton, new_0, 0}}, - {1476, {wxBitmapButton, create, 4}}, - {1477, {wxBitmapButton, getBitmapDisabled, 0}}, - {1479, {wxBitmapButton, getBitmapFocus, 0}}, - {1481, {wxBitmapButton, getBitmapLabel, 0}}, - {1483, {wxBitmapButton, getBitmapSelected, 0}}, - {1485, {wxBitmapButton, setBitmapDisabled, 1}}, - {1486, {wxBitmapButton, setBitmapFocus, 1}}, - {1487, {wxBitmapButton, setBitmapLabel, 1}}, - {1488, {wxBitmapButton, setBitmapSelected, 1}}, - {1489, {wxBitmapButton, 'Destroy', undefined}}, - {1490, {wxToggleButton, new_0, 0}}, - {1491, {wxToggleButton, new_4, 4}}, - {1492, {wxToggleButton, create, 4}}, - {1493, {wxToggleButton, getValue, 0}}, - {1494, {wxToggleButton, setValue, 1}}, - {1495, {wxToggleButton, 'Destroy', undefined}}, - {1496, {wxCalendarCtrl, new_0, 0}}, - {1497, {wxCalendarCtrl, new_3, 3}}, - {1498, {wxCalendarCtrl, create, 3}}, - {1499, {wxCalendarCtrl, destruct, 0}}, - {1500, {wxCalendarCtrl, setDate, 1}}, - {1501, {wxCalendarCtrl, getDate, 0}}, - {1502, {wxCalendarCtrl, enableYearChange, 1}}, - {1503, {wxCalendarCtrl, enableMonthChange, 1}}, - {1504, {wxCalendarCtrl, enableHolidayDisplay, 1}}, - {1505, {wxCalendarCtrl, setHeaderColours, 2}}, - {1506, {wxCalendarCtrl, getHeaderColourFg, 0}}, - {1507, {wxCalendarCtrl, getHeaderColourBg, 0}}, - {1508, {wxCalendarCtrl, setHighlightColours, 2}}, - {1509, {wxCalendarCtrl, getHighlightColourFg, 0}}, - {1510, {wxCalendarCtrl, getHighlightColourBg, 0}}, - {1511, {wxCalendarCtrl, setHolidayColours, 2}}, - {1512, {wxCalendarCtrl, getHolidayColourFg, 0}}, - {1513, {wxCalendarCtrl, getHolidayColourBg, 0}}, - {1514, {wxCalendarCtrl, getAttr, 1}}, - {1515, {wxCalendarCtrl, setAttr, 2}}, - {1516, {wxCalendarCtrl, setHoliday, 1}}, - {1517, {wxCalendarCtrl, resetAttr, 1}}, - {1518, {wxCalendarCtrl, hitTest, 2}}, - {1519, {wxCalendarDateAttr, new_0, 0}}, - {1520, {wxCalendarDateAttr, new_2_1, 2}}, - {1521, {wxCalendarDateAttr, new_2_0, 2}}, - {1522, {wxCalendarDateAttr, setTextColour, 1}}, - {1523, {wxCalendarDateAttr, setBackgroundColour, 1}}, - {1524, {wxCalendarDateAttr, setBorderColour, 1}}, - {1525, {wxCalendarDateAttr, setFont, 1}}, - {1526, {wxCalendarDateAttr, setBorder, 1}}, - {1527, {wxCalendarDateAttr, setHoliday, 1}}, - {1528, {wxCalendarDateAttr, hasTextColour, 0}}, - {1529, {wxCalendarDateAttr, hasBackgroundColour, 0}}, - {1530, {wxCalendarDateAttr, hasBorderColour, 0}}, - {1531, {wxCalendarDateAttr, hasFont, 0}}, - {1532, {wxCalendarDateAttr, hasBorder, 0}}, - {1533, {wxCalendarDateAttr, isHoliday, 0}}, - {1534, {wxCalendarDateAttr, getTextColour, 0}}, - {1535, {wxCalendarDateAttr, getBackgroundColour, 0}}, - {1536, {wxCalendarDateAttr, getBorderColour, 0}}, - {1537, {wxCalendarDateAttr, getFont, 0}}, - {1538, {wxCalendarDateAttr, getBorder, 0}}, - {1539, {wxCalendarDateAttr, 'Destroy', undefined}}, - {1541, {wxCheckBox, new_4, 4}}, - {1542, {wxCheckBox, new_0, 0}}, - {1543, {wxCheckBox, create, 4}}, - {1544, {wxCheckBox, getValue, 0}}, - {1545, {wxCheckBox, get3StateValue, 0}}, - {1546, {wxCheckBox, is3rdStateAllowedForUser, 0}}, - {1547, {wxCheckBox, is3State, 0}}, - {1548, {wxCheckBox, isChecked, 0}}, - {1549, {wxCheckBox, setValue, 1}}, - {1550, {wxCheckBox, set3StateValue, 1}}, - {1551, {wxCheckBox, 'Destroy', undefined}}, - {1552, {wxCheckListBox, new_0, 0}}, - {1554, {wxCheckListBox, new_3, 3}}, - {1555, {wxCheckListBox, check, 2}}, - {1556, {wxCheckListBox, isChecked, 1}}, - {1557, {wxCheckListBox, 'Destroy', undefined}}, - {1560, {wxChoice, new_3, 3}}, - {1561, {wxChoice, new_0, 0}}, - {1563, {wxChoice, destruct, 0}}, - {1565, {wxChoice, create, 6}}, - {1566, {wxChoice, delete, 1}}, - {1567, {wxChoice, getColumns, 0}}, - {1568, {wxChoice, setColumns, 1}}, - {1569, {wxComboBox, new_0, 0}}, - {1571, {wxComboBox, new_3, 3}}, - {1572, {wxComboBox, destruct, 0}}, - {1574, {wxComboBox, create, 7}}, - {1575, {wxComboBox, canCopy, 0}}, - {1576, {wxComboBox, canCut, 0}}, - {1577, {wxComboBox, canPaste, 0}}, - {1578, {wxComboBox, canRedo, 0}}, - {1579, {wxComboBox, canUndo, 0}}, - {1580, {wxComboBox, copy, 0}}, - {1581, {wxComboBox, cut, 0}}, - {1582, {wxComboBox, getInsertionPoint, 0}}, - {1583, {wxComboBox, getLastPosition, 0}}, - {1584, {wxComboBox, getValue, 0}}, - {1585, {wxComboBox, paste, 0}}, - {1586, {wxComboBox, redo, 0}}, - {1587, {wxComboBox, replace, 3}}, - {1588, {wxComboBox, remove, 2}}, - {1589, {wxComboBox, setInsertionPoint, 1}}, - {1590, {wxComboBox, setInsertionPointEnd, 0}}, - {1591, {wxComboBox, setSelection_1, 1}}, - {1592, {wxComboBox, setSelection_2, 2}}, - {1593, {wxComboBox, setValue, 1}}, - {1594, {wxComboBox, undo, 0}}, - {1595, {wxGauge, new_0, 0}}, - {1596, {wxGauge, new_4, 4}}, - {1597, {wxGauge, create, 4}}, - {1598, {wxGauge, getBezelFace, 0}}, - {1599, {wxGauge, getRange, 0}}, - {1600, {wxGauge, getShadowWidth, 0}}, - {1601, {wxGauge, getValue, 0}}, - {1602, {wxGauge, isVertical, 0}}, - {1603, {wxGauge, setBezelFace, 1}}, - {1604, {wxGauge, setRange, 1}}, - {1605, {wxGauge, setShadowWidth, 1}}, - {1606, {wxGauge, setValue, 1}}, - {1607, {wxGauge, pulse, 0}}, - {1608, {wxGauge, 'Destroy', undefined}}, - {1609, {wxGenericDirCtrl, new_0, 0}}, - {1610, {wxGenericDirCtrl, new_2, 2}}, - {1611, {wxGenericDirCtrl, destruct, 0}}, - {1612, {wxGenericDirCtrl, create, 2}}, - {1613, {wxGenericDirCtrl, init, 0}}, - {1614, {wxGenericDirCtrl, collapseTree, 0}}, - {1615, {wxGenericDirCtrl, expandPath, 1}}, - {1616, {wxGenericDirCtrl, getDefaultPath, 0}}, - {1617, {wxGenericDirCtrl, getPath, 0}}, - {1618, {wxGenericDirCtrl, getFilePath, 0}}, - {1619, {wxGenericDirCtrl, getFilter, 0}}, - {1620, {wxGenericDirCtrl, getFilterIndex, 0}}, - {1621, {wxGenericDirCtrl, getRootId, 0}}, - {1622, {wxGenericDirCtrl, getTreeCtrl, 0}}, - {1623, {wxGenericDirCtrl, reCreateTree, 0}}, - {1624, {wxGenericDirCtrl, setDefaultPath, 1}}, - {1625, {wxGenericDirCtrl, setFilter, 1}}, - {1626, {wxGenericDirCtrl, setFilterIndex, 1}}, - {1627, {wxGenericDirCtrl, setPath, 1}}, - {1629, {wxStaticBox, new_4, 4}}, - {1630, {wxStaticBox, new_0, 0}}, - {1631, {wxStaticBox, create, 4}}, - {1632, {wxStaticBox, 'Destroy', undefined}}, - {1634, {wxStaticLine, new_2, 2}}, - {1635, {wxStaticLine, new_0, 0}}, - {1636, {wxStaticLine, create, 2}}, - {1637, {wxStaticLine, isVertical, 0}}, - {1638, {wxStaticLine, getDefaultSize, 0}}, - {1639, {wxStaticLine, 'Destroy', undefined}}, - {1642, {wxListBox, new_3, 3}}, - {1643, {wxListBox, new_0, 0}}, - {1645, {wxListBox, destruct, 0}}, - {1647, {wxListBox, create, 6}}, - {1648, {wxListBox, deselect, 1}}, - {1649, {wxListBox, getSelections, 1}}, - {1650, {wxListBox, insertItems, 2}}, - {1651, {wxListBox, isSelected, 1}}, - {1653, {wxListBox, set, 2}}, - {1654, {wxListBox, hitTest, 1}}, - {1655, {wxListBox, setFirstItem_1_0, 1}}, - {1656, {wxListBox, setFirstItem_1_1, 1}}, - {1657, {wxListCtrl, new_0, 0}}, - {1658, {wxListCtrl, new_2, 2}}, - {1659, {wxListCtrl, arrange, 1}}, - {1660, {wxListCtrl, assignImageList, 2}}, - {1661, {wxListCtrl, clearAll, 0}}, - {1662, {wxListCtrl, create, 2}}, - {1663, {wxListCtrl, deleteAllItems, 0}}, - {1664, {wxListCtrl, deleteColumn, 1}}, - {1665, {wxListCtrl, deleteItem, 1}}, - {1666, {wxListCtrl, editLabel, 1}}, - {1667, {wxListCtrl, ensureVisible, 1}}, - {1668, {wxListCtrl, findItem_3_0, 3}}, - {1669, {wxListCtrl, findItem_3_1, 3}}, - {1670, {wxListCtrl, getColumn, 2}}, - {1671, {wxListCtrl, getColumnCount, 0}}, - {1672, {wxListCtrl, getColumnWidth, 1}}, - {1673, {wxListCtrl, getCountPerPage, 0}}, - {1674, {wxListCtrl, getEditControl, 0}}, - {1675, {wxListCtrl, getImageList, 1}}, - {1676, {wxListCtrl, getItem, 1}}, - {1677, {wxListCtrl, getItemBackgroundColour, 1}}, - {1678, {wxListCtrl, getItemCount, 0}}, - {1679, {wxListCtrl, getItemData, 1}}, - {1680, {wxListCtrl, getItemFont, 1}}, - {1681, {wxListCtrl, getItemPosition, 2}}, - {1682, {wxListCtrl, getItemRect, 3}}, - {1683, {wxListCtrl, getItemSpacing, 0}}, - {1684, {wxListCtrl, getItemState, 2}}, - {1685, {wxListCtrl, getItemText, 1}}, - {1686, {wxListCtrl, getItemTextColour, 1}}, - {1687, {wxListCtrl, getNextItem, 2}}, - {1688, {wxListCtrl, getSelectedItemCount, 0}}, - {1689, {wxListCtrl, getTextColour, 0}}, - {1690, {wxListCtrl, getTopItem, 0}}, - {1691, {wxListCtrl, getViewRect, 0}}, - {1692, {wxListCtrl, hitTest, 2}}, - {1693, {wxListCtrl, insertColumn_2, 2}}, - {1694, {wxListCtrl, insertColumn_3, 3}}, - {1695, {wxListCtrl, insertItem_1, 1}}, - {1696, {wxListCtrl, insertItem_2_1, 2}}, - {1697, {wxListCtrl, insertItem_2_0, 2}}, - {1698, {wxListCtrl, insertItem_3, 3}}, - {1699, {wxListCtrl, refreshItem, 1}}, - {1700, {wxListCtrl, refreshItems, 2}}, - {1701, {wxListCtrl, scrollList, 2}}, - {1702, {wxListCtrl, setBackgroundColour, 1}}, - {1703, {wxListCtrl, setColumn, 2}}, - {1704, {wxListCtrl, setColumnWidth, 2}}, - {1705, {wxListCtrl, setImageList, 2}}, - {1706, {wxListCtrl, setItem_1, 1}}, - {1707, {wxListCtrl, setItem_4, 4}}, - {1708, {wxListCtrl, setItemBackgroundColour, 2}}, - {1709, {wxListCtrl, setItemCount, 1}}, - {1710, {wxListCtrl, setItemData, 2}}, - {1711, {wxListCtrl, setItemFont, 2}}, - {1712, {wxListCtrl, setItemImage, 3}}, - {1713, {wxListCtrl, setItemColumnImage, 3}}, - {1714, {wxListCtrl, setItemPosition, 2}}, - {1715, {wxListCtrl, setItemState, 3}}, - {1716, {wxListCtrl, setItemText, 2}}, - {1717, {wxListCtrl, setItemTextColour, 2}}, - {1718, {wxListCtrl, setSingleStyle, 2}}, - {1719, {wxListCtrl, setTextColour, 1}}, - {1720, {wxListCtrl, setWindowStyleFlag, 1}}, - {1721, {wxListCtrl, sortItems, 2}}, - {1722, {wxListCtrl, 'Destroy', undefined}}, - {1723, {wxListView, clearColumnImage, 1}}, - {1724, {wxListView, focus, 1}}, - {1725, {wxListView, getFirstSelected, 0}}, - {1726, {wxListView, getFocusedItem, 0}}, - {1727, {wxListView, getNextSelected, 1}}, - {1728, {wxListView, isSelected, 1}}, - {1729, {wxListView, select, 2}}, - {1730, {wxListView, setColumnImage, 2}}, - {1731, {wxListItem, new_0, 0}}, - {1732, {wxListItem, new_1, 1}}, - {1733, {wxListItem, destruct, 0}}, - {1734, {wxListItem, clear, 0}}, - {1735, {wxListItem, getAlign, 0}}, - {1736, {wxListItem, getBackgroundColour, 0}}, - {1737, {wxListItem, getColumn, 0}}, - {1738, {wxListItem, getFont, 0}}, - {1739, {wxListItem, getId, 0}}, - {1740, {wxListItem, getImage, 0}}, - {1741, {wxListItem, getMask, 0}}, - {1742, {wxListItem, getState, 0}}, - {1743, {wxListItem, getText, 0}}, - {1744, {wxListItem, getTextColour, 0}}, - {1745, {wxListItem, getWidth, 0}}, - {1746, {wxListItem, setAlign, 1}}, - {1747, {wxListItem, setBackgroundColour, 1}}, - {1748, {wxListItem, setColumn, 1}}, - {1749, {wxListItem, setFont, 1}}, - {1750, {wxListItem, setId, 1}}, - {1751, {wxListItem, setImage, 1}}, - {1752, {wxListItem, setMask, 1}}, - {1753, {wxListItem, setState, 1}}, - {1754, {wxListItem, setStateMask, 1}}, - {1755, {wxListItem, setText, 1}}, - {1756, {wxListItem, setTextColour, 1}}, - {1757, {wxListItem, setWidth, 1}}, - {1758, {wxListItemAttr, new_0, 0}}, - {1759, {wxListItemAttr, new_3, 3}}, - {1760, {wxListItemAttr, getBackgroundColour, 0}}, - {1761, {wxListItemAttr, getFont, 0}}, - {1762, {wxListItemAttr, getTextColour, 0}}, - {1763, {wxListItemAttr, hasBackgroundColour, 0}}, - {1764, {wxListItemAttr, hasFont, 0}}, - {1765, {wxListItemAttr, hasTextColour, 0}}, - {1766, {wxListItemAttr, setBackgroundColour, 1}}, - {1767, {wxListItemAttr, setFont, 1}}, - {1768, {wxListItemAttr, setTextColour, 1}}, - {1769, {wxListItemAttr, 'Destroy', undefined}}, - {1770, {wxImageList, new_0, 0}}, - {1771, {wxImageList, new_3, 3}}, - {1772, {wxImageList, add_1, 1}}, - {1773, {wxImageList, add_2_0, 2}}, - {1774, {wxImageList, add_2_1, 2}}, - {1775, {wxImageList, create, 3}}, - {1777, {wxImageList, draw, 5}}, - {1778, {wxImageList, getBitmap, 1}}, - {1779, {wxImageList, getIcon, 1}}, - {1780, {wxImageList, getImageCount, 0}}, - {1781, {wxImageList, getSize, 3}}, - {1782, {wxImageList, remove, 1}}, - {1783, {wxImageList, removeAll, 0}}, - {1784, {wxImageList, replace_2, 2}}, - {1785, {wxImageList, replace_3, 3}}, - {1786, {wxImageList, 'Destroy', undefined}}, - {1787, {wxTextAttr, new_0, 0}}, - {1788, {wxTextAttr, new_2, 2}}, - {1789, {wxTextAttr, getAlignment, 0}}, - {1790, {wxTextAttr, getBackgroundColour, 0}}, - {1791, {wxTextAttr, getFont, 0}}, - {1792, {wxTextAttr, getLeftIndent, 0}}, - {1793, {wxTextAttr, getLeftSubIndent, 0}}, - {1794, {wxTextAttr, getRightIndent, 0}}, - {1795, {wxTextAttr, getTabs, 0}}, - {1796, {wxTextAttr, getTextColour, 0}}, - {1797, {wxTextAttr, hasBackgroundColour, 0}}, - {1798, {wxTextAttr, hasFont, 0}}, - {1799, {wxTextAttr, hasTextColour, 0}}, - {1800, {wxTextAttr, getFlags, 0}}, - {1801, {wxTextAttr, isDefault, 0}}, - {1802, {wxTextAttr, setAlignment, 1}}, - {1803, {wxTextAttr, setBackgroundColour, 1}}, - {1804, {wxTextAttr, setFlags, 1}}, - {1805, {wxTextAttr, setFont, 2}}, - {1806, {wxTextAttr, setLeftIndent, 2}}, - {1807, {wxTextAttr, setRightIndent, 1}}, - {1808, {wxTextAttr, setTabs, 1}}, - {1809, {wxTextAttr, setTextColour, 1}}, - {1810, {wxTextAttr, 'Destroy', undefined}}, - {1812, {wxTextCtrl, new_3, 3}}, - {1813, {wxTextCtrl, new_0, 0}}, - {1815, {wxTextCtrl, destruct, 0}}, - {1816, {wxTextCtrl, appendText, 1}}, - {1817, {wxTextCtrl, canCopy, 0}}, - {1818, {wxTextCtrl, canCut, 0}}, - {1819, {wxTextCtrl, canPaste, 0}}, - {1820, {wxTextCtrl, canRedo, 0}}, - {1821, {wxTextCtrl, canUndo, 0}}, - {1822, {wxTextCtrl, clear, 0}}, - {1823, {wxTextCtrl, copy, 0}}, - {1824, {wxTextCtrl, create, 3}}, - {1825, {wxTextCtrl, cut, 0}}, - {1826, {wxTextCtrl, discardEdits, 0}}, - {1827, {wxTextCtrl, emulateKeyPress, 1}}, - {1828, {wxTextCtrl, getDefaultStyle, 0}}, - {1829, {wxTextCtrl, getInsertionPoint, 0}}, - {1830, {wxTextCtrl, getLastPosition, 0}}, - {1831, {wxTextCtrl, getLineLength, 1}}, - {1832, {wxTextCtrl, getLineText, 1}}, - {1833, {wxTextCtrl, getNumberOfLines, 0}}, - {1834, {wxTextCtrl, getRange, 2}}, - {1835, {wxTextCtrl, getSelection, 2}}, - {1836, {wxTextCtrl, getStringSelection, 0}}, - {1837, {wxTextCtrl, getStyle, 2}}, - {1838, {wxTextCtrl, getValue, 0}}, - {1839, {wxTextCtrl, isEditable, 0}}, - {1840, {wxTextCtrl, isModified, 0}}, - {1841, {wxTextCtrl, isMultiLine, 0}}, - {1842, {wxTextCtrl, isSingleLine, 0}}, - {1843, {wxTextCtrl, loadFile, 2}}, - {1844, {wxTextCtrl, markDirty, 0}}, - {1845, {wxTextCtrl, paste, 0}}, - {1846, {wxTextCtrl, positionToXY, 3}}, - {1847, {wxTextCtrl, redo, 0}}, - {1848, {wxTextCtrl, remove, 2}}, - {1849, {wxTextCtrl, replace, 3}}, - {1850, {wxTextCtrl, saveFile, 1}}, - {1851, {wxTextCtrl, setDefaultStyle, 1}}, - {1852, {wxTextCtrl, setEditable, 1}}, - {1853, {wxTextCtrl, setInsertionPoint, 1}}, - {1854, {wxTextCtrl, setInsertionPointEnd, 0}}, - {1856, {wxTextCtrl, setMaxLength, 1}}, - {1857, {wxTextCtrl, setSelection, 2}}, - {1858, {wxTextCtrl, setStyle, 3}}, - {1859, {wxTextCtrl, setValue, 1}}, - {1860, {wxTextCtrl, showPosition, 1}}, - {1861, {wxTextCtrl, undo, 0}}, - {1862, {wxTextCtrl, writeText, 1}}, - {1863, {wxTextCtrl, xYToPosition, 2}}, - {1866, {wxNotebook, new_0, 0}}, - {1867, {wxNotebook, new_3, 3}}, - {1868, {wxNotebook, destruct, 0}}, - {1869, {wxNotebook, addPage, 3}}, - {1870, {wxNotebook, advanceSelection, 1}}, - {1871, {wxNotebook, assignImageList, 1}}, - {1872, {wxNotebook, create, 3}}, - {1873, {wxNotebook, deleteAllPages, 0}}, - {1874, {wxNotebook, deletePage, 1}}, - {1875, {wxNotebook, removePage, 1}}, - {1876, {wxNotebook, getCurrentPage, 0}}, - {1877, {wxNotebook, getImageList, 0}}, - {1879, {wxNotebook, getPage, 1}}, - {1880, {wxNotebook, getPageCount, 0}}, - {1881, {wxNotebook, getPageImage, 1}}, - {1882, {wxNotebook, getPageText, 1}}, - {1883, {wxNotebook, getRowCount, 0}}, - {1884, {wxNotebook, getSelection, 0}}, - {1885, {wxNotebook, getThemeBackgroundColour, 0}}, - {1887, {wxNotebook, hitTest, 2}}, - {1889, {wxNotebook, insertPage, 4}}, - {1890, {wxNotebook, setImageList, 1}}, - {1891, {wxNotebook, setPadding, 1}}, - {1892, {wxNotebook, setPageSize, 1}}, - {1893, {wxNotebook, setPageImage, 2}}, - {1894, {wxNotebook, setPageText, 2}}, - {1895, {wxNotebook, setSelection, 1}}, - {1896, {wxNotebook, changeSelection, 1}}, - {1897, {wxChoicebook, new_0, 0}}, - {1898, {wxChoicebook, new_3, 3}}, - {1899, {wxChoicebook, addPage, 3}}, - {1900, {wxChoicebook, advanceSelection, 1}}, - {1901, {wxChoicebook, assignImageList, 1}}, - {1902, {wxChoicebook, create, 3}}, - {1903, {wxChoicebook, deleteAllPages, 0}}, - {1904, {wxChoicebook, deletePage, 1}}, - {1905, {wxChoicebook, removePage, 1}}, - {1906, {wxChoicebook, getCurrentPage, 0}}, - {1907, {wxChoicebook, getImageList, 0}}, - {1909, {wxChoicebook, getPage, 1}}, - {1910, {wxChoicebook, getPageCount, 0}}, - {1911, {wxChoicebook, getPageImage, 1}}, - {1912, {wxChoicebook, getPageText, 1}}, - {1913, {wxChoicebook, getSelection, 0}}, - {1914, {wxChoicebook, hitTest, 2}}, - {1915, {wxChoicebook, insertPage, 4}}, - {1916, {wxChoicebook, setImageList, 1}}, - {1917, {wxChoicebook, setPageSize, 1}}, - {1918, {wxChoicebook, setPageImage, 2}}, - {1919, {wxChoicebook, setPageText, 2}}, - {1920, {wxChoicebook, setSelection, 1}}, - {1921, {wxChoicebook, changeSelection, 1}}, - {1922, {wxChoicebook, 'Destroy', undefined}}, - {1923, {wxToolbook, new_0, 0}}, - {1924, {wxToolbook, new_3, 3}}, - {1925, {wxToolbook, addPage, 3}}, - {1926, {wxToolbook, advanceSelection, 1}}, - {1927, {wxToolbook, assignImageList, 1}}, - {1928, {wxToolbook, create, 3}}, - {1929, {wxToolbook, deleteAllPages, 0}}, - {1930, {wxToolbook, deletePage, 1}}, - {1931, {wxToolbook, removePage, 1}}, - {1932, {wxToolbook, getCurrentPage, 0}}, - {1933, {wxToolbook, getImageList, 0}}, - {1935, {wxToolbook, getPage, 1}}, - {1936, {wxToolbook, getPageCount, 0}}, - {1937, {wxToolbook, getPageImage, 1}}, - {1938, {wxToolbook, getPageText, 1}}, - {1939, {wxToolbook, getSelection, 0}}, - {1941, {wxToolbook, hitTest, 2}}, - {1942, {wxToolbook, insertPage, 4}}, - {1943, {wxToolbook, setImageList, 1}}, - {1944, {wxToolbook, setPageSize, 1}}, - {1945, {wxToolbook, setPageImage, 2}}, - {1946, {wxToolbook, setPageText, 2}}, - {1947, {wxToolbook, setSelection, 1}}, - {1948, {wxToolbook, changeSelection, 1}}, - {1949, {wxToolbook, 'Destroy', undefined}}, - {1950, {wxListbook, new_0, 0}}, - {1951, {wxListbook, new_3, 3}}, - {1952, {wxListbook, addPage, 3}}, - {1953, {wxListbook, advanceSelection, 1}}, - {1954, {wxListbook, assignImageList, 1}}, - {1955, {wxListbook, create, 3}}, - {1956, {wxListbook, deleteAllPages, 0}}, - {1957, {wxListbook, deletePage, 1}}, - {1958, {wxListbook, removePage, 1}}, - {1959, {wxListbook, getCurrentPage, 0}}, - {1960, {wxListbook, getImageList, 0}}, - {1962, {wxListbook, getPage, 1}}, - {1963, {wxListbook, getPageCount, 0}}, - {1964, {wxListbook, getPageImage, 1}}, - {1965, {wxListbook, getPageText, 1}}, - {1966, {wxListbook, getSelection, 0}}, - {1968, {wxListbook, hitTest, 2}}, - {1969, {wxListbook, insertPage, 4}}, - {1970, {wxListbook, setImageList, 1}}, - {1971, {wxListbook, setPageSize, 1}}, - {1972, {wxListbook, setPageImage, 2}}, - {1973, {wxListbook, setPageText, 2}}, - {1974, {wxListbook, setSelection, 1}}, - {1975, {wxListbook, changeSelection, 1}}, - {1976, {wxListbook, 'Destroy', undefined}}, - {1977, {wxTreebook, new_0, 0}}, - {1978, {wxTreebook, new_3, 3}}, - {1979, {wxTreebook, addPage, 3}}, - {1980, {wxTreebook, advanceSelection, 1}}, - {1981, {wxTreebook, assignImageList, 1}}, - {1982, {wxTreebook, create, 3}}, - {1983, {wxTreebook, deleteAllPages, 0}}, - {1984, {wxTreebook, deletePage, 1}}, - {1985, {wxTreebook, removePage, 1}}, - {1986, {wxTreebook, getCurrentPage, 0}}, - {1987, {wxTreebook, getImageList, 0}}, - {1989, {wxTreebook, getPage, 1}}, - {1990, {wxTreebook, getPageCount, 0}}, - {1991, {wxTreebook, getPageImage, 1}}, - {1992, {wxTreebook, getPageText, 1}}, - {1993, {wxTreebook, getSelection, 0}}, - {1994, {wxTreebook, expandNode, 2}}, - {1995, {wxTreebook, isNodeExpanded, 1}}, - {1997, {wxTreebook, hitTest, 2}}, - {1998, {wxTreebook, insertPage, 4}}, - {1999, {wxTreebook, insertSubPage, 4}}, - {2000, {wxTreebook, setImageList, 1}}, - {2001, {wxTreebook, setPageSize, 1}}, - {2002, {wxTreebook, setPageImage, 2}}, - {2003, {wxTreebook, setPageText, 2}}, - {2004, {wxTreebook, setSelection, 1}}, - {2005, {wxTreebook, changeSelection, 1}}, - {2006, {wxTreebook, 'Destroy', undefined}}, - {2009, {wxTreeCtrl, new_2, 2}}, - {2010, {wxTreeCtrl, new_0, 0}}, - {2012, {wxTreeCtrl, destruct, 0}}, - {2013, {wxTreeCtrl, addRoot, 2}}, - {2014, {wxTreeCtrl, appendItem, 3}}, - {2015, {wxTreeCtrl, assignImageList, 1}}, - {2016, {wxTreeCtrl, assignStateImageList, 1}}, - {2017, {wxTreeCtrl, collapse, 1}}, - {2018, {wxTreeCtrl, collapseAndReset, 1}}, - {2019, {wxTreeCtrl, create, 2}}, - {2020, {wxTreeCtrl, delete, 1}}, - {2021, {wxTreeCtrl, deleteAllItems, 0}}, - {2022, {wxTreeCtrl, deleteChildren, 1}}, - {2023, {wxTreeCtrl, editLabel, 1}}, - {2024, {wxTreeCtrl, ensureVisible, 1}}, - {2025, {wxTreeCtrl, expand, 1}}, - {2026, {wxTreeCtrl, getBoundingRect, 3}}, - {2028, {wxTreeCtrl, getChildrenCount, 2}}, - {2029, {wxTreeCtrl, getCount, 0}}, - {2030, {wxTreeCtrl, getEditControl, 0}}, - {2031, {wxTreeCtrl, getFirstChild, 2}}, - {2032, {wxTreeCtrl, getNextChild, 2}}, - {2033, {wxTreeCtrl, getFirstVisibleItem, 0}}, - {2034, {wxTreeCtrl, getImageList, 0}}, - {2035, {wxTreeCtrl, getIndent, 0}}, - {2036, {wxTreeCtrl, getItemBackgroundColour, 1}}, - {2037, {wxTreeCtrl, getItemData, 1}}, - {2038, {wxTreeCtrl, getItemFont, 1}}, - {2039, {wxTreeCtrl, getItemImage_1, 1}}, - {2040, {wxTreeCtrl, getItemImage_2, 2}}, - {2041, {wxTreeCtrl, getItemText, 1}}, - {2042, {wxTreeCtrl, getItemTextColour, 1}}, - {2043, {wxTreeCtrl, getLastChild, 1}}, - {2044, {wxTreeCtrl, getNextSibling, 1}}, - {2045, {wxTreeCtrl, getNextVisible, 1}}, - {2046, {wxTreeCtrl, getItemParent, 1}}, - {2047, {wxTreeCtrl, getPrevSibling, 1}}, - {2048, {wxTreeCtrl, getPrevVisible, 1}}, - {2049, {wxTreeCtrl, getRootItem, 0}}, - {2050, {wxTreeCtrl, getSelection, 0}}, - {2051, {wxTreeCtrl, getSelections, 1}}, - {2052, {wxTreeCtrl, getStateImageList, 0}}, - {2053, {wxTreeCtrl, hitTest, 2}}, - {2055, {wxTreeCtrl, insertItem, 4}}, - {2056, {wxTreeCtrl, isBold, 1}}, - {2057, {wxTreeCtrl, isExpanded, 1}}, - {2058, {wxTreeCtrl, isSelected, 1}}, - {2059, {wxTreeCtrl, isVisible, 1}}, - {2060, {wxTreeCtrl, itemHasChildren, 1}}, - {2061, {wxTreeCtrl, isTreeItemIdOk, 1}}, - {2062, {wxTreeCtrl, prependItem, 3}}, - {2063, {wxTreeCtrl, scrollTo, 1}}, - {2064, {wxTreeCtrl, selectItem_1, 1}}, - {2065, {wxTreeCtrl, selectItem_2, 2}}, - {2066, {wxTreeCtrl, setIndent, 1}}, - {2067, {wxTreeCtrl, setImageList, 1}}, - {2068, {wxTreeCtrl, setItemBackgroundColour, 2}}, - {2069, {wxTreeCtrl, setItemBold, 2}}, - {2070, {wxTreeCtrl, setItemData, 2}}, - {2071, {wxTreeCtrl, setItemDropHighlight, 2}}, - {2072, {wxTreeCtrl, setItemFont, 2}}, - {2073, {wxTreeCtrl, setItemHasChildren, 2}}, - {2074, {wxTreeCtrl, setItemImage_2, 2}}, - {2075, {wxTreeCtrl, setItemImage_3, 3}}, - {2076, {wxTreeCtrl, setItemText, 2}}, - {2077, {wxTreeCtrl, setItemTextColour, 2}}, - {2078, {wxTreeCtrl, setStateImageList, 1}}, - {2079, {wxTreeCtrl, setWindowStyle, 1}}, - {2080, {wxTreeCtrl, sortChildren, 1}}, - {2081, {wxTreeCtrl, toggle, 1}}, - {2082, {wxTreeCtrl, toggleItemSelection, 1}}, - {2083, {wxTreeCtrl, unselect, 0}}, - {2084, {wxTreeCtrl, unselectAll, 0}}, - {2085, {wxTreeCtrl, unselectItem, 1}}, - {2086, {wxScrollBar, new_0, 0}}, - {2087, {wxScrollBar, new_3, 3}}, - {2088, {wxScrollBar, destruct, 0}}, - {2089, {wxScrollBar, create, 3}}, - {2090, {wxScrollBar, getRange, 0}}, - {2091, {wxScrollBar, getPageSize, 0}}, - {2092, {wxScrollBar, getThumbPosition, 0}}, - {2093, {wxScrollBar, getThumbSize, 0}}, - {2094, {wxScrollBar, setThumbPosition, 1}}, - {2095, {wxScrollBar, setScrollbar, 5}}, - {2097, {wxSpinButton, new_2, 2}}, - {2098, {wxSpinButton, new_0, 0}}, - {2099, {wxSpinButton, create, 2}}, - {2100, {wxSpinButton, getMax, 0}}, - {2101, {wxSpinButton, getMin, 0}}, - {2102, {wxSpinButton, getValue, 0}}, - {2103, {wxSpinButton, setRange, 2}}, - {2104, {wxSpinButton, setValue, 1}}, - {2105, {wxSpinButton, 'Destroy', undefined}}, - {2106, {wxSpinCtrl, new_0, 0}}, - {2107, {wxSpinCtrl, new_2, 2}}, - {2109, {wxSpinCtrl, create, 2}}, - {2112, {wxSpinCtrl, setValue_1_1, 1}}, - {2113, {wxSpinCtrl, setValue_1_0, 1}}, - {2115, {wxSpinCtrl, getValue, 0}}, - {2117, {wxSpinCtrl, setRange, 2}}, - {2118, {wxSpinCtrl, setSelection, 2}}, - {2120, {wxSpinCtrl, getMin, 0}}, - {2122, {wxSpinCtrl, getMax, 0}}, - {2123, {wxSpinCtrl, 'Destroy', undefined}}, - {2124, {wxStaticText, new_0, 0}}, - {2125, {wxStaticText, new_4, 4}}, - {2126, {wxStaticText, create, 4}}, - {2127, {wxStaticText, getLabel, 0}}, - {2128, {wxStaticText, setLabel, 1}}, - {2129, {wxStaticText, wrap, 1}}, - {2130, {wxStaticText, 'Destroy', undefined}}, - {2131, {wxStaticBitmap, new_0, 0}}, - {2132, {wxStaticBitmap, new_4, 4}}, - {2133, {wxStaticBitmap, create, 4}}, - {2134, {wxStaticBitmap, getBitmap, 0}}, - {2135, {wxStaticBitmap, setBitmap, 1}}, - {2136, {wxStaticBitmap, 'Destroy', undefined}}, - {2137, {wxRadioBox, new, 7}}, - {2139, {wxRadioBox, destruct, 0}}, - {2140, {wxRadioBox, create, 7}}, - {2141, {wxRadioBox, enable_2, 2}}, - {2142, {wxRadioBox, enable_1, 1}}, - {2143, {wxRadioBox, getSelection, 0}}, - {2144, {wxRadioBox, getString, 1}}, - {2145, {wxRadioBox, setSelection, 1}}, - {2146, {wxRadioBox, show_2, 2}}, - {2147, {wxRadioBox, show_1, 1}}, - {2148, {wxRadioBox, getColumnCount, 0}}, - {2149, {wxRadioBox, getItemHelpText, 1}}, - {2150, {wxRadioBox, getItemToolTip, 1}}, - {2152, {wxRadioBox, getItemFromPoint, 1}}, - {2153, {wxRadioBox, getRowCount, 0}}, - {2154, {wxRadioBox, isItemEnabled, 1}}, - {2155, {wxRadioBox, isItemShown, 1}}, - {2156, {wxRadioBox, setItemHelpText, 2}}, - {2157, {wxRadioBox, setItemToolTip, 2}}, - {2158, {wxRadioButton, new_0, 0}}, - {2159, {wxRadioButton, new_4, 4}}, - {2160, {wxRadioButton, create, 4}}, - {2161, {wxRadioButton, getValue, 0}}, - {2162, {wxRadioButton, setValue, 1}}, - {2163, {wxRadioButton, 'Destroy', undefined}}, - {2165, {wxSlider, new_6, 6}}, - {2166, {wxSlider, new_0, 0}}, - {2167, {wxSlider, create, 6}}, - {2168, {wxSlider, getLineSize, 0}}, - {2169, {wxSlider, getMax, 0}}, - {2170, {wxSlider, getMin, 0}}, - {2171, {wxSlider, getPageSize, 0}}, - {2172, {wxSlider, getThumbLength, 0}}, - {2173, {wxSlider, getValue, 0}}, - {2174, {wxSlider, setLineSize, 1}}, - {2175, {wxSlider, setPageSize, 1}}, - {2176, {wxSlider, setRange, 2}}, - {2177, {wxSlider, setThumbLength, 1}}, - {2178, {wxSlider, setValue, 1}}, - {2179, {wxSlider, 'Destroy', undefined}}, - {2181, {wxDialog, new_4, 4}}, - {2182, {wxDialog, new_0, 0}}, - {2184, {wxDialog, destruct, 0}}, - {2185, {wxDialog, create, 4}}, - {2186, {wxDialog, createButtonSizer, 1}}, - {2187, {wxDialog, createStdDialogButtonSizer, 1}}, - {2188, {wxDialog, endModal, 1}}, - {2189, {wxDialog, getAffirmativeId, 0}}, - {2190, {wxDialog, getReturnCode, 0}}, - {2191, {wxDialog, isModal, 0}}, - {2192, {wxDialog, setAffirmativeId, 1}}, - {2193, {wxDialog, setReturnCode, 1}}, - {2194, {wxDialog, show, 1}}, - {2195, {wxDialog, showModal, 0}}, - {2196, {wxColourDialog, new_0, 0}}, - {2197, {wxColourDialog, new_2, 2}}, - {2198, {wxColourDialog, destruct, 0}}, - {2199, {wxColourDialog, create, 2}}, - {2200, {wxColourDialog, getColourData, 0}}, - {2201, {wxColourData, new_0, 0}}, - {2202, {wxColourData, new_1, 1}}, - {2203, {wxColourData, destruct, 0}}, - {2204, {wxColourData, getChooseFull, 0}}, - {2205, {wxColourData, getColour, 0}}, - {2207, {wxColourData, getCustomColour, 1}}, - {2208, {wxColourData, setChooseFull, 1}}, - {2209, {wxColourData, setColour, 1}}, - {2210, {wxColourData, setCustomColour, 2}}, - {2211, {wxPalette, new_0, 0}}, - {2212, {wxPalette, new_4, 4}}, - {2214, {wxPalette, destruct, 0}}, - {2215, {wxPalette, create, 4}}, - {2216, {wxPalette, getColoursCount, 0}}, - {2217, {wxPalette, getPixel, 3}}, - {2218, {wxPalette, getRGB, 4}}, - {2219, {wxPalette, isOk, 0}}, - {2223, {wxDirDialog, new, 2}}, - {2224, {wxDirDialog, destruct, 0}}, - {2225, {wxDirDialog, getPath, 0}}, - {2226, {wxDirDialog, getMessage, 0}}, - {2227, {wxDirDialog, setMessage, 1}}, - {2228, {wxDirDialog, setPath, 1}}, - {2232, {wxFileDialog, new, 2}}, - {2233, {wxFileDialog, destruct, 0}}, - {2234, {wxFileDialog, getDirectory, 0}}, - {2235, {wxFileDialog, getFilename, 0}}, - {2236, {wxFileDialog, getFilenames, 1}}, - {2237, {wxFileDialog, getFilterIndex, 0}}, - {2238, {wxFileDialog, getMessage, 0}}, - {2239, {wxFileDialog, getPath, 0}}, - {2240, {wxFileDialog, getPaths, 1}}, - {2241, {wxFileDialog, getWildcard, 0}}, - {2242, {wxFileDialog, setDirectory, 1}}, - {2243, {wxFileDialog, setFilename, 1}}, - {2244, {wxFileDialog, setFilterIndex, 1}}, - {2245, {wxFileDialog, setMessage, 1}}, - {2246, {wxFileDialog, setPath, 1}}, - {2247, {wxFileDialog, setWildcard, 1}}, - {2248, {wxPickerBase, setInternalMargin, 1}}, - {2249, {wxPickerBase, getInternalMargin, 0}}, - {2250, {wxPickerBase, setTextCtrlProportion, 1}}, - {2251, {wxPickerBase, setPickerCtrlProportion, 1}}, - {2252, {wxPickerBase, getTextCtrlProportion, 0}}, - {2253, {wxPickerBase, getPickerCtrlProportion, 0}}, - {2254, {wxPickerBase, hasTextCtrl, 0}}, - {2255, {wxPickerBase, getTextCtrl, 0}}, - {2256, {wxPickerBase, isTextCtrlGrowable, 0}}, - {2257, {wxPickerBase, setPickerCtrlGrowable, 1}}, - {2258, {wxPickerBase, setTextCtrlGrowable, 1}}, - {2259, {wxPickerBase, isPickerCtrlGrowable, 0}}, - {2260, {wxFilePickerCtrl, new_0, 0}}, - {2261, {wxFilePickerCtrl, new_3, 3}}, - {2262, {wxFilePickerCtrl, create, 3}}, - {2263, {wxFilePickerCtrl, getPath, 0}}, - {2264, {wxFilePickerCtrl, setPath, 1}}, - {2265, {wxFilePickerCtrl, 'Destroy', undefined}}, - {2266, {wxDirPickerCtrl, new_0, 0}}, - {2267, {wxDirPickerCtrl, new_3, 3}}, - {2268, {wxDirPickerCtrl, create, 3}}, - {2269, {wxDirPickerCtrl, getPath, 0}}, - {2270, {wxDirPickerCtrl, setPath, 1}}, - {2271, {wxDirPickerCtrl, 'Destroy', undefined}}, - {2272, {wxColourPickerCtrl, new_0, 0}}, - {2273, {wxColourPickerCtrl, new_3, 3}}, - {2274, {wxColourPickerCtrl, create, 3}}, - {2275, {wxColourPickerCtrl, getColour, 0}}, - {2276, {wxColourPickerCtrl, setColour_1_1, 1}}, - {2277, {wxColourPickerCtrl, setColour_1_0, 1}}, - {2278, {wxColourPickerCtrl, 'Destroy', undefined}}, - {2279, {wxDatePickerCtrl, new_0, 0}}, - {2280, {wxDatePickerCtrl, new_3, 3}}, - {2281, {wxDatePickerCtrl, getRange, 2}}, - {2282, {wxDatePickerCtrl, getValue, 0}}, - {2283, {wxDatePickerCtrl, setRange, 2}}, - {2284, {wxDatePickerCtrl, setValue, 1}}, - {2285, {wxDatePickerCtrl, 'Destroy', undefined}}, - {2286, {wxFontPickerCtrl, new_0, 0}}, - {2287, {wxFontPickerCtrl, new_3, 3}}, - {2288, {wxFontPickerCtrl, create, 3}}, - {2289, {wxFontPickerCtrl, getSelectedFont, 0}}, - {2290, {wxFontPickerCtrl, setSelectedFont, 1}}, - {2291, {wxFontPickerCtrl, getMaxPointSize, 0}}, - {2292, {wxFontPickerCtrl, setMaxPointSize, 1}}, - {2293, {wxFontPickerCtrl, 'Destroy', undefined}}, - {2296, {wxFindReplaceDialog, new_0, 0}}, - {2297, {wxFindReplaceDialog, new_4, 4}}, - {2298, {wxFindReplaceDialog, destruct, 0}}, - {2299, {wxFindReplaceDialog, create, 4}}, - {2300, {wxFindReplaceDialog, getData, 0}}, - {2301, {wxFindReplaceData, new_0, 0}}, - {2302, {wxFindReplaceData, new_1, 1}}, - {2303, {wxFindReplaceData, getFindString, 0}}, - {2304, {wxFindReplaceData, getReplaceString, 0}}, - {2305, {wxFindReplaceData, getFlags, 0}}, - {2306, {wxFindReplaceData, setFlags, 1}}, - {2307, {wxFindReplaceData, setFindString, 1}}, - {2308, {wxFindReplaceData, setReplaceString, 1}}, - {2309, {wxFindReplaceData, 'Destroy', undefined}}, - {2310, {wxMultiChoiceDialog, new_0, 0}}, - {2312, {wxMultiChoiceDialog, new_5, 5}}, - {2313, {wxMultiChoiceDialog, getSelections, 0}}, - {2314, {wxMultiChoiceDialog, setSelections, 1}}, - {2315, {wxMultiChoiceDialog, 'Destroy', undefined}}, - {2316, {wxSingleChoiceDialog, new_0, 0}}, - {2318, {wxSingleChoiceDialog, new_5, 5}}, - {2319, {wxSingleChoiceDialog, getSelection, 0}}, - {2320, {wxSingleChoiceDialog, getStringSelection, 0}}, - {2321, {wxSingleChoiceDialog, setSelection, 1}}, - {2322, {wxSingleChoiceDialog, 'Destroy', undefined}}, - {2323, {wxTextEntryDialog, new, 3}}, - {2324, {wxTextEntryDialog, getValue, 0}}, - {2325, {wxTextEntryDialog, setValue, 1}}, - {2326, {wxTextEntryDialog, 'Destroy', undefined}}, - {2327, {wxPasswordEntryDialog, new, 3}}, - {2328, {wxPasswordEntryDialog, 'Destroy', undefined}}, - {2329, {wxFontData, new_0, 0}}, - {2330, {wxFontData, new_1, 1}}, - {2331, {wxFontData, destruct, 0}}, - {2332, {wxFontData, enableEffects, 1}}, - {2333, {wxFontData, getAllowSymbols, 0}}, - {2334, {wxFontData, getColour, 0}}, - {2335, {wxFontData, getChosenFont, 0}}, - {2336, {wxFontData, getEnableEffects, 0}}, - {2337, {wxFontData, getInitialFont, 0}}, - {2338, {wxFontData, getShowHelp, 0}}, - {2339, {wxFontData, setAllowSymbols, 1}}, - {2340, {wxFontData, setChosenFont, 1}}, - {2341, {wxFontData, setColour, 1}}, - {2342, {wxFontData, setInitialFont, 1}}, - {2343, {wxFontData, setRange, 2}}, - {2344, {wxFontData, setShowHelp, 1}}, - {2348, {wxFontDialog, new_0, 0}}, - {2350, {wxFontDialog, new_2, 2}}, - {2352, {wxFontDialog, create, 2}}, - {2353, {wxFontDialog, getFontData, 0}}, - {2355, {wxFontDialog, 'Destroy', undefined}}, - {2356, {wxProgressDialog, new, 3}}, - {2357, {wxProgressDialog, destruct, 0}}, - {2358, {wxProgressDialog, resume, 0}}, - {2359, {wxProgressDialog, update_2, 2}}, - {2360, {wxProgressDialog, update_0, 0}}, - {2361, {wxMessageDialog, new, 3}}, - {2362, {wxMessageDialog, destruct, 0}}, - {2363, {wxPageSetupDialog, new, 2}}, - {2364, {wxPageSetupDialog, destruct, 0}}, - {2365, {wxPageSetupDialog, getPageSetupData, 0}}, - {2366, {wxPageSetupDialog, showModal, 0}}, - {2367, {wxPageSetupDialogData, new_0, 0}}, - {2368, {wxPageSetupDialogData, new_1_0, 1}}, - {2369, {wxPageSetupDialogData, new_1_1, 1}}, - {2370, {wxPageSetupDialogData, destruct, 0}}, - {2371, {wxPageSetupDialogData, enableHelp, 1}}, - {2372, {wxPageSetupDialogData, enableMargins, 1}}, - {2373, {wxPageSetupDialogData, enableOrientation, 1}}, - {2374, {wxPageSetupDialogData, enablePaper, 1}}, - {2375, {wxPageSetupDialogData, enablePrinter, 1}}, - {2376, {wxPageSetupDialogData, getDefaultMinMargins, 0}}, - {2377, {wxPageSetupDialogData, getEnableMargins, 0}}, - {2378, {wxPageSetupDialogData, getEnableOrientation, 0}}, - {2379, {wxPageSetupDialogData, getEnablePaper, 0}}, - {2380, {wxPageSetupDialogData, getEnablePrinter, 0}}, - {2381, {wxPageSetupDialogData, getEnableHelp, 0}}, - {2382, {wxPageSetupDialogData, getDefaultInfo, 0}}, - {2383, {wxPageSetupDialogData, getMarginTopLeft, 0}}, - {2384, {wxPageSetupDialogData, getMarginBottomRight, 0}}, - {2385, {wxPageSetupDialogData, getMinMarginTopLeft, 0}}, - {2386, {wxPageSetupDialogData, getMinMarginBottomRight, 0}}, - {2387, {wxPageSetupDialogData, getPaperId, 0}}, - {2388, {wxPageSetupDialogData, getPaperSize, 0}}, - {2390, {wxPageSetupDialogData, getPrintData, 0}}, - {2391, {wxPageSetupDialogData, isOk, 0}}, - {2392, {wxPageSetupDialogData, setDefaultInfo, 1}}, - {2393, {wxPageSetupDialogData, setDefaultMinMargins, 1}}, - {2394, {wxPageSetupDialogData, setMarginTopLeft, 1}}, - {2395, {wxPageSetupDialogData, setMarginBottomRight, 1}}, - {2396, {wxPageSetupDialogData, setMinMarginTopLeft, 1}}, - {2397, {wxPageSetupDialogData, setMinMarginBottomRight, 1}}, - {2398, {wxPageSetupDialogData, setPaperId, 1}}, - {2399, {wxPageSetupDialogData, setPaperSize_1_1, 1}}, - {2400, {wxPageSetupDialogData, setPaperSize_1_0, 1}}, - {2401, {wxPageSetupDialogData, setPrintData, 1}}, - {2402, {wxPrintDialog, new_2_0, 2}}, - {2403, {wxPrintDialog, new_2_1, 2}}, - {2404, {wxPrintDialog, destruct, 0}}, - {2405, {wxPrintDialog, getPrintDialogData, 0}}, - {2406, {wxPrintDialog, getPrintDC, 0}}, - {2407, {wxPrintDialogData, new_0, 0}}, - {2408, {wxPrintDialogData, new_1_1, 1}}, - {2409, {wxPrintDialogData, new_1_0, 1}}, - {2410, {wxPrintDialogData, destruct, 0}}, - {2411, {wxPrintDialogData, enableHelp, 1}}, - {2412, {wxPrintDialogData, enablePageNumbers, 1}}, - {2413, {wxPrintDialogData, enablePrintToFile, 1}}, - {2414, {wxPrintDialogData, enableSelection, 1}}, - {2415, {wxPrintDialogData, getAllPages, 0}}, - {2416, {wxPrintDialogData, getCollate, 0}}, - {2417, {wxPrintDialogData, getFromPage, 0}}, - {2418, {wxPrintDialogData, getMaxPage, 0}}, - {2419, {wxPrintDialogData, getMinPage, 0}}, - {2420, {wxPrintDialogData, getNoCopies, 0}}, - {2421, {wxPrintDialogData, getPrintData, 0}}, - {2422, {wxPrintDialogData, getPrintToFile, 0}}, - {2423, {wxPrintDialogData, getSelection, 0}}, - {2424, {wxPrintDialogData, getToPage, 0}}, - {2425, {wxPrintDialogData, isOk, 0}}, - {2426, {wxPrintDialogData, setCollate, 1}}, - {2427, {wxPrintDialogData, setFromPage, 1}}, - {2428, {wxPrintDialogData, setMaxPage, 1}}, - {2429, {wxPrintDialogData, setMinPage, 1}}, - {2430, {wxPrintDialogData, setNoCopies, 1}}, - {2431, {wxPrintDialogData, setPrintData, 1}}, - {2432, {wxPrintDialogData, setPrintToFile, 1}}, - {2433, {wxPrintDialogData, setSelection, 1}}, - {2434, {wxPrintDialogData, setToPage, 1}}, - {2435, {wxPrintData, new_0, 0}}, - {2436, {wxPrintData, new_1, 1}}, - {2437, {wxPrintData, destruct, 0}}, - {2438, {wxPrintData, getCollate, 0}}, - {2439, {wxPrintData, getBin, 0}}, - {2440, {wxPrintData, getColour, 0}}, - {2441, {wxPrintData, getDuplex, 0}}, - {2442, {wxPrintData, getNoCopies, 0}}, - {2443, {wxPrintData, getOrientation, 0}}, - {2444, {wxPrintData, getPaperId, 0}}, - {2445, {wxPrintData, getPrinterName, 0}}, - {2446, {wxPrintData, getQuality, 0}}, - {2447, {wxPrintData, isOk, 0}}, - {2448, {wxPrintData, setBin, 1}}, - {2449, {wxPrintData, setCollate, 1}}, - {2450, {wxPrintData, setColour, 1}}, - {2451, {wxPrintData, setDuplex, 1}}, - {2452, {wxPrintData, setNoCopies, 1}}, - {2453, {wxPrintData, setOrientation, 1}}, - {2454, {wxPrintData, setPaperId, 1}}, - {2455, {wxPrintData, setPrinterName, 1}}, - {2456, {wxPrintData, setQuality, 1}}, - {2459, {wxPrintPreview, new_2, 2}}, - {2460, {wxPrintPreview, new_3, 3}}, - {2462, {wxPrintPreview, destruct, 0}}, - {2463, {wxPrintPreview, getCanvas, 0}}, - {2464, {wxPrintPreview, getCurrentPage, 0}}, - {2465, {wxPrintPreview, getFrame, 0}}, - {2466, {wxPrintPreview, getMaxPage, 0}}, - {2467, {wxPrintPreview, getMinPage, 0}}, - {2468, {wxPrintPreview, getPrintout, 0}}, - {2469, {wxPrintPreview, getPrintoutForPrinting, 0}}, - {2470, {wxPrintPreview, isOk, 0}}, - {2471, {wxPrintPreview, paintPage, 2}}, - {2472, {wxPrintPreview, print, 1}}, - {2473, {wxPrintPreview, renderPage, 1}}, - {2474, {wxPrintPreview, setCanvas, 1}}, - {2475, {wxPrintPreview, setCurrentPage, 1}}, - {2476, {wxPrintPreview, setFrame, 1}}, - {2477, {wxPrintPreview, setPrintout, 1}}, - {2478, {wxPrintPreview, setZoom, 1}}, - {2479, {wxPreviewFrame, new, 3}}, - {2480, {wxPreviewFrame, destruct, 0}}, - {2481, {wxPreviewFrame, createControlBar, 0}}, - {2482, {wxPreviewFrame, createCanvas, 0}}, - {2483, {wxPreviewFrame, initialize, 0}}, - {2484, {wxPreviewFrame, onCloseWindow, 1}}, - {2485, {wxPreviewControlBar, new, 4}}, - {2486, {wxPreviewControlBar, destruct, 0}}, - {2487, {wxPreviewControlBar, createButtons, 0}}, - {2488, {wxPreviewControlBar, getPrintPreview, 0}}, - {2489, {wxPreviewControlBar, getZoomControl, 0}}, - {2490, {wxPreviewControlBar, setZoomControl, 1}}, - {2492, {wxPrinter, new, 1}}, - {2493, {wxPrinter, createAbortWindow, 2}}, - {2494, {wxPrinter, getAbort, 0}}, - {2495, {wxPrinter, getLastError, 0}}, - {2496, {wxPrinter, getPrintDialogData, 0}}, - {2497, {wxPrinter, print, 3}}, - {2498, {wxPrinter, printDialog, 1}}, - {2499, {wxPrinter, reportError, 3}}, - {2500, {wxPrinter, setup, 1}}, - {2501, {wxPrinter, 'Destroy', undefined}}, - {2502, {wxXmlResource, new_1, 1}}, - {2503, {wxXmlResource, new_2, 2}}, - {2504, {wxXmlResource, destruct, 0}}, - {2505, {wxXmlResource, attachUnknownControl, 3}}, - {2506, {wxXmlResource, clearHandlers, 0}}, - {2507, {wxXmlResource, compareVersion, 4}}, - {2508, {wxXmlResource, get, 0}}, - {2509, {wxXmlResource, getFlags, 0}}, - {2510, {wxXmlResource, getVersion, 0}}, - {2511, {wxXmlResource, getXRCID, 2}}, - {2512, {wxXmlResource, initAllHandlers, 0}}, - {2513, {wxXmlResource, load, 1}}, - {2514, {wxXmlResource, loadBitmap, 1}}, - {2515, {wxXmlResource, loadDialog_2, 2}}, - {2516, {wxXmlResource, loadDialog_3, 3}}, - {2517, {wxXmlResource, loadFrame_2, 2}}, - {2518, {wxXmlResource, loadFrame_3, 3}}, - {2519, {wxXmlResource, loadIcon, 1}}, - {2520, {wxXmlResource, loadMenu, 1}}, - {2521, {wxXmlResource, loadMenuBar_2, 2}}, - {2522, {wxXmlResource, loadMenuBar_1, 1}}, - {2523, {wxXmlResource, loadPanel_2, 2}}, - {2524, {wxXmlResource, loadPanel_3, 3}}, - {2525, {wxXmlResource, loadToolBar, 2}}, - {2526, {wxXmlResource, set, 1}}, - {2527, {wxXmlResource, setFlags, 1}}, - {2528, {wxXmlResource, unload, 1}}, - {2529, {wxXmlResource, xrcctrl, 3}}, - {2530, {wxHtmlEasyPrinting, new, 1}}, - {2531, {wxHtmlEasyPrinting, destruct, 0}}, - {2532, {wxHtmlEasyPrinting, getPrintData, 0}}, - {2533, {wxHtmlEasyPrinting, getPageSetupData, 0}}, - {2534, {wxHtmlEasyPrinting, previewFile, 1}}, - {2535, {wxHtmlEasyPrinting, previewText, 2}}, - {2536, {wxHtmlEasyPrinting, printFile, 1}}, - {2537, {wxHtmlEasyPrinting, printText, 2}}, - {2538, {wxHtmlEasyPrinting, pageSetup, 0}}, - {2539, {wxHtmlEasyPrinting, setFonts, 3}}, - {2540, {wxHtmlEasyPrinting, setHeader, 2}}, - {2541, {wxHtmlEasyPrinting, setFooter, 2}}, - {2543, {wxGLCanvas, new_2, 2}}, - {2544, {wxGLCanvas, new_3_1, 3}}, - {2545, {wxGLCanvas, new_3_0, 3}}, - {2546, {wxGLCanvas, getContext, 0}}, - {2548, {wxGLCanvas, setCurrent, 0}}, - {2549, {wxGLCanvas, swapBuffers, 0}}, - {2550, {wxGLCanvas, 'Destroy', undefined}}, - {2551, {wxAuiManager, new, 1}}, - {2552, {wxAuiManager, destruct, 0}}, - {2553, {wxAuiManager, addPane_2_1, 2}}, - {2554, {wxAuiManager, addPane_3, 3}}, - {2555, {wxAuiManager, addPane_2_0, 2}}, - {2556, {wxAuiManager, detachPane, 1}}, - {2557, {wxAuiManager, getAllPanes, 0}}, - {2558, {wxAuiManager, getArtProvider, 0}}, - {2559, {wxAuiManager, getDockSizeConstraint, 2}}, - {2560, {wxAuiManager, getFlags, 0}}, - {2561, {wxAuiManager, getManagedWindow, 0}}, - {2562, {wxAuiManager, getManager, 1}}, - {2563, {wxAuiManager, getPane_1_1, 1}}, - {2564, {wxAuiManager, getPane_1_0, 1}}, - {2565, {wxAuiManager, hideHint, 0}}, - {2566, {wxAuiManager, insertPane, 3}}, - {2567, {wxAuiManager, loadPaneInfo, 2}}, - {2568, {wxAuiManager, loadPerspective, 2}}, - {2569, {wxAuiManager, savePaneInfo, 1}}, - {2570, {wxAuiManager, savePerspective, 0}}, - {2571, {wxAuiManager, setArtProvider, 1}}, - {2572, {wxAuiManager, setDockSizeConstraint, 2}}, - {2573, {wxAuiManager, setFlags, 1}}, - {2574, {wxAuiManager, setManagedWindow, 1}}, - {2575, {wxAuiManager, showHint, 1}}, - {2576, {wxAuiManager, unInit, 0}}, - {2577, {wxAuiManager, update, 0}}, - {2578, {wxAuiPaneInfo, new_0, 0}}, - {2579, {wxAuiPaneInfo, new_1, 1}}, - {2580, {wxAuiPaneInfo, destruct, 0}}, - {2581, {wxAuiPaneInfo, bestSize_1, 1}}, - {2582, {wxAuiPaneInfo, bestSize_2, 2}}, - {2583, {wxAuiPaneInfo, bottom, 0}}, - {2584, {wxAuiPaneInfo, bottomDockable, 1}}, - {2585, {wxAuiPaneInfo, caption, 1}}, - {2586, {wxAuiPaneInfo, captionVisible, 1}}, - {2587, {wxAuiPaneInfo, centre, 0}}, - {2588, {wxAuiPaneInfo, centrePane, 0}}, - {2589, {wxAuiPaneInfo, closeButton, 1}}, - {2590, {wxAuiPaneInfo, defaultPane, 0}}, - {2591, {wxAuiPaneInfo, destroyOnClose, 1}}, - {2592, {wxAuiPaneInfo, direction, 1}}, - {2593, {wxAuiPaneInfo, dock, 0}}, - {2594, {wxAuiPaneInfo, dockable, 1}}, - {2595, {wxAuiPaneInfo, fixed, 0}}, - {2596, {wxAuiPaneInfo, float, 0}}, - {2597, {wxAuiPaneInfo, floatable, 1}}, - {2598, {wxAuiPaneInfo, floatingPosition_1, 1}}, - {2599, {wxAuiPaneInfo, floatingPosition_2, 2}}, - {2600, {wxAuiPaneInfo, floatingSize_1, 1}}, - {2601, {wxAuiPaneInfo, floatingSize_2, 2}}, - {2602, {wxAuiPaneInfo, gripper, 1}}, - {2603, {wxAuiPaneInfo, gripperTop, 1}}, - {2604, {wxAuiPaneInfo, hasBorder, 0}}, - {2605, {wxAuiPaneInfo, hasCaption, 0}}, - {2606, {wxAuiPaneInfo, hasCloseButton, 0}}, - {2607, {wxAuiPaneInfo, hasFlag, 1}}, - {2608, {wxAuiPaneInfo, hasGripper, 0}}, - {2609, {wxAuiPaneInfo, hasGripperTop, 0}}, - {2610, {wxAuiPaneInfo, hasMaximizeButton, 0}}, - {2611, {wxAuiPaneInfo, hasMinimizeButton, 0}}, - {2612, {wxAuiPaneInfo, hasPinButton, 0}}, - {2613, {wxAuiPaneInfo, hide, 0}}, - {2614, {wxAuiPaneInfo, isBottomDockable, 0}}, - {2615, {wxAuiPaneInfo, isDocked, 0}}, - {2616, {wxAuiPaneInfo, isFixed, 0}}, - {2617, {wxAuiPaneInfo, isFloatable, 0}}, - {2618, {wxAuiPaneInfo, isFloating, 0}}, - {2619, {wxAuiPaneInfo, isLeftDockable, 0}}, - {2620, {wxAuiPaneInfo, isMovable, 0}}, - {2621, {wxAuiPaneInfo, isOk, 0}}, - {2622, {wxAuiPaneInfo, isResizable, 0}}, - {2623, {wxAuiPaneInfo, isRightDockable, 0}}, - {2624, {wxAuiPaneInfo, isShown, 0}}, - {2625, {wxAuiPaneInfo, isToolbar, 0}}, - {2626, {wxAuiPaneInfo, isTopDockable, 0}}, - {2627, {wxAuiPaneInfo, layer, 1}}, - {2628, {wxAuiPaneInfo, left, 0}}, - {2629, {wxAuiPaneInfo, leftDockable, 1}}, - {2630, {wxAuiPaneInfo, maxSize_1, 1}}, - {2631, {wxAuiPaneInfo, maxSize_2, 2}}, - {2632, {wxAuiPaneInfo, maximizeButton, 1}}, - {2633, {wxAuiPaneInfo, minSize_1, 1}}, - {2634, {wxAuiPaneInfo, minSize_2, 2}}, - {2635, {wxAuiPaneInfo, minimizeButton, 1}}, - {2636, {wxAuiPaneInfo, movable, 1}}, - {2637, {wxAuiPaneInfo, name, 1}}, - {2638, {wxAuiPaneInfo, paneBorder, 1}}, - {2639, {wxAuiPaneInfo, pinButton, 1}}, - {2640, {wxAuiPaneInfo, position, 1}}, - {2641, {wxAuiPaneInfo, resizable, 1}}, - {2642, {wxAuiPaneInfo, right, 0}}, - {2643, {wxAuiPaneInfo, rightDockable, 1}}, - {2644, {wxAuiPaneInfo, row, 1}}, - {2645, {wxAuiPaneInfo, safeSet, 1}}, - {2646, {wxAuiPaneInfo, setFlag, 2}}, - {2647, {wxAuiPaneInfo, show, 1}}, - {2648, {wxAuiPaneInfo, toolbarPane, 0}}, - {2649, {wxAuiPaneInfo, top, 0}}, - {2650, {wxAuiPaneInfo, topDockable, 1}}, - {2651, {wxAuiPaneInfo, window, 1}}, - {2652, {wxAuiNotebook, new_0, 0}}, - {2653, {wxAuiNotebook, new_2, 2}}, - {2654, {wxAuiNotebook, addPage, 3}}, - {2655, {wxAuiNotebook, create, 2}}, - {2656, {wxAuiNotebook, deletePage, 1}}, - {2657, {wxAuiNotebook, getArtProvider, 0}}, - {2658, {wxAuiNotebook, getPage, 1}}, - {2659, {wxAuiNotebook, getPageBitmap, 1}}, - {2660, {wxAuiNotebook, getPageCount, 0}}, - {2661, {wxAuiNotebook, getPageIndex, 1}}, - {2662, {wxAuiNotebook, getPageText, 1}}, - {2663, {wxAuiNotebook, getSelection, 0}}, - {2664, {wxAuiNotebook, insertPage, 4}}, - {2665, {wxAuiNotebook, removePage, 1}}, - {2666, {wxAuiNotebook, setArtProvider, 1}}, - {2667, {wxAuiNotebook, setFont, 1}}, - {2668, {wxAuiNotebook, setPageBitmap, 2}}, - {2669, {wxAuiNotebook, setPageText, 2}}, - {2670, {wxAuiNotebook, setSelection, 1}}, - {2671, {wxAuiNotebook, setTabCtrlHeight, 1}}, - {2672, {wxAuiNotebook, setUniformBitmapSize, 1}}, - {2673, {wxAuiNotebook, 'Destroy', undefined}}, - {2674, {wxMDIParentFrame, new_0, 0}}, - {2675, {wxMDIParentFrame, new_4, 4}}, - {2676, {wxMDIParentFrame, destruct, 0}}, - {2677, {wxMDIParentFrame, activateNext, 0}}, - {2678, {wxMDIParentFrame, activatePrevious, 0}}, - {2679, {wxMDIParentFrame, arrangeIcons, 0}}, - {2680, {wxMDIParentFrame, cascade, 0}}, - {2681, {wxMDIParentFrame, create, 4}}, - {2682, {wxMDIParentFrame, getActiveChild, 0}}, - {2683, {wxMDIParentFrame, getClientWindow, 0}}, - {2684, {wxMDIParentFrame, tile, 1}}, - {2685, {wxMDIChildFrame, new_0, 0}}, - {2686, {wxMDIChildFrame, new_4, 4}}, - {2687, {wxMDIChildFrame, destruct, 0}}, - {2688, {wxMDIChildFrame, activate, 0}}, - {2689, {wxMDIChildFrame, create, 4}}, - {2690, {wxMDIChildFrame, maximize, 1}}, - {2691, {wxMDIChildFrame, restore, 0}}, - {2692, {wxMDIClientWindow, new_0, 0}}, - {2693, {wxMDIClientWindow, new_2, 2}}, - {2694, {wxMDIClientWindow, destruct, 0}}, - {2695, {wxMDIClientWindow, createClient, 2}}, - {2696, {wxLayoutAlgorithm, new, 0}}, - {2697, {wxLayoutAlgorithm, layoutFrame, 2}}, - {2698, {wxLayoutAlgorithm, layoutMDIFrame, 2}}, - {2699, {wxLayoutAlgorithm, layoutWindow, 2}}, - {2700, {wxLayoutAlgorithm, 'Destroy', undefined}}, - {2701, {wxEvent, getId, 0}}, - {2702, {wxEvent, getSkipped, 0}}, - {2703, {wxEvent, getTimestamp, 0}}, - {2704, {wxEvent, isCommandEvent, 0}}, - {2705, {wxEvent, resumePropagation, 1}}, - {2706, {wxEvent, shouldPropagate, 0}}, - {2707, {wxEvent, skip, 1}}, - {2708, {wxEvent, stopPropagation, 0}}, - {2709, {wxCommandEvent, getClientData, 0}}, - {2710, {wxCommandEvent, getExtraLong, 0}}, - {2711, {wxCommandEvent, getInt, 0}}, - {2712, {wxCommandEvent, getSelection, 0}}, - {2713, {wxCommandEvent, getString, 0}}, - {2714, {wxCommandEvent, isChecked, 0}}, - {2715, {wxCommandEvent, isSelection, 0}}, - {2716, {wxCommandEvent, setInt, 1}}, - {2717, {wxCommandEvent, setString, 1}}, - {2718, {wxScrollEvent, getOrientation, 0}}, - {2719, {wxScrollEvent, getPosition, 0}}, - {2720, {wxScrollWinEvent, getOrientation, 0}}, - {2721, {wxScrollWinEvent, getPosition, 0}}, - {2722, {wxMouseEvent, altDown, 0}}, - {2723, {wxMouseEvent, button, 1}}, - {2724, {wxMouseEvent, buttonDClick, 1}}, - {2725, {wxMouseEvent, buttonDown, 1}}, - {2726, {wxMouseEvent, buttonUp, 1}}, - {2727, {wxMouseEvent, cmdDown, 0}}, - {2728, {wxMouseEvent, controlDown, 0}}, - {2729, {wxMouseEvent, dragging, 0}}, - {2730, {wxMouseEvent, entering, 0}}, - {2731, {wxMouseEvent, getButton, 0}}, - {2734, {wxMouseEvent, getPosition, 0}}, - {2735, {wxMouseEvent, getLogicalPosition, 1}}, - {2736, {wxMouseEvent, getLinesPerAction, 0}}, - {2737, {wxMouseEvent, getWheelRotation, 0}}, - {2738, {wxMouseEvent, getWheelDelta, 0}}, - {2739, {wxMouseEvent, getX, 0}}, - {2740, {wxMouseEvent, getY, 0}}, - {2741, {wxMouseEvent, isButton, 0}}, - {2742, {wxMouseEvent, isPageScroll, 0}}, - {2743, {wxMouseEvent, leaving, 0}}, - {2744, {wxMouseEvent, leftDClick, 0}}, - {2745, {wxMouseEvent, leftDown, 0}}, - {2746, {wxMouseEvent, leftIsDown, 0}}, - {2747, {wxMouseEvent, leftUp, 0}}, - {2748, {wxMouseEvent, metaDown, 0}}, - {2749, {wxMouseEvent, middleDClick, 0}}, - {2750, {wxMouseEvent, middleDown, 0}}, - {2751, {wxMouseEvent, middleIsDown, 0}}, - {2752, {wxMouseEvent, middleUp, 0}}, - {2753, {wxMouseEvent, moving, 0}}, - {2754, {wxMouseEvent, rightDClick, 0}}, - {2755, {wxMouseEvent, rightDown, 0}}, - {2756, {wxMouseEvent, rightIsDown, 0}}, - {2757, {wxMouseEvent, rightUp, 0}}, - {2758, {wxMouseEvent, shiftDown, 0}}, - {2759, {wxSetCursorEvent, getCursor, 0}}, - {2760, {wxSetCursorEvent, getX, 0}}, - {2761, {wxSetCursorEvent, getY, 0}}, - {2762, {wxSetCursorEvent, hasCursor, 0}}, - {2763, {wxSetCursorEvent, setCursor, 1}}, - {2764, {wxKeyEvent, altDown, 0}}, - {2765, {wxKeyEvent, cmdDown, 0}}, - {2766, {wxKeyEvent, controlDown, 0}}, - {2767, {wxKeyEvent, getKeyCode, 0}}, - {2768, {wxKeyEvent, getModifiers, 0}}, - {2771, {wxKeyEvent, getPosition, 0}}, - {2772, {wxKeyEvent, getRawKeyCode, 0}}, - {2773, {wxKeyEvent, getRawKeyFlags, 0}}, - {2774, {wxKeyEvent, getUnicodeKey, 0}}, - {2775, {wxKeyEvent, getX, 0}}, - {2776, {wxKeyEvent, getY, 0}}, - {2777, {wxKeyEvent, hasModifiers, 0}}, - {2778, {wxKeyEvent, metaDown, 0}}, - {2779, {wxKeyEvent, shiftDown, 0}}, - {2780, {wxSizeEvent, getSize, 0}}, - {2781, {wxMoveEvent, getPosition, 0}}, - {2782, {wxEraseEvent, getDC, 0}}, - {2783, {wxFocusEvent, getWindow, 0}}, - {2784, {wxChildFocusEvent, getWindow, 0}}, - {2785, {wxMenuEvent, getMenu, 0}}, - {2786, {wxMenuEvent, getMenuId, 0}}, - {2787, {wxMenuEvent, isPopup, 0}}, - {2788, {wxCloseEvent, canVeto, 0}}, - {2789, {wxCloseEvent, getLoggingOff, 0}}, - {2790, {wxCloseEvent, setCanVeto, 1}}, - {2791, {wxCloseEvent, setLoggingOff, 1}}, - {2792, {wxCloseEvent, veto, 1}}, - {2793, {wxShowEvent, setShow, 1}}, - {2794, {wxShowEvent, getShow, 0}}, - {2795, {wxIconizeEvent, iconized, 0}}, - {2796, {wxJoystickEvent, buttonDown, 1}}, - {2797, {wxJoystickEvent, buttonIsDown, 1}}, - {2798, {wxJoystickEvent, buttonUp, 1}}, - {2799, {wxJoystickEvent, getButtonChange, 0}}, - {2800, {wxJoystickEvent, getButtonState, 0}}, - {2801, {wxJoystickEvent, getJoystick, 0}}, - {2802, {wxJoystickEvent, getPosition, 0}}, - {2803, {wxJoystickEvent, getZPosition, 0}}, - {2804, {wxJoystickEvent, isButton, 0}}, - {2805, {wxJoystickEvent, isMove, 0}}, - {2806, {wxJoystickEvent, isZMove, 0}}, - {2807, {wxUpdateUIEvent, canUpdate, 1}}, - {2808, {wxUpdateUIEvent, check, 1}}, - {2809, {wxUpdateUIEvent, enable, 1}}, - {2810, {wxUpdateUIEvent, show, 1}}, - {2811, {wxUpdateUIEvent, getChecked, 0}}, - {2812, {wxUpdateUIEvent, getEnabled, 0}}, - {2813, {wxUpdateUIEvent, getShown, 0}}, - {2814, {wxUpdateUIEvent, getSetChecked, 0}}, - {2815, {wxUpdateUIEvent, getSetEnabled, 0}}, - {2816, {wxUpdateUIEvent, getSetShown, 0}}, - {2817, {wxUpdateUIEvent, getSetText, 0}}, - {2818, {wxUpdateUIEvent, getText, 0}}, - {2819, {wxUpdateUIEvent, getMode, 0}}, - {2820, {wxUpdateUIEvent, getUpdateInterval, 0}}, - {2821, {wxUpdateUIEvent, resetUpdateTime, 0}}, - {2822, {wxUpdateUIEvent, setMode, 1}}, - {2823, {wxUpdateUIEvent, setText, 1}}, - {2824, {wxUpdateUIEvent, setUpdateInterval, 1}}, - {2825, {wxMouseCaptureChangedEvent, getCapturedWindow, 0}}, - {2826, {wxPaletteChangedEvent, setChangedWindow, 1}}, - {2827, {wxPaletteChangedEvent, getChangedWindow, 0}}, - {2828, {wxQueryNewPaletteEvent, setPaletteRealized, 1}}, - {2829, {wxQueryNewPaletteEvent, getPaletteRealized, 0}}, - {2830, {wxNavigationKeyEvent, getDirection, 0}}, - {2831, {wxNavigationKeyEvent, setDirection, 1}}, - {2832, {wxNavigationKeyEvent, isWindowChange, 0}}, - {2833, {wxNavigationKeyEvent, setWindowChange, 1}}, - {2834, {wxNavigationKeyEvent, isFromTab, 0}}, - {2835, {wxNavigationKeyEvent, setFromTab, 1}}, - {2836, {wxNavigationKeyEvent, getCurrentFocus, 0}}, - {2837, {wxNavigationKeyEvent, setCurrentFocus, 1}}, - {2838, {wxHelpEvent, getOrigin, 0}}, - {2839, {wxHelpEvent, getPosition, 0}}, - {2840, {wxHelpEvent, setOrigin, 1}}, - {2841, {wxHelpEvent, setPosition, 1}}, - {2842, {wxContextMenuEvent, getPosition, 0}}, - {2843, {wxContextMenuEvent, setPosition, 1}}, - {2844, {wxIdleEvent, canSend, 1}}, - {2845, {wxIdleEvent, getMode, 0}}, - {2846, {wxIdleEvent, requestMore, 1}}, - {2847, {wxIdleEvent, moreRequested, 0}}, - {2848, {wxIdleEvent, setMode, 1}}, - {2849, {wxGridEvent, altDown, 0}}, - {2850, {wxGridEvent, controlDown, 0}}, - {2851, {wxGridEvent, getCol, 0}}, - {2852, {wxGridEvent, getPosition, 0}}, - {2853, {wxGridEvent, getRow, 0}}, - {2854, {wxGridEvent, metaDown, 0}}, - {2855, {wxGridEvent, selecting, 0}}, - {2856, {wxGridEvent, shiftDown, 0}}, - {2857, {wxNotifyEvent, allow, 0}}, - {2858, {wxNotifyEvent, isAllowed, 0}}, - {2859, {wxNotifyEvent, veto, 0}}, - {2860, {wxSashEvent, getEdge, 0}}, - {2861, {wxSashEvent, getDragRect, 0}}, - {2862, {wxSashEvent, getDragStatus, 0}}, - {2863, {wxListEvent, getCacheFrom, 0}}, - {2864, {wxListEvent, getCacheTo, 0}}, - {2865, {wxListEvent, getKeyCode, 0}}, - {2866, {wxListEvent, getIndex, 0}}, - {2867, {wxListEvent, getColumn, 0}}, - {2868, {wxListEvent, getPoint, 0}}, - {2869, {wxListEvent, getLabel, 0}}, - {2870, {wxListEvent, getText, 0}}, - {2871, {wxListEvent, getImage, 0}}, - {2872, {wxListEvent, getData, 0}}, - {2873, {wxListEvent, getMask, 0}}, - {2874, {wxListEvent, getItem, 0}}, - {2875, {wxListEvent, isEditCancelled, 0}}, - {2876, {wxDateEvent, getDate, 0}}, - {2877, {wxCalendarEvent, getWeekDay, 0}}, - {2878, {wxFileDirPickerEvent, getPath, 0}}, - {2879, {wxColourPickerEvent, getColour, 0}}, - {2880, {wxFontPickerEvent, getFont, 0}}, - {2881, {wxStyledTextEvent, getPosition, 0}}, - {2882, {wxStyledTextEvent, getKey, 0}}, - {2883, {wxStyledTextEvent, getModifiers, 0}}, - {2884, {wxStyledTextEvent, getModificationType, 0}}, - {2885, {wxStyledTextEvent, getText, 0}}, - {2886, {wxStyledTextEvent, getLength, 0}}, - {2887, {wxStyledTextEvent, getLinesAdded, 0}}, - {2888, {wxStyledTextEvent, getLine, 0}}, - {2889, {wxStyledTextEvent, getFoldLevelNow, 0}}, - {2890, {wxStyledTextEvent, getFoldLevelPrev, 0}}, - {2891, {wxStyledTextEvent, getMargin, 0}}, - {2892, {wxStyledTextEvent, getMessage, 0}}, - {2893, {wxStyledTextEvent, getWParam, 0}}, - {2894, {wxStyledTextEvent, getLParam, 0}}, - {2895, {wxStyledTextEvent, getListType, 0}}, - {2896, {wxStyledTextEvent, getX, 0}}, - {2897, {wxStyledTextEvent, getY, 0}}, - {2898, {wxStyledTextEvent, getDragText, 0}}, - {2899, {wxStyledTextEvent, getDragAllowMove, 0}}, - {2900, {wxStyledTextEvent, getDragResult, 0}}, - {2901, {wxStyledTextEvent, getShift, 0}}, - {2902, {wxStyledTextEvent, getControl, 0}}, - {2903, {wxStyledTextEvent, getAlt, 0}}, - {2904, {utils, getKeyState, 1}}, - {2905, {utils, getMousePosition, 2}}, - {2906, {utils, getMouseState, 0}}, - {2907, {utils, setDetectableAutoRepeat, 1}}, - {2908, {utils, bell, 0}}, - {2909, {utils, findMenuItemId, 3}}, - {2910, {utils, genericFindWindowAtPoint, 1}}, - {2911, {utils, findWindowAtPoint, 1}}, - {2912, {utils, beginBusyCursor, 1}}, - {2913, {utils, endBusyCursor, 0}}, - {2914, {utils, isBusy, 0}}, - {2915, {utils, shutdown, 1}}, - {2916, {utils, shell, 1}}, - {2917, {utils, launchDefaultBrowser, 2}}, - {2918, {utils, getEmailAddress, 0}}, - {2919, {utils, getUserId, 0}}, - {2920, {utils, getHomeDir, 0}}, - {2921, {utils, newId, 0}}, - {2922, {utils, registerId, 1}}, - {2923, {utils, getCurrentId, 0}}, - {2924, {utils, getOsDescription, 0}}, - {2925, {utils, isPlatformLittleEndian, 0}}, - {2926, {utils, isPlatform64Bit, 0}}, - {2927, {wxPrintout, new, 1}}, - {2928, {wxPrintout, destruct, 0}}, - {2929, {wxPrintout, getDC, 0}}, - {2930, {wxPrintout, getPageSizeMM, 2}}, - {2931, {wxPrintout, getPageSizePixels, 2}}, - {2932, {wxPrintout, getPaperRectPixels, 0}}, - {2933, {wxPrintout, getPPIPrinter, 2}}, - {2934, {wxPrintout, getPPIScreen, 2}}, - {2935, {wxPrintout, getTitle, 0}}, - {2936, {wxPrintout, isPreview, 0}}, - {2937, {wxPrintout, fitThisSizeToPaper, 1}}, - {2938, {wxPrintout, fitThisSizeToPage, 1}}, - {2939, {wxPrintout, fitThisSizeToPageMargins, 2}}, - {2940, {wxPrintout, mapScreenSizeToPaper, 0}}, - {2941, {wxPrintout, mapScreenSizeToPage, 0}}, - {2942, {wxPrintout, mapScreenSizeToPageMargins, 1}}, - {2943, {wxPrintout, mapScreenSizeToDevice, 0}}, - {2944, {wxPrintout, getLogicalPaperRect, 0}}, - {2945, {wxPrintout, getLogicalPageRect, 0}}, - {2946, {wxPrintout, getLogicalPageMarginsRect, 1}}, - {2947, {wxPrintout, setLogicalOrigin, 2}}, - {2948, {wxPrintout, offsetLogicalOrigin, 2}}, - {2949, {wxStyledTextCtrl, new_2, 2}}, - {2950, {wxStyledTextCtrl, new_0, 0}}, - {2951, {wxStyledTextCtrl, destruct, 0}}, - {2952, {wxStyledTextCtrl, create, 2}}, - {2953, {wxStyledTextCtrl, addText, 1}}, - {2954, {wxStyledTextCtrl, addStyledText, 1}}, - {2955, {wxStyledTextCtrl, insertText, 2}}, - {2956, {wxStyledTextCtrl, clearAll, 0}}, - {2957, {wxStyledTextCtrl, clearDocumentStyle, 0}}, - {2958, {wxStyledTextCtrl, getLength, 0}}, - {2959, {wxStyledTextCtrl, getCharAt, 1}}, - {2960, {wxStyledTextCtrl, getCurrentPos, 0}}, - {2961, {wxStyledTextCtrl, getAnchor, 0}}, - {2962, {wxStyledTextCtrl, getStyleAt, 1}}, - {2963, {wxStyledTextCtrl, redo, 0}}, - {2964, {wxStyledTextCtrl, setUndoCollection, 1}}, - {2965, {wxStyledTextCtrl, selectAll, 0}}, - {2966, {wxStyledTextCtrl, setSavePoint, 0}}, - {2967, {wxStyledTextCtrl, getStyledText, 2}}, - {2968, {wxStyledTextCtrl, canRedo, 0}}, - {2969, {wxStyledTextCtrl, markerLineFromHandle, 1}}, - {2970, {wxStyledTextCtrl, markerDeleteHandle, 1}}, - {2971, {wxStyledTextCtrl, getUndoCollection, 0}}, - {2972, {wxStyledTextCtrl, getViewWhiteSpace, 0}}, - {2973, {wxStyledTextCtrl, setViewWhiteSpace, 1}}, - {2974, {wxStyledTextCtrl, positionFromPoint, 1}}, - {2975, {wxStyledTextCtrl, positionFromPointClose, 2}}, - {2976, {wxStyledTextCtrl, gotoLine, 1}}, - {2977, {wxStyledTextCtrl, gotoPos, 1}}, - {2978, {wxStyledTextCtrl, setAnchor, 1}}, - {2979, {wxStyledTextCtrl, getCurLine, 1}}, - {2980, {wxStyledTextCtrl, getEndStyled, 0}}, - {2981, {wxStyledTextCtrl, convertEOLs, 1}}, - {2982, {wxStyledTextCtrl, getEOLMode, 0}}, - {2983, {wxStyledTextCtrl, setEOLMode, 1}}, - {2984, {wxStyledTextCtrl, startStyling, 2}}, - {2985, {wxStyledTextCtrl, setStyling, 2}}, - {2986, {wxStyledTextCtrl, getBufferedDraw, 0}}, - {2987, {wxStyledTextCtrl, setBufferedDraw, 1}}, - {2988, {wxStyledTextCtrl, setTabWidth, 1}}, - {2989, {wxStyledTextCtrl, getTabWidth, 0}}, - {2990, {wxStyledTextCtrl, setCodePage, 1}}, - {2991, {wxStyledTextCtrl, markerDefine, 3}}, - {2992, {wxStyledTextCtrl, markerSetForeground, 2}}, - {2993, {wxStyledTextCtrl, markerSetBackground, 2}}, - {2994, {wxStyledTextCtrl, markerAdd, 2}}, - {2995, {wxStyledTextCtrl, markerDelete, 2}}, - {2996, {wxStyledTextCtrl, markerDeleteAll, 1}}, - {2997, {wxStyledTextCtrl, markerGet, 1}}, - {2998, {wxStyledTextCtrl, markerNext, 2}}, - {2999, {wxStyledTextCtrl, markerPrevious, 2}}, - {3000, {wxStyledTextCtrl, markerDefineBitmap, 2}}, - {3001, {wxStyledTextCtrl, markerAddSet, 2}}, - {3002, {wxStyledTextCtrl, markerSetAlpha, 2}}, - {3003, {wxStyledTextCtrl, setMarginType, 2}}, - {3004, {wxStyledTextCtrl, getMarginType, 1}}, - {3005, {wxStyledTextCtrl, setMarginWidth, 2}}, - {3006, {wxStyledTextCtrl, getMarginWidth, 1}}, - {3007, {wxStyledTextCtrl, setMarginMask, 2}}, - {3008, {wxStyledTextCtrl, getMarginMask, 1}}, - {3009, {wxStyledTextCtrl, setMarginSensitive, 2}}, - {3010, {wxStyledTextCtrl, getMarginSensitive, 1}}, - {3011, {wxStyledTextCtrl, styleClearAll, 0}}, - {3012, {wxStyledTextCtrl, styleSetForeground, 2}}, - {3013, {wxStyledTextCtrl, styleSetBackground, 2}}, - {3014, {wxStyledTextCtrl, styleSetBold, 2}}, - {3015, {wxStyledTextCtrl, styleSetItalic, 2}}, - {3016, {wxStyledTextCtrl, styleSetSize, 2}}, - {3017, {wxStyledTextCtrl, styleSetFaceName, 2}}, - {3018, {wxStyledTextCtrl, styleSetEOLFilled, 2}}, - {3019, {wxStyledTextCtrl, styleResetDefault, 0}}, - {3020, {wxStyledTextCtrl, styleSetUnderline, 2}}, - {3021, {wxStyledTextCtrl, styleSetCase, 2}}, - {3022, {wxStyledTextCtrl, styleSetHotSpot, 2}}, - {3023, {wxStyledTextCtrl, setSelForeground, 2}}, - {3024, {wxStyledTextCtrl, setSelBackground, 2}}, - {3025, {wxStyledTextCtrl, getSelAlpha, 0}}, - {3026, {wxStyledTextCtrl, setSelAlpha, 1}}, - {3027, {wxStyledTextCtrl, setCaretForeground, 1}}, - {3028, {wxStyledTextCtrl, cmdKeyAssign, 3}}, - {3029, {wxStyledTextCtrl, cmdKeyClear, 2}}, - {3030, {wxStyledTextCtrl, cmdKeyClearAll, 0}}, - {3031, {wxStyledTextCtrl, setStyleBytes, 2}}, - {3032, {wxStyledTextCtrl, styleSetVisible, 2}}, - {3033, {wxStyledTextCtrl, getCaretPeriod, 0}}, - {3034, {wxStyledTextCtrl, setCaretPeriod, 1}}, - {3035, {wxStyledTextCtrl, setWordChars, 1}}, - {3036, {wxStyledTextCtrl, beginUndoAction, 0}}, - {3037, {wxStyledTextCtrl, endUndoAction, 0}}, - {3038, {wxStyledTextCtrl, indicatorSetStyle, 2}}, - {3039, {wxStyledTextCtrl, indicatorGetStyle, 1}}, - {3040, {wxStyledTextCtrl, indicatorSetForeground, 2}}, - {3041, {wxStyledTextCtrl, indicatorGetForeground, 1}}, - {3042, {wxStyledTextCtrl, setWhitespaceForeground, 2}}, - {3043, {wxStyledTextCtrl, setWhitespaceBackground, 2}}, - {3044, {wxStyledTextCtrl, getStyleBits, 0}}, - {3045, {wxStyledTextCtrl, setLineState, 2}}, - {3046, {wxStyledTextCtrl, getLineState, 1}}, - {3047, {wxStyledTextCtrl, getMaxLineState, 0}}, - {3048, {wxStyledTextCtrl, getCaretLineVisible, 0}}, - {3049, {wxStyledTextCtrl, setCaretLineVisible, 1}}, - {3050, {wxStyledTextCtrl, getCaretLineBackground, 0}}, - {3051, {wxStyledTextCtrl, setCaretLineBackground, 1}}, - {3052, {wxStyledTextCtrl, autoCompShow, 2}}, - {3053, {wxStyledTextCtrl, autoCompCancel, 0}}, - {3054, {wxStyledTextCtrl, autoCompActive, 0}}, - {3055, {wxStyledTextCtrl, autoCompPosStart, 0}}, - {3056, {wxStyledTextCtrl, autoCompComplete, 0}}, - {3057, {wxStyledTextCtrl, autoCompStops, 1}}, - {3058, {wxStyledTextCtrl, autoCompSetSeparator, 1}}, - {3059, {wxStyledTextCtrl, autoCompGetSeparator, 0}}, - {3060, {wxStyledTextCtrl, autoCompSelect, 1}}, - {3061, {wxStyledTextCtrl, autoCompSetCancelAtStart, 1}}, - {3062, {wxStyledTextCtrl, autoCompGetCancelAtStart, 0}}, - {3063, {wxStyledTextCtrl, autoCompSetFillUps, 1}}, - {3064, {wxStyledTextCtrl, autoCompSetChooseSingle, 1}}, - {3065, {wxStyledTextCtrl, autoCompGetChooseSingle, 0}}, - {3066, {wxStyledTextCtrl, autoCompSetIgnoreCase, 1}}, - {3067, {wxStyledTextCtrl, autoCompGetIgnoreCase, 0}}, - {3068, {wxStyledTextCtrl, userListShow, 2}}, - {3069, {wxStyledTextCtrl, autoCompSetAutoHide, 1}}, - {3070, {wxStyledTextCtrl, autoCompGetAutoHide, 0}}, - {3071, {wxStyledTextCtrl, autoCompSetDropRestOfWord, 1}}, - {3072, {wxStyledTextCtrl, autoCompGetDropRestOfWord, 0}}, - {3073, {wxStyledTextCtrl, registerImage, 2}}, - {3074, {wxStyledTextCtrl, clearRegisteredImages, 0}}, - {3075, {wxStyledTextCtrl, autoCompGetTypeSeparator, 0}}, - {3076, {wxStyledTextCtrl, autoCompSetTypeSeparator, 1}}, - {3077, {wxStyledTextCtrl, autoCompSetMaxWidth, 1}}, - {3078, {wxStyledTextCtrl, autoCompGetMaxWidth, 0}}, - {3079, {wxStyledTextCtrl, autoCompSetMaxHeight, 1}}, - {3080, {wxStyledTextCtrl, autoCompGetMaxHeight, 0}}, - {3081, {wxStyledTextCtrl, setIndent, 1}}, - {3082, {wxStyledTextCtrl, getIndent, 0}}, - {3083, {wxStyledTextCtrl, setUseTabs, 1}}, - {3084, {wxStyledTextCtrl, getUseTabs, 0}}, - {3085, {wxStyledTextCtrl, setLineIndentation, 2}}, - {3086, {wxStyledTextCtrl, getLineIndentation, 1}}, - {3087, {wxStyledTextCtrl, getLineIndentPosition, 1}}, - {3088, {wxStyledTextCtrl, getColumn, 1}}, - {3089, {wxStyledTextCtrl, setUseHorizontalScrollBar, 1}}, - {3090, {wxStyledTextCtrl, getUseHorizontalScrollBar, 0}}, - {3091, {wxStyledTextCtrl, setIndentationGuides, 1}}, - {3092, {wxStyledTextCtrl, getIndentationGuides, 0}}, - {3093, {wxStyledTextCtrl, setHighlightGuide, 1}}, - {3094, {wxStyledTextCtrl, getHighlightGuide, 0}}, - {3095, {wxStyledTextCtrl, getLineEndPosition, 1}}, - {3096, {wxStyledTextCtrl, getCodePage, 0}}, - {3097, {wxStyledTextCtrl, getCaretForeground, 0}}, - {3098, {wxStyledTextCtrl, getReadOnly, 0}}, - {3099, {wxStyledTextCtrl, setCurrentPos, 1}}, - {3100, {wxStyledTextCtrl, setSelectionStart, 1}}, - {3101, {wxStyledTextCtrl, getSelectionStart, 0}}, - {3102, {wxStyledTextCtrl, setSelectionEnd, 1}}, - {3103, {wxStyledTextCtrl, getSelectionEnd, 0}}, - {3104, {wxStyledTextCtrl, setPrintMagnification, 1}}, - {3105, {wxStyledTextCtrl, getPrintMagnification, 0}}, - {3106, {wxStyledTextCtrl, setPrintColourMode, 1}}, - {3107, {wxStyledTextCtrl, getPrintColourMode, 0}}, - {3108, {wxStyledTextCtrl, findText, 4}}, - {3109, {wxStyledTextCtrl, formatRange, 7}}, - {3110, {wxStyledTextCtrl, getFirstVisibleLine, 0}}, - {3111, {wxStyledTextCtrl, getLine, 1}}, - {3112, {wxStyledTextCtrl, getLineCount, 0}}, - {3113, {wxStyledTextCtrl, setMarginLeft, 1}}, - {3114, {wxStyledTextCtrl, getMarginLeft, 0}}, - {3115, {wxStyledTextCtrl, setMarginRight, 1}}, - {3116, {wxStyledTextCtrl, getMarginRight, 0}}, - {3117, {wxStyledTextCtrl, getModify, 0}}, - {3118, {wxStyledTextCtrl, setSelection, 2}}, - {3119, {wxStyledTextCtrl, getSelectedText, 0}}, - {3120, {wxStyledTextCtrl, getTextRange, 2}}, - {3121, {wxStyledTextCtrl, hideSelection, 1}}, - {3122, {wxStyledTextCtrl, lineFromPosition, 1}}, - {3123, {wxStyledTextCtrl, positionFromLine, 1}}, - {3124, {wxStyledTextCtrl, lineScroll, 2}}, - {3125, {wxStyledTextCtrl, ensureCaretVisible, 0}}, - {3126, {wxStyledTextCtrl, replaceSelection, 1}}, - {3127, {wxStyledTextCtrl, setReadOnly, 1}}, - {3128, {wxStyledTextCtrl, canPaste, 0}}, - {3129, {wxStyledTextCtrl, canUndo, 0}}, - {3130, {wxStyledTextCtrl, emptyUndoBuffer, 0}}, - {3131, {wxStyledTextCtrl, undo, 0}}, - {3132, {wxStyledTextCtrl, cut, 0}}, - {3133, {wxStyledTextCtrl, copy, 0}}, - {3134, {wxStyledTextCtrl, paste, 0}}, - {3135, {wxStyledTextCtrl, clear, 0}}, - {3136, {wxStyledTextCtrl, setText, 1}}, - {3137, {wxStyledTextCtrl, getText, 0}}, - {3138, {wxStyledTextCtrl, getTextLength, 0}}, - {3139, {wxStyledTextCtrl, getOvertype, 0}}, - {3140, {wxStyledTextCtrl, setCaretWidth, 1}}, - {3141, {wxStyledTextCtrl, getCaretWidth, 0}}, - {3142, {wxStyledTextCtrl, setTargetStart, 1}}, - {3143, {wxStyledTextCtrl, getTargetStart, 0}}, - {3144, {wxStyledTextCtrl, setTargetEnd, 1}}, - {3145, {wxStyledTextCtrl, getTargetEnd, 0}}, - {3146, {wxStyledTextCtrl, replaceTarget, 1}}, - {3147, {wxStyledTextCtrl, searchInTarget, 1}}, - {3148, {wxStyledTextCtrl, setSearchFlags, 1}}, - {3149, {wxStyledTextCtrl, getSearchFlags, 0}}, - {3150, {wxStyledTextCtrl, callTipShow, 2}}, - {3151, {wxStyledTextCtrl, callTipCancel, 0}}, - {3152, {wxStyledTextCtrl, callTipActive, 0}}, - {3153, {wxStyledTextCtrl, callTipPosAtStart, 0}}, - {3154, {wxStyledTextCtrl, callTipSetHighlight, 2}}, - {3155, {wxStyledTextCtrl, callTipSetBackground, 1}}, - {3156, {wxStyledTextCtrl, callTipSetForeground, 1}}, - {3157, {wxStyledTextCtrl, callTipSetForegroundHighlight, 1}}, - {3158, {wxStyledTextCtrl, callTipUseStyle, 1}}, - {3159, {wxStyledTextCtrl, visibleFromDocLine, 1}}, - {3160, {wxStyledTextCtrl, docLineFromVisible, 1}}, - {3161, {wxStyledTextCtrl, wrapCount, 1}}, - {3162, {wxStyledTextCtrl, setFoldLevel, 2}}, - {3163, {wxStyledTextCtrl, getFoldLevel, 1}}, - {3164, {wxStyledTextCtrl, getLastChild, 2}}, - {3165, {wxStyledTextCtrl, getFoldParent, 1}}, - {3166, {wxStyledTextCtrl, showLines, 2}}, - {3167, {wxStyledTextCtrl, hideLines, 2}}, - {3168, {wxStyledTextCtrl, getLineVisible, 1}}, - {3169, {wxStyledTextCtrl, setFoldExpanded, 2}}, - {3170, {wxStyledTextCtrl, getFoldExpanded, 1}}, - {3171, {wxStyledTextCtrl, toggleFold, 1}}, - {3172, {wxStyledTextCtrl, ensureVisible, 1}}, - {3173, {wxStyledTextCtrl, setFoldFlags, 1}}, - {3174, {wxStyledTextCtrl, ensureVisibleEnforcePolicy, 1}}, - {3175, {wxStyledTextCtrl, setTabIndents, 1}}, - {3176, {wxStyledTextCtrl, getTabIndents, 0}}, - {3177, {wxStyledTextCtrl, setBackSpaceUnIndents, 1}}, - {3178, {wxStyledTextCtrl, getBackSpaceUnIndents, 0}}, - {3179, {wxStyledTextCtrl, setMouseDwellTime, 1}}, - {3180, {wxStyledTextCtrl, getMouseDwellTime, 0}}, - {3181, {wxStyledTextCtrl, wordStartPosition, 2}}, - {3182, {wxStyledTextCtrl, wordEndPosition, 2}}, - {3183, {wxStyledTextCtrl, setWrapMode, 1}}, - {3184, {wxStyledTextCtrl, getWrapMode, 0}}, - {3185, {wxStyledTextCtrl, setWrapVisualFlags, 1}}, - {3186, {wxStyledTextCtrl, getWrapVisualFlags, 0}}, - {3187, {wxStyledTextCtrl, setWrapVisualFlagsLocation, 1}}, - {3188, {wxStyledTextCtrl, getWrapVisualFlagsLocation, 0}}, - {3189, {wxStyledTextCtrl, setWrapStartIndent, 1}}, - {3190, {wxStyledTextCtrl, getWrapStartIndent, 0}}, - {3191, {wxStyledTextCtrl, setLayoutCache, 1}}, - {3192, {wxStyledTextCtrl, getLayoutCache, 0}}, - {3193, {wxStyledTextCtrl, setScrollWidth, 1}}, - {3194, {wxStyledTextCtrl, getScrollWidth, 0}}, - {3195, {wxStyledTextCtrl, textWidth, 2}}, - {3196, {wxStyledTextCtrl, getEndAtLastLine, 0}}, - {3197, {wxStyledTextCtrl, textHeight, 1}}, - {3198, {wxStyledTextCtrl, setUseVerticalScrollBar, 1}}, - {3199, {wxStyledTextCtrl, getUseVerticalScrollBar, 0}}, - {3200, {wxStyledTextCtrl, appendText, 1}}, - {3201, {wxStyledTextCtrl, getTwoPhaseDraw, 0}}, - {3202, {wxStyledTextCtrl, setTwoPhaseDraw, 1}}, - {3203, {wxStyledTextCtrl, targetFromSelection, 0}}, - {3204, {wxStyledTextCtrl, linesJoin, 0}}, - {3205, {wxStyledTextCtrl, linesSplit, 1}}, - {3206, {wxStyledTextCtrl, setFoldMarginColour, 2}}, - {3207, {wxStyledTextCtrl, setFoldMarginHiColour, 2}}, - {3208, {wxStyledTextCtrl, lineDown, 0}}, - {3209, {wxStyledTextCtrl, lineDownExtend, 0}}, - {3210, {wxStyledTextCtrl, lineUp, 0}}, - {3211, {wxStyledTextCtrl, lineUpExtend, 0}}, - {3212, {wxStyledTextCtrl, charLeft, 0}}, - {3213, {wxStyledTextCtrl, charLeftExtend, 0}}, - {3214, {wxStyledTextCtrl, charRight, 0}}, - {3215, {wxStyledTextCtrl, charRightExtend, 0}}, - {3216, {wxStyledTextCtrl, wordLeft, 0}}, - {3217, {wxStyledTextCtrl, wordLeftExtend, 0}}, - {3218, {wxStyledTextCtrl, wordRight, 0}}, - {3219, {wxStyledTextCtrl, wordRightExtend, 0}}, - {3220, {wxStyledTextCtrl, home, 0}}, - {3221, {wxStyledTextCtrl, homeExtend, 0}}, - {3222, {wxStyledTextCtrl, lineEnd, 0}}, - {3223, {wxStyledTextCtrl, lineEndExtend, 0}}, - {3224, {wxStyledTextCtrl, documentStart, 0}}, - {3225, {wxStyledTextCtrl, documentStartExtend, 0}}, - {3226, {wxStyledTextCtrl, documentEnd, 0}}, - {3227, {wxStyledTextCtrl, documentEndExtend, 0}}, - {3228, {wxStyledTextCtrl, pageUp, 0}}, - {3229, {wxStyledTextCtrl, pageUpExtend, 0}}, - {3230, {wxStyledTextCtrl, pageDown, 0}}, - {3231, {wxStyledTextCtrl, pageDownExtend, 0}}, - {3232, {wxStyledTextCtrl, editToggleOvertype, 0}}, - {3233, {wxStyledTextCtrl, cancel, 0}}, - {3234, {wxStyledTextCtrl, deleteBack, 0}}, - {3235, {wxStyledTextCtrl, tab, 0}}, - {3236, {wxStyledTextCtrl, backTab, 0}}, - {3237, {wxStyledTextCtrl, newLine, 0}}, - {3238, {wxStyledTextCtrl, formFeed, 0}}, - {3239, {wxStyledTextCtrl, vCHome, 0}}, - {3240, {wxStyledTextCtrl, vCHomeExtend, 0}}, - {3241, {wxStyledTextCtrl, zoomIn, 0}}, - {3242, {wxStyledTextCtrl, zoomOut, 0}}, - {3243, {wxStyledTextCtrl, delWordLeft, 0}}, - {3244, {wxStyledTextCtrl, delWordRight, 0}}, - {3245, {wxStyledTextCtrl, lineCut, 0}}, - {3246, {wxStyledTextCtrl, lineDelete, 0}}, - {3247, {wxStyledTextCtrl, lineTranspose, 0}}, - {3248, {wxStyledTextCtrl, lineDuplicate, 0}}, - {3249, {wxStyledTextCtrl, lowerCase, 0}}, - {3250, {wxStyledTextCtrl, upperCase, 0}}, - {3251, {wxStyledTextCtrl, lineScrollDown, 0}}, - {3252, {wxStyledTextCtrl, lineScrollUp, 0}}, - {3253, {wxStyledTextCtrl, deleteBackNotLine, 0}}, - {3254, {wxStyledTextCtrl, homeDisplay, 0}}, - {3255, {wxStyledTextCtrl, homeDisplayExtend, 0}}, - {3256, {wxStyledTextCtrl, lineEndDisplay, 0}}, - {3257, {wxStyledTextCtrl, lineEndDisplayExtend, 0}}, - {3258, {wxStyledTextCtrl, homeWrapExtend, 0}}, - {3259, {wxStyledTextCtrl, lineEndWrap, 0}}, - {3260, {wxStyledTextCtrl, lineEndWrapExtend, 0}}, - {3261, {wxStyledTextCtrl, vCHomeWrap, 0}}, - {3262, {wxStyledTextCtrl, vCHomeWrapExtend, 0}}, - {3263, {wxStyledTextCtrl, lineCopy, 0}}, - {3264, {wxStyledTextCtrl, moveCaretInsideView, 0}}, - {3265, {wxStyledTextCtrl, lineLength, 1}}, - {3266, {wxStyledTextCtrl, braceHighlight, 2}}, - {3267, {wxStyledTextCtrl, braceBadLight, 1}}, - {3268, {wxStyledTextCtrl, braceMatch, 1}}, - {3269, {wxStyledTextCtrl, getViewEOL, 0}}, - {3270, {wxStyledTextCtrl, setViewEOL, 1}}, - {3271, {wxStyledTextCtrl, setModEventMask, 1}}, - {3272, {wxStyledTextCtrl, getEdgeColumn, 0}}, - {3273, {wxStyledTextCtrl, setEdgeColumn, 1}}, - {3274, {wxStyledTextCtrl, setEdgeMode, 1}}, - {3275, {wxStyledTextCtrl, getEdgeMode, 0}}, - {3276, {wxStyledTextCtrl, getEdgeColour, 0}}, - {3277, {wxStyledTextCtrl, setEdgeColour, 1}}, - {3278, {wxStyledTextCtrl, searchAnchor, 0}}, - {3279, {wxStyledTextCtrl, searchNext, 2}}, - {3280, {wxStyledTextCtrl, searchPrev, 2}}, - {3281, {wxStyledTextCtrl, linesOnScreen, 0}}, - {3282, {wxStyledTextCtrl, usePopUp, 1}}, - {3283, {wxStyledTextCtrl, selectionIsRectangle, 0}}, - {3284, {wxStyledTextCtrl, setZoom, 1}}, - {3285, {wxStyledTextCtrl, getZoom, 0}}, - {3286, {wxStyledTextCtrl, getModEventMask, 0}}, - {3287, {wxStyledTextCtrl, setSTCFocus, 1}}, - {3288, {wxStyledTextCtrl, getSTCFocus, 0}}, - {3289, {wxStyledTextCtrl, setStatus, 1}}, - {3290, {wxStyledTextCtrl, getStatus, 0}}, - {3291, {wxStyledTextCtrl, setMouseDownCaptures, 1}}, - {3292, {wxStyledTextCtrl, getMouseDownCaptures, 0}}, - {3293, {wxStyledTextCtrl, setSTCCursor, 1}}, - {3294, {wxStyledTextCtrl, getSTCCursor, 0}}, - {3295, {wxStyledTextCtrl, setControlCharSymbol, 1}}, - {3296, {wxStyledTextCtrl, getControlCharSymbol, 0}}, - {3297, {wxStyledTextCtrl, wordPartLeft, 0}}, - {3298, {wxStyledTextCtrl, wordPartLeftExtend, 0}}, - {3299, {wxStyledTextCtrl, wordPartRight, 0}}, - {3300, {wxStyledTextCtrl, wordPartRightExtend, 0}}, - {3301, {wxStyledTextCtrl, setVisiblePolicy, 2}}, - {3302, {wxStyledTextCtrl, delLineLeft, 0}}, - {3303, {wxStyledTextCtrl, delLineRight, 0}}, - {3304, {wxStyledTextCtrl, getXOffset, 0}}, - {3305, {wxStyledTextCtrl, chooseCaretX, 0}}, - {3306, {wxStyledTextCtrl, setXCaretPolicy, 2}}, - {3307, {wxStyledTextCtrl, setYCaretPolicy, 2}}, - {3308, {wxStyledTextCtrl, getPrintWrapMode, 0}}, - {3309, {wxStyledTextCtrl, setHotspotActiveForeground, 2}}, - {3310, {wxStyledTextCtrl, setHotspotActiveBackground, 2}}, - {3311, {wxStyledTextCtrl, setHotspotActiveUnderline, 1}}, - {3312, {wxStyledTextCtrl, setHotspotSingleLine, 1}}, - {3313, {wxStyledTextCtrl, paraDownExtend, 0}}, - {3314, {wxStyledTextCtrl, paraUp, 0}}, - {3315, {wxStyledTextCtrl, paraUpExtend, 0}}, - {3316, {wxStyledTextCtrl, positionBefore, 1}}, - {3317, {wxStyledTextCtrl, positionAfter, 1}}, - {3318, {wxStyledTextCtrl, copyRange, 2}}, - {3319, {wxStyledTextCtrl, copyText, 2}}, - {3320, {wxStyledTextCtrl, setSelectionMode, 1}}, - {3321, {wxStyledTextCtrl, getSelectionMode, 0}}, - {3322, {wxStyledTextCtrl, lineDownRectExtend, 0}}, - {3323, {wxStyledTextCtrl, lineUpRectExtend, 0}}, - {3324, {wxStyledTextCtrl, charLeftRectExtend, 0}}, - {3325, {wxStyledTextCtrl, charRightRectExtend, 0}}, - {3326, {wxStyledTextCtrl, homeRectExtend, 0}}, - {3327, {wxStyledTextCtrl, vCHomeRectExtend, 0}}, - {3328, {wxStyledTextCtrl, lineEndRectExtend, 0}}, - {3329, {wxStyledTextCtrl, pageUpRectExtend, 0}}, - {3330, {wxStyledTextCtrl, pageDownRectExtend, 0}}, - {3331, {wxStyledTextCtrl, stutteredPageUp, 0}}, - {3332, {wxStyledTextCtrl, stutteredPageUpExtend, 0}}, - {3333, {wxStyledTextCtrl, stutteredPageDown, 0}}, - {3334, {wxStyledTextCtrl, stutteredPageDownExtend, 0}}, - {3335, {wxStyledTextCtrl, wordLeftEnd, 0}}, - {3336, {wxStyledTextCtrl, wordLeftEndExtend, 0}}, - {3337, {wxStyledTextCtrl, wordRightEnd, 0}}, - {3338, {wxStyledTextCtrl, wordRightEndExtend, 0}}, - {3339, {wxStyledTextCtrl, setWhitespaceChars, 1}}, - {3340, {wxStyledTextCtrl, setCharsDefault, 0}}, - {3341, {wxStyledTextCtrl, autoCompGetCurrent, 0}}, - {3342, {wxStyledTextCtrl, allocate, 1}}, - {3343, {wxStyledTextCtrl, findColumn, 2}}, - {3344, {wxStyledTextCtrl, getCaretSticky, 0}}, - {3345, {wxStyledTextCtrl, setCaretSticky, 1}}, - {3346, {wxStyledTextCtrl, toggleCaretSticky, 0}}, - {3347, {wxStyledTextCtrl, setPasteConvertEndings, 1}}, - {3348, {wxStyledTextCtrl, getPasteConvertEndings, 0}}, - {3349, {wxStyledTextCtrl, selectionDuplicate, 0}}, - {3350, {wxStyledTextCtrl, setCaretLineBackAlpha, 1}}, - {3351, {wxStyledTextCtrl, getCaretLineBackAlpha, 0}}, - {3352, {wxStyledTextCtrl, startRecord, 0}}, - {3353, {wxStyledTextCtrl, stopRecord, 0}}, - {3354, {wxStyledTextCtrl, setLexer, 1}}, - {3355, {wxStyledTextCtrl, getLexer, 0}}, - {3356, {wxStyledTextCtrl, colourise, 2}}, - {3357, {wxStyledTextCtrl, setProperty, 2}}, - {3358, {wxStyledTextCtrl, setKeyWords, 2}}, - {3359, {wxStyledTextCtrl, setLexerLanguage, 1}}, - {3360, {wxStyledTextCtrl, getProperty, 1}}, - {3361, {wxStyledTextCtrl, getStyleBitsNeeded, 0}}, - {3362, {wxStyledTextCtrl, getCurrentLine, 0}}, - {3363, {wxStyledTextCtrl, styleSetSpec, 2}}, - {3364, {wxStyledTextCtrl, styleSetFont, 2}}, - {3365, {wxStyledTextCtrl, styleSetFontAttr, 7}}, - {3366, {wxStyledTextCtrl, styleSetCharacterSet, 2}}, - {3367, {wxStyledTextCtrl, styleSetFontEncoding, 2}}, - {3368, {wxStyledTextCtrl, cmdKeyExecute, 1}}, - {3369, {wxStyledTextCtrl, setMargins, 2}}, - {3370, {wxStyledTextCtrl, getSelection, 2}}, - {3371, {wxStyledTextCtrl, pointFromPosition, 1}}, - {3372, {wxStyledTextCtrl, scrollToLine, 1}}, - {3373, {wxStyledTextCtrl, scrollToColumn, 1}}, - {3374, {wxStyledTextCtrl, setVScrollBar, 1}}, - {3375, {wxStyledTextCtrl, setHScrollBar, 1}}, - {3376, {wxStyledTextCtrl, getLastKeydownProcessed, 0}}, - {3377, {wxStyledTextCtrl, setLastKeydownProcessed, 1}}, - {3378, {wxStyledTextCtrl, saveFile, 1}}, - {3379, {wxStyledTextCtrl, loadFile, 1}}, - {3380, {wxStyledTextCtrl, doDragOver, 3}}, - {3381, {wxStyledTextCtrl, doDropText, 3}}, - {3382, {wxStyledTextCtrl, getUseAntiAliasing, 0}}, - {3383, {wxStyledTextCtrl, addTextRaw, 1}}, - {3384, {wxStyledTextCtrl, insertTextRaw, 2}}, - {3385, {wxStyledTextCtrl, getCurLineRaw, 1}}, - {3386, {wxStyledTextCtrl, getLineRaw, 1}}, - {3387, {wxStyledTextCtrl, getSelectedTextRaw, 0}}, - {3388, {wxStyledTextCtrl, getTextRangeRaw, 2}}, - {3389, {wxStyledTextCtrl, setTextRaw, 1}}, - {3390, {wxStyledTextCtrl, getTextRaw, 0}}, - {3391, {wxStyledTextCtrl, appendTextRaw, 1}}, - {3392, {wxArtProvider, getBitmap, 2}}, - {3393, {wxArtProvider, getIcon, 2}}, - {3394, {wxTreeEvent, getKeyCode, 0}}, - {3395, {wxTreeEvent, getItem, 0}}, - {3396, {wxTreeEvent, getKeyEvent, 0}}, - {3397, {wxTreeEvent, getLabel, 0}}, - {3398, {wxTreeEvent, getOldItem, 0}}, - {3399, {wxTreeEvent, getPoint, 0}}, - {3400, {wxTreeEvent, isEditCancelled, 0}}, - {3401, {wxTreeEvent, setToolTip, 1}}, - {3402, {wxNotebookEvent, getOldSelection, 0}}, - {3403, {wxNotebookEvent, getSelection, 0}}, - {3404, {wxNotebookEvent, setOldSelection, 1}}, - {3405, {wxNotebookEvent, setSelection, 1}}, - {3406, {wxFileDataObject, new, 0}}, - {3407, {wxFileDataObject, addFile, 1}}, - {3408, {wxFileDataObject, getFilenames, 0}}, - {3409, {wxFileDataObject, 'Destroy', undefined}}, - {3410, {wxTextDataObject, new, 1}}, - {3411, {wxTextDataObject, getTextLength, 0}}, - {3412, {wxTextDataObject, getText, 0}}, - {3413, {wxTextDataObject, setText, 1}}, - {3414, {wxTextDataObject, 'Destroy', undefined}}, - {3415, {wxBitmapDataObject, new_1_1, 1}}, - {3416, {wxBitmapDataObject, new_1_0, 1}}, - {3417, {wxBitmapDataObject, getBitmap, 0}}, - {3418, {wxBitmapDataObject, setBitmap, 1}}, - {3419, {wxBitmapDataObject, 'Destroy', undefined}}, - {3421, {wxClipboard, new, 0}}, - {3422, {wxClipboard, destruct, 0}}, - {3423, {wxClipboard, addData, 1}}, - {3424, {wxClipboard, clear, 0}}, - {3425, {wxClipboard, close, 0}}, - {3426, {wxClipboard, flush, 0}}, - {3427, {wxClipboard, getData, 1}}, - {3428, {wxClipboard, isOpened, 0}}, - {3429, {wxClipboard, open, 0}}, - {3430, {wxClipboard, setData, 1}}, - {3432, {wxClipboard, usePrimarySelection, 1}}, - {3433, {wxClipboard, isSupported, 1}}, - {3434, {wxClipboard, get, 0}}, - {3435, {wxSpinEvent, getPosition, 0}}, - {3436, {wxSpinEvent, setPosition, 1}}, - {3437, {wxSplitterWindow, new_0, 0}}, - {3438, {wxSplitterWindow, new_2, 2}}, - {3439, {wxSplitterWindow, destruct, 0}}, - {3440, {wxSplitterWindow, create, 2}}, - {3441, {wxSplitterWindow, getMinimumPaneSize, 0}}, - {3442, {wxSplitterWindow, getSashGravity, 0}}, - {3443, {wxSplitterWindow, getSashPosition, 0}}, - {3444, {wxSplitterWindow, getSplitMode, 0}}, - {3445, {wxSplitterWindow, getWindow1, 0}}, - {3446, {wxSplitterWindow, getWindow2, 0}}, - {3447, {wxSplitterWindow, initialize, 1}}, - {3448, {wxSplitterWindow, isSplit, 0}}, - {3449, {wxSplitterWindow, replaceWindow, 2}}, - {3450, {wxSplitterWindow, setSashGravity, 1}}, - {3451, {wxSplitterWindow, setSashPosition, 2}}, - {3452, {wxSplitterWindow, setSashSize, 1}}, - {3453, {wxSplitterWindow, setMinimumPaneSize, 1}}, - {3454, {wxSplitterWindow, setSplitMode, 1}}, - {3455, {wxSplitterWindow, splitHorizontally, 3}}, - {3456, {wxSplitterWindow, splitVertically, 3}}, - {3457, {wxSplitterWindow, unsplit, 1}}, - {3458, {wxSplitterWindow, updateSize, 0}}, - {3459, {wxSplitterEvent, getSashPosition, 0}}, - {3460, {wxSplitterEvent, getX, 0}}, - {3461, {wxSplitterEvent, getY, 0}}, - {3462, {wxSplitterEvent, getWindowBeingRemoved, 0}}, - {3463, {wxSplitterEvent, setSashPosition, 1}}, - {3464, {wxHtmlWindow, new_0, 0}}, - {3465, {wxHtmlWindow, new_2, 2}}, - {3466, {wxHtmlWindow, appendToPage, 1}}, - {3467, {wxHtmlWindow, getOpenedAnchor, 0}}, - {3468, {wxHtmlWindow, getOpenedPage, 0}}, - {3469, {wxHtmlWindow, getOpenedPageTitle, 0}}, - {3470, {wxHtmlWindow, getRelatedFrame, 0}}, - {3471, {wxHtmlWindow, historyBack, 0}}, - {3472, {wxHtmlWindow, historyCanBack, 0}}, - {3473, {wxHtmlWindow, historyCanForward, 0}}, - {3474, {wxHtmlWindow, historyClear, 0}}, - {3475, {wxHtmlWindow, historyForward, 0}}, - {3476, {wxHtmlWindow, loadFile, 1}}, - {3477, {wxHtmlWindow, loadPage, 1}}, - {3478, {wxHtmlWindow, selectAll, 0}}, - {3479, {wxHtmlWindow, selectionToText, 0}}, - {3480, {wxHtmlWindow, selectLine, 1}}, - {3481, {wxHtmlWindow, selectWord, 1}}, - {3482, {wxHtmlWindow, setBorders, 1}}, - {3483, {wxHtmlWindow, setFonts, 3}}, - {3484, {wxHtmlWindow, setPage, 1}}, - {3485, {wxHtmlWindow, setRelatedFrame, 2}}, - {3486, {wxHtmlWindow, setRelatedStatusBar, 1}}, - {3487, {wxHtmlWindow, toText, 0}}, - {3488, {wxHtmlWindow, 'Destroy', undefined}}, - {3489, {wxHtmlLinkEvent, getLinkInfo, 0}}, - {3490, {wxSystemSettings, getColour, 1}}, - {3491, {wxSystemSettings, getFont, 1}}, - {3492, {wxSystemSettings, getMetric, 2}}, - {3493, {wxSystemSettings, getScreenType, 0}}, - {3494, {wxSystemOptions, getOption, 1}}, - {3495, {wxSystemOptions, getOptionInt, 1}}, - {3496, {wxSystemOptions, hasOption, 1}}, - {3497, {wxSystemOptions, isFalse, 1}}, - {3498, {wxSystemOptions, setOption_2_1, 2}}, - {3499, {wxSystemOptions, setOption_2_0, 2}}, - {3500, {wxAuiNotebookEvent, setSelection, 1}}, - {3501, {wxAuiNotebookEvent, getSelection, 0}}, - {3502, {wxAuiNotebookEvent, setOldSelection, 1}}, - {3503, {wxAuiNotebookEvent, getOldSelection, 0}}, - {3504, {wxAuiNotebookEvent, setDragSource, 1}}, - {3505, {wxAuiNotebookEvent, getDragSource, 0}}, - {3506, {wxAuiManagerEvent, setManager, 1}}, - {3507, {wxAuiManagerEvent, getManager, 0}}, - {3508, {wxAuiManagerEvent, setPane, 1}}, - {3509, {wxAuiManagerEvent, getPane, 0}}, - {3510, {wxAuiManagerEvent, setButton, 1}}, - {3511, {wxAuiManagerEvent, getButton, 0}}, - {3512, {wxAuiManagerEvent, setDC, 1}}, - {3513, {wxAuiManagerEvent, getDC, 0}}, - {3514, {wxAuiManagerEvent, veto, 1}}, - {3515, {wxAuiManagerEvent, getVeto, 0}}, - {3516, {wxAuiManagerEvent, setCanVeto, 1}}, - {3517, {wxAuiManagerEvent, canVeto, 0}}, - {3518, {wxLogNull, new, 0}}, - {3519, {wxLogNull, 'Destroy', undefined}}, - {3520, {wxTaskBarIcon, new, 0}}, - {3521, {wxTaskBarIcon, destruct, 0}}, - {3522, {wxTaskBarIcon, popupMenu, 1}}, - {3523, {wxTaskBarIcon, removeIcon, 0}}, - {3524, {wxTaskBarIcon, setIcon, 2}}, + {337, {wxPanel, setFocusIgnoringChildren, 0}}, + {338, {wxScrolledWindow, new_0, 0}}, + {339, {wxScrolledWindow, new_2, 2}}, + {340, {wxScrolledWindow, destruct, 0}}, + {341, {wxScrolledWindow, calcScrolledPosition_4, 4}}, + {342, {wxScrolledWindow, calcScrolledPosition_1, 1}}, + {343, {wxScrolledWindow, calcUnscrolledPosition_4, 4}}, + {344, {wxScrolledWindow, calcUnscrolledPosition_1, 1}}, + {345, {wxScrolledWindow, enableScrolling, 2}}, + {346, {wxScrolledWindow, getScrollPixelsPerUnit, 2}}, + {347, {wxScrolledWindow, getViewStart, 2}}, + {348, {wxScrolledWindow, doPrepareDC, 1}}, + {349, {wxScrolledWindow, prepareDC, 1}}, + {350, {wxScrolledWindow, scroll, 2}}, + {351, {wxScrolledWindow, setScrollbars, 5}}, + {352, {wxScrolledWindow, setScrollRate, 2}}, + {353, {wxScrolledWindow, setTargetWindow, 1}}, + {354, {wxSashWindow, new_0, 0}}, + {355, {wxSashWindow, new_2, 2}}, + {356, {wxSashWindow, destruct, 0}}, + {357, {wxSashWindow, getSashVisible, 1}}, + {358, {wxSashWindow, getMaximumSizeX, 0}}, + {359, {wxSashWindow, getMaximumSizeY, 0}}, + {360, {wxSashWindow, getMinimumSizeX, 0}}, + {361, {wxSashWindow, getMinimumSizeY, 0}}, + {362, {wxSashWindow, setMaximumSizeX, 1}}, + {363, {wxSashWindow, setMaximumSizeY, 1}}, + {364, {wxSashWindow, setMinimumSizeX, 1}}, + {365, {wxSashWindow, setMinimumSizeY, 1}}, + {366, {wxSashWindow, setSashVisible, 2}}, + {367, {wxSashLayoutWindow, new_0, 0}}, + {368, {wxSashLayoutWindow, new_2, 2}}, + {369, {wxSashLayoutWindow, create, 2}}, + {370, {wxSashLayoutWindow, getAlignment, 0}}, + {371, {wxSashLayoutWindow, getOrientation, 0}}, + {372, {wxSashLayoutWindow, setAlignment, 1}}, + {373, {wxSashLayoutWindow, setDefaultSize, 1}}, + {374, {wxSashLayoutWindow, setOrientation, 1}}, + {375, {wxSashLayoutWindow, 'Destroy', undefined}}, + {376, {wxGrid, new_0, 0}}, + {377, {wxGrid, new_3, 3}}, + {378, {wxGrid, new_4, 4}}, + {379, {wxGrid, destruct, 0}}, + {380, {wxGrid, appendCols, 1}}, + {381, {wxGrid, appendRows, 1}}, + {382, {wxGrid, autoSize, 0}}, + {383, {wxGrid, autoSizeColumn, 2}}, + {384, {wxGrid, autoSizeColumns, 1}}, + {385, {wxGrid, autoSizeRow, 2}}, + {386, {wxGrid, autoSizeRows, 1}}, + {387, {wxGrid, beginBatch, 0}}, + {388, {wxGrid, blockToDeviceRect, 2}}, + {389, {wxGrid, canDragColSize, 0}}, + {390, {wxGrid, canDragRowSize, 0}}, + {391, {wxGrid, canDragGridSize, 0}}, + {392, {wxGrid, canEnableCellControl, 0}}, + {393, {wxGrid, cellToRect_2, 2}}, + {394, {wxGrid, cellToRect_1, 1}}, + {395, {wxGrid, clearGrid, 0}}, + {396, {wxGrid, clearSelection, 0}}, + {397, {wxGrid, createGrid, 3}}, + {398, {wxGrid, deleteCols, 1}}, + {399, {wxGrid, deleteRows, 1}}, + {400, {wxGrid, disableCellEditControl, 0}}, + {401, {wxGrid, disableDragColSize, 0}}, + {402, {wxGrid, disableDragGridSize, 0}}, + {403, {wxGrid, disableDragRowSize, 0}}, + {404, {wxGrid, enableCellEditControl, 1}}, + {405, {wxGrid, enableDragColSize, 1}}, + {406, {wxGrid, enableDragGridSize, 1}}, + {407, {wxGrid, enableDragRowSize, 1}}, + {408, {wxGrid, enableEditing, 1}}, + {409, {wxGrid, enableGridLines, 1}}, + {410, {wxGrid, endBatch, 0}}, + {411, {wxGrid, fit, 0}}, + {412, {wxGrid, forceRefresh, 0}}, + {413, {wxGrid, getBatchCount, 0}}, + {414, {wxGrid, getCellAlignment, 4}}, + {415, {wxGrid, getCellBackgroundColour, 2}}, + {416, {wxGrid, getCellEditor, 2}}, + {417, {wxGrid, getCellFont, 2}}, + {418, {wxGrid, getCellRenderer, 2}}, + {419, {wxGrid, getCellTextColour, 2}}, + {420, {wxGrid, getCellValue_2, 2}}, + {421, {wxGrid, getCellValue_1, 1}}, + {422, {wxGrid, getColLabelAlignment, 2}}, + {423, {wxGrid, getColLabelSize, 0}}, + {424, {wxGrid, getColLabelValue, 1}}, + {425, {wxGrid, getColMinimalAcceptableWidth, 0}}, + {426, {wxGrid, getDefaultCellAlignment, 2}}, + {427, {wxGrid, getDefaultCellBackgroundColour, 0}}, + {428, {wxGrid, getDefaultCellFont, 0}}, + {429, {wxGrid, getDefaultCellTextColour, 0}}, + {430, {wxGrid, getDefaultColLabelSize, 0}}, + {431, {wxGrid, getDefaultColSize, 0}}, + {432, {wxGrid, getDefaultEditor, 0}}, + {433, {wxGrid, getDefaultEditorForCell_2, 2}}, + {434, {wxGrid, getDefaultEditorForCell_1, 1}}, + {435, {wxGrid, getDefaultEditorForType, 1}}, + {436, {wxGrid, getDefaultRenderer, 0}}, + {437, {wxGrid, getDefaultRendererForCell, 2}}, + {438, {wxGrid, getDefaultRendererForType, 1}}, + {439, {wxGrid, getDefaultRowLabelSize, 0}}, + {440, {wxGrid, getDefaultRowSize, 0}}, + {441, {wxGrid, getGridCursorCol, 0}}, + {442, {wxGrid, getGridCursorRow, 0}}, + {443, {wxGrid, getGridLineColour, 0}}, + {444, {wxGrid, gridLinesEnabled, 0}}, + {445, {wxGrid, getLabelBackgroundColour, 0}}, + {446, {wxGrid, getLabelFont, 0}}, + {447, {wxGrid, getLabelTextColour, 0}}, + {448, {wxGrid, getNumberCols, 0}}, + {449, {wxGrid, getNumberRows, 0}}, + {450, {wxGrid, getOrCreateCellAttr, 2}}, + {451, {wxGrid, getRowMinimalAcceptableHeight, 0}}, + {452, {wxGrid, getRowLabelAlignment, 2}}, + {453, {wxGrid, getRowLabelSize, 0}}, + {454, {wxGrid, getRowLabelValue, 1}}, + {455, {wxGrid, getRowSize, 1}}, + {456, {wxGrid, getScrollLineX, 0}}, + {457, {wxGrid, getScrollLineY, 0}}, + {458, {wxGrid, getSelectedCells, 0}}, + {459, {wxGrid, getSelectedCols, 0}}, + {460, {wxGrid, getSelectedRows, 0}}, + {461, {wxGrid, getSelectionBackground, 0}}, + {462, {wxGrid, getSelectionBlockTopLeft, 0}}, + {463, {wxGrid, getSelectionBlockBottomRight, 0}}, + {464, {wxGrid, getSelectionForeground, 0}}, + {465, {wxGrid, getViewWidth, 0}}, + {466, {wxGrid, getGridWindow, 0}}, + {467, {wxGrid, getGridRowLabelWindow, 0}}, + {468, {wxGrid, getGridColLabelWindow, 0}}, + {469, {wxGrid, getGridCornerLabelWindow, 0}}, + {470, {wxGrid, hideCellEditControl, 0}}, + {471, {wxGrid, insertCols, 1}}, + {472, {wxGrid, insertRows, 1}}, + {473, {wxGrid, isCellEditControlEnabled, 0}}, + {474, {wxGrid, isCurrentCellReadOnly, 0}}, + {475, {wxGrid, isEditable, 0}}, + {476, {wxGrid, isInSelection_2, 2}}, + {477, {wxGrid, isInSelection_1, 1}}, + {478, {wxGrid, isReadOnly, 2}}, + {479, {wxGrid, isSelection, 0}}, + {480, {wxGrid, isVisible_3, 3}}, + {481, {wxGrid, isVisible_2, 2}}, + {482, {wxGrid, makeCellVisible_2, 2}}, + {483, {wxGrid, makeCellVisible_1, 1}}, + {484, {wxGrid, moveCursorDown, 1}}, + {485, {wxGrid, moveCursorLeft, 1}}, + {486, {wxGrid, moveCursorRight, 1}}, + {487, {wxGrid, moveCursorUp, 1}}, + {488, {wxGrid, moveCursorDownBlock, 1}}, + {489, {wxGrid, moveCursorLeftBlock, 1}}, + {490, {wxGrid, moveCursorRightBlock, 1}}, + {491, {wxGrid, moveCursorUpBlock, 1}}, + {492, {wxGrid, movePageDown, 0}}, + {493, {wxGrid, movePageUp, 0}}, + {494, {wxGrid, registerDataType, 3}}, + {495, {wxGrid, saveEditControlValue, 0}}, + {496, {wxGrid, selectAll, 0}}, + {497, {wxGrid, selectBlock_5, 5}}, + {498, {wxGrid, selectBlock_3, 3}}, + {499, {wxGrid, selectCol, 2}}, + {500, {wxGrid, selectRow, 2}}, + {501, {wxGrid, setCellAlignment_4, 4}}, + {502, {wxGrid, setCellAlignment_3, 3}}, + {503, {wxGrid, setCellAlignment_1, 1}}, + {504, {wxGrid, setCellBackgroundColour_3_0, 3}}, + {505, {wxGrid, setCellBackgroundColour_1, 1}}, + {506, {wxGrid, setCellBackgroundColour_3_1, 3}}, + {507, {wxGrid, setCellEditor, 3}}, + {508, {wxGrid, setCellFont, 3}}, + {509, {wxGrid, setCellRenderer, 3}}, + {510, {wxGrid, setCellTextColour_3_0, 3}}, + {511, {wxGrid, setCellTextColour_3_1, 3}}, + {512, {wxGrid, setCellTextColour_1, 1}}, + {513, {wxGrid, setCellValue_3_0, 3}}, + {514, {wxGrid, setCellValue_2, 2}}, + {515, {wxGrid, setCellValue_3_1, 3}}, + {516, {wxGrid, setColAttr, 2}}, + {517, {wxGrid, setColFormatBool, 1}}, + {518, {wxGrid, setColFormatNumber, 1}}, + {519, {wxGrid, setColFormatFloat, 2}}, + {520, {wxGrid, setColFormatCustom, 2}}, + {521, {wxGrid, setColLabelAlignment, 2}}, + {522, {wxGrid, setColLabelSize, 1}}, + {523, {wxGrid, setColLabelValue, 2}}, + {524, {wxGrid, setColMinimalWidth, 2}}, + {525, {wxGrid, setColMinimalAcceptableWidth, 1}}, + {526, {wxGrid, setColSize, 2}}, + {527, {wxGrid, setDefaultCellAlignment, 2}}, + {528, {wxGrid, setDefaultCellBackgroundColour, 1}}, + {529, {wxGrid, setDefaultCellFont, 1}}, + {530, {wxGrid, setDefaultCellTextColour, 1}}, + {531, {wxGrid, setDefaultEditor, 1}}, + {532, {wxGrid, setDefaultRenderer, 1}}, + {533, {wxGrid, setDefaultColSize, 2}}, + {534, {wxGrid, setDefaultRowSize, 2}}, + {535, {wxGrid, setGridCursor, 2}}, + {536, {wxGrid, setGridLineColour, 1}}, + {537, {wxGrid, setLabelBackgroundColour, 1}}, + {538, {wxGrid, setLabelFont, 1}}, + {539, {wxGrid, setLabelTextColour, 1}}, + {540, {wxGrid, setMargins, 2}}, + {541, {wxGrid, setReadOnly, 3}}, + {542, {wxGrid, setRowAttr, 2}}, + {543, {wxGrid, setRowLabelAlignment, 2}}, + {544, {wxGrid, setRowLabelSize, 1}}, + {545, {wxGrid, setRowLabelValue, 2}}, + {546, {wxGrid, setRowMinimalHeight, 2}}, + {547, {wxGrid, setRowMinimalAcceptableHeight, 1}}, + {548, {wxGrid, setRowSize, 2}}, + {549, {wxGrid, setScrollLineX, 1}}, + {550, {wxGrid, setScrollLineY, 1}}, + {551, {wxGrid, setSelectionBackground, 1}}, + {552, {wxGrid, setSelectionForeground, 1}}, + {553, {wxGrid, setSelectionMode, 1}}, + {554, {wxGrid, showCellEditControl, 0}}, + {555, {wxGrid, xToCol, 2}}, + {556, {wxGrid, xToEdgeOfCol, 1}}, + {557, {wxGrid, yToEdgeOfRow, 1}}, + {558, {wxGrid, yToRow, 1}}, + {559, {wxGridCellRenderer, draw, 7}}, + {560, {wxGridCellRenderer, getBestSize, 5}}, + {561, {wxGridCellEditor, create, 3}}, + {562, {wxGridCellEditor, isCreated, 0}}, + {563, {wxGridCellEditor, setSize, 1}}, + {564, {wxGridCellEditor, show, 2}}, + {565, {wxGridCellEditor, paintBackground, 2}}, + {566, {wxGridCellEditor, beginEdit, 3}}, + {567, {wxGridCellEditor, endEdit, 3}}, + {568, {wxGridCellEditor, reset, 0}}, + {569, {wxGridCellEditor, startingKey, 1}}, + {570, {wxGridCellEditor, startingClick, 0}}, + {571, {wxGridCellEditor, handleReturn, 1}}, + {572, {wxGridCellBoolRenderer, new, 0}}, + {573, {wxGridCellBoolRenderer, 'Destroy', undefined}}, + {574, {wxGridCellBoolEditor, new, 0}}, + {575, {wxGridCellBoolEditor, isTrueValue, 1}}, + {576, {wxGridCellBoolEditor, useStringValues, 1}}, + {577, {wxGridCellBoolEditor, 'Destroy', undefined}}, + {578, {wxGridCellFloatRenderer, new, 1}}, + {579, {wxGridCellFloatRenderer, getPrecision, 0}}, + {580, {wxGridCellFloatRenderer, getWidth, 0}}, + {581, {wxGridCellFloatRenderer, setParameters, 1}}, + {582, {wxGridCellFloatRenderer, setPrecision, 1}}, + {583, {wxGridCellFloatRenderer, setWidth, 1}}, + {584, {wxGridCellFloatRenderer, 'Destroy', undefined}}, + {585, {wxGridCellFloatEditor, new, 1}}, + {586, {wxGridCellFloatEditor, setParameters, 1}}, + {587, {wxGridCellFloatEditor, 'Destroy', undefined}}, + {588, {wxGridCellStringRenderer, new, 0}}, + {589, {wxGridCellStringRenderer, 'Destroy', undefined}}, + {590, {wxGridCellTextEditor, new, 0}}, + {591, {wxGridCellTextEditor, setParameters, 1}}, + {592, {wxGridCellTextEditor, 'Destroy', undefined}}, + {594, {wxGridCellChoiceEditor, new, 2}}, + {595, {wxGridCellChoiceEditor, setParameters, 1}}, + {596, {wxGridCellChoiceEditor, 'Destroy', undefined}}, + {597, {wxGridCellNumberRenderer, new, 0}}, + {598, {wxGridCellNumberRenderer, 'Destroy', undefined}}, + {599, {wxGridCellNumberEditor, new, 1}}, + {600, {wxGridCellNumberEditor, getValue, 0}}, + {601, {wxGridCellNumberEditor, setParameters, 1}}, + {602, {wxGridCellNumberEditor, 'Destroy', undefined}}, + {603, {wxGridCellAttr, setTextColour, 1}}, + {604, {wxGridCellAttr, setBackgroundColour, 1}}, + {605, {wxGridCellAttr, setFont, 1}}, + {606, {wxGridCellAttr, setAlignment, 2}}, + {607, {wxGridCellAttr, setReadOnly, 1}}, + {608, {wxGridCellAttr, setRenderer, 1}}, + {609, {wxGridCellAttr, setEditor, 1}}, + {610, {wxGridCellAttr, hasTextColour, 0}}, + {611, {wxGridCellAttr, hasBackgroundColour, 0}}, + {612, {wxGridCellAttr, hasFont, 0}}, + {613, {wxGridCellAttr, hasAlignment, 0}}, + {614, {wxGridCellAttr, hasRenderer, 0}}, + {615, {wxGridCellAttr, hasEditor, 0}}, + {616, {wxGridCellAttr, getTextColour, 0}}, + {617, {wxGridCellAttr, getBackgroundColour, 0}}, + {618, {wxGridCellAttr, getFont, 0}}, + {619, {wxGridCellAttr, getAlignment, 2}}, + {620, {wxGridCellAttr, getRenderer, 3}}, + {621, {wxGridCellAttr, getEditor, 3}}, + {622, {wxGridCellAttr, isReadOnly, 0}}, + {623, {wxGridCellAttr, setDefAttr, 1}}, + {624, {wxDC, blit, 5}}, + {625, {wxDC, calcBoundingBox, 2}}, + {626, {wxDC, clear, 0}}, + {627, {wxDC, computeScaleAndOrigin, 0}}, + {628, {wxDC, crossHair, 1}}, + {629, {wxDC, destroyClippingRegion, 0}}, + {630, {wxDC, deviceToLogicalX, 1}}, + {631, {wxDC, deviceToLogicalXRel, 1}}, + {632, {wxDC, deviceToLogicalY, 1}}, + {633, {wxDC, deviceToLogicalYRel, 1}}, + {634, {wxDC, drawArc, 3}}, + {635, {wxDC, drawBitmap, 3}}, + {636, {wxDC, drawCheckMark, 1}}, + {637, {wxDC, drawCircle, 2}}, + {639, {wxDC, drawEllipse_2, 2}}, + {640, {wxDC, drawEllipse_1, 1}}, + {641, {wxDC, drawEllipticArc, 4}}, + {642, {wxDC, drawIcon, 2}}, + {643, {wxDC, drawLabel, 3}}, + {644, {wxDC, drawLine, 2}}, + {645, {wxDC, drawLines, 3}}, + {647, {wxDC, drawPolygon, 3}}, + {649, {wxDC, drawPoint, 1}}, + {651, {wxDC, drawRectangle_2, 2}}, + {652, {wxDC, drawRectangle_1, 1}}, + {653, {wxDC, drawRotatedText, 3}}, + {655, {wxDC, drawRoundedRectangle_3, 3}}, + {656, {wxDC, drawRoundedRectangle_2, 2}}, + {657, {wxDC, drawText, 2}}, + {658, {wxDC, endDoc, 0}}, + {659, {wxDC, endPage, 0}}, + {660, {wxDC, floodFill, 3}}, + {661, {wxDC, getBackground, 0}}, + {662, {wxDC, getBackgroundMode, 0}}, + {663, {wxDC, getBrush, 0}}, + {664, {wxDC, getCharHeight, 0}}, + {665, {wxDC, getCharWidth, 0}}, + {666, {wxDC, getClippingBox, 4}}, + {668, {wxDC, getFont, 0}}, + {669, {wxDC, getLayoutDirection, 0}}, + {670, {wxDC, getLogicalFunction, 0}}, + {671, {wxDC, getMapMode, 0}}, + {672, {wxDC, getMultiLineTextExtent_4, 4}}, + {673, {wxDC, getMultiLineTextExtent_1, 1}}, + {674, {wxDC, getPartialTextExtents, 2}}, + {675, {wxDC, getPen, 0}}, + {676, {wxDC, getPixel, 2}}, + {677, {wxDC, getPPI, 0}}, + {679, {wxDC, getSize, 0}}, + {681, {wxDC, getSizeMM, 0}}, + {682, {wxDC, getTextBackground, 0}}, + {683, {wxDC, getTextExtent_4, 4}}, + {684, {wxDC, getTextExtent_1, 1}}, + {686, {wxDC, getTextForeground, 0}}, + {687, {wxDC, getUserScale, 2}}, + {688, {wxDC, gradientFillConcentric_3, 3}}, + {689, {wxDC, gradientFillConcentric_4, 4}}, + {690, {wxDC, gradientFillLinear, 4}}, + {691, {wxDC, logicalToDeviceX, 1}}, + {692, {wxDC, logicalToDeviceXRel, 1}}, + {693, {wxDC, logicalToDeviceY, 1}}, + {694, {wxDC, logicalToDeviceYRel, 1}}, + {695, {wxDC, maxX, 0}}, + {696, {wxDC, maxY, 0}}, + {697, {wxDC, minX, 0}}, + {698, {wxDC, minY, 0}}, + {699, {wxDC, isOk, 0}}, + {700, {wxDC, resetBoundingBox, 0}}, + {701, {wxDC, setAxisOrientation, 2}}, + {702, {wxDC, setBackground, 1}}, + {703, {wxDC, setBackgroundMode, 1}}, + {704, {wxDC, setBrush, 1}}, + {706, {wxDC, setClippingRegion_2, 2}}, + {707, {wxDC, setClippingRegion_1_1, 1}}, + {708, {wxDC, setClippingRegion_1_0, 1}}, + {709, {wxDC, setDeviceOrigin, 2}}, + {710, {wxDC, setFont, 1}}, + {711, {wxDC, setLayoutDirection, 1}}, + {712, {wxDC, setLogicalFunction, 1}}, + {713, {wxDC, setMapMode, 1}}, + {714, {wxDC, setPalette, 1}}, + {715, {wxDC, setPen, 1}}, + {716, {wxDC, setTextBackground, 1}}, + {717, {wxDC, setTextForeground, 1}}, + {718, {wxDC, setUserScale, 2}}, + {719, {wxDC, startDoc, 1}}, + {720, {wxDC, startPage, 0}}, + {721, {wxMirrorDC, new, 2}}, + {722, {wxMirrorDC, 'Destroy', undefined}}, + {723, {wxScreenDC, new, 0}}, + {724, {wxScreenDC, destruct, 0}}, + {725, {wxPostScriptDC, new_0, 0}}, + {726, {wxPostScriptDC, new_1, 1}}, + {727, {wxPostScriptDC, destruct, 0}}, + {728, {wxPostScriptDC, setResolution, 1}}, + {729, {wxPostScriptDC, getResolution, 0}}, + {730, {wxWindowDC, new_0, 0}}, + {731, {wxWindowDC, new_1, 1}}, + {732, {wxWindowDC, destruct, 0}}, + {733, {wxClientDC, new_0, 0}}, + {734, {wxClientDC, new_1, 1}}, + {735, {wxClientDC, 'Destroy', undefined}}, + {736, {wxPaintDC, new_0, 0}}, + {737, {wxPaintDC, new_1, 1}}, + {738, {wxPaintDC, 'Destroy', undefined}}, + {740, {wxMemoryDC, new_1_0, 1}}, + {741, {wxMemoryDC, new_1_1, 1}}, + {742, {wxMemoryDC, new_0, 0}}, + {744, {wxMemoryDC, destruct, 0}}, + {745, {wxMemoryDC, selectObject, 1}}, + {746, {wxMemoryDC, selectObjectAsSource, 1}}, + {747, {wxBufferedDC, new_0, 0}}, + {748, {wxBufferedDC, new_2, 2}}, + {749, {wxBufferedDC, new_3, 3}}, + {750, {wxBufferedDC, destruct, 0}}, + {751, {wxBufferedDC, init_2, 2}}, + {752, {wxBufferedDC, init_3, 3}}, + {753, {wxBufferedPaintDC, new_3, 3}}, + {754, {wxBufferedPaintDC, new_2, 2}}, + {755, {wxBufferedPaintDC, destruct, 0}}, + {756, {wxGraphicsObject, destruct, 0}}, + {757, {wxGraphicsObject, getRenderer, 0}}, + {758, {wxGraphicsObject, isNull, 0}}, + {759, {wxGraphicsContext, destruct, 0}}, + {760, {wxGraphicsContext, create_1_1, 1}}, + {761, {wxGraphicsContext, create_1_0, 1}}, + {762, {wxGraphicsContext, create_0, 0}}, + {763, {wxGraphicsContext, createPen, 1}}, + {764, {wxGraphicsContext, createBrush, 1}}, + {765, {wxGraphicsContext, createRadialGradientBrush, 7}}, + {766, {wxGraphicsContext, createLinearGradientBrush, 6}}, + {767, {wxGraphicsContext, createFont, 2}}, + {768, {wxGraphicsContext, createMatrix, 1}}, + {769, {wxGraphicsContext, createPath, 0}}, + {770, {wxGraphicsContext, clip_1, 1}}, + {771, {wxGraphicsContext, clip_4, 4}}, + {772, {wxGraphicsContext, resetClip, 0}}, + {773, {wxGraphicsContext, drawBitmap, 5}}, + {774, {wxGraphicsContext, drawEllipse, 4}}, + {775, {wxGraphicsContext, drawIcon, 5}}, + {776, {wxGraphicsContext, drawLines, 3}}, + {777, {wxGraphicsContext, drawPath, 2}}, + {778, {wxGraphicsContext, drawRectangle, 4}}, + {779, {wxGraphicsContext, drawRoundedRectangle, 5}}, + {780, {wxGraphicsContext, drawText_3, 3}}, + {781, {wxGraphicsContext, drawText_4_0, 4}}, + {782, {wxGraphicsContext, drawText_4_1, 4}}, + {783, {wxGraphicsContext, drawText_5, 5}}, + {784, {wxGraphicsContext, fillPath, 2}}, + {785, {wxGraphicsContext, strokePath, 1}}, + {786, {wxGraphicsContext, getPartialTextExtents, 2}}, + {787, {wxGraphicsContext, getTextExtent, 5}}, + {788, {wxGraphicsContext, rotate, 1}}, + {789, {wxGraphicsContext, scale, 2}}, + {790, {wxGraphicsContext, translate, 2}}, + {791, {wxGraphicsContext, getTransform, 0}}, + {792, {wxGraphicsContext, setTransform, 1}}, + {793, {wxGraphicsContext, concatTransform, 1}}, + {794, {wxGraphicsContext, setBrush_1_1, 1}}, + {795, {wxGraphicsContext, setBrush_1_0, 1}}, + {796, {wxGraphicsContext, setFont_1, 1}}, + {797, {wxGraphicsContext, setFont_2, 2}}, + {798, {wxGraphicsContext, setPen_1_0, 1}}, + {799, {wxGraphicsContext, setPen_1_1, 1}}, + {800, {wxGraphicsContext, strokeLine, 4}}, + {801, {wxGraphicsContext, strokeLines, 2}}, + {803, {wxGraphicsMatrix, concat, 1}}, + {805, {wxGraphicsMatrix, get, 1}}, + {806, {wxGraphicsMatrix, invert, 0}}, + {807, {wxGraphicsMatrix, isEqual, 1}}, + {809, {wxGraphicsMatrix, isIdentity, 0}}, + {810, {wxGraphicsMatrix, rotate, 1}}, + {811, {wxGraphicsMatrix, scale, 2}}, + {812, {wxGraphicsMatrix, translate, 2}}, + {813, {wxGraphicsMatrix, set, 1}}, + {814, {wxGraphicsMatrix, transformPoint, 2}}, + {815, {wxGraphicsMatrix, transformDistance, 2}}, + {816, {wxGraphicsPath, moveToPoint_2, 2}}, + {817, {wxGraphicsPath, moveToPoint_1, 1}}, + {818, {wxGraphicsPath, addArc_6, 6}}, + {819, {wxGraphicsPath, addArc_5, 5}}, + {820, {wxGraphicsPath, addArcToPoint, 5}}, + {821, {wxGraphicsPath, addCircle, 3}}, + {822, {wxGraphicsPath, addCurveToPoint_6, 6}}, + {823, {wxGraphicsPath, addCurveToPoint_3, 3}}, + {824, {wxGraphicsPath, addEllipse, 4}}, + {825, {wxGraphicsPath, addLineToPoint_2, 2}}, + {826, {wxGraphicsPath, addLineToPoint_1, 1}}, + {827, {wxGraphicsPath, addPath, 1}}, + {828, {wxGraphicsPath, addQuadCurveToPoint, 4}}, + {829, {wxGraphicsPath, addRectangle, 4}}, + {830, {wxGraphicsPath, addRoundedRectangle, 5}}, + {831, {wxGraphicsPath, closeSubpath, 0}}, + {832, {wxGraphicsPath, contains_3, 3}}, + {833, {wxGraphicsPath, contains_2, 2}}, + {835, {wxGraphicsPath, getBox, 0}}, + {837, {wxGraphicsPath, getCurrentPoint, 0}}, + {838, {wxGraphicsPath, transform, 1}}, + {839, {wxGraphicsRenderer, getDefaultRenderer, 0}}, + {840, {wxGraphicsRenderer, createContext_1_1, 1}}, + {841, {wxGraphicsRenderer, createContext_1_0, 1}}, + {842, {wxGraphicsRenderer, createPen, 1}}, + {843, {wxGraphicsRenderer, createBrush, 1}}, + {844, {wxGraphicsRenderer, createLinearGradientBrush, 6}}, + {845, {wxGraphicsRenderer, createRadialGradientBrush, 7}}, + {846, {wxGraphicsRenderer, createFont, 2}}, + {847, {wxGraphicsRenderer, createMatrix, 1}}, + {848, {wxGraphicsRenderer, createPath, 0}}, + {850, {wxMenuBar, new_1, 1}}, + {852, {wxMenuBar, new_0, 0}}, + {854, {wxMenuBar, destruct, 0}}, + {855, {wxMenuBar, append, 2}}, + {856, {wxMenuBar, check, 2}}, + {857, {wxMenuBar, enable_2, 2}}, + {858, {wxMenuBar, enable_1, 1}}, + {859, {wxMenuBar, enableTop, 2}}, + {860, {wxMenuBar, findMenu, 1}}, + {861, {wxMenuBar, findMenuItem, 2}}, + {862, {wxMenuBar, findItem, 2}}, + {863, {wxMenuBar, getHelpString, 1}}, + {864, {wxMenuBar, getLabel_1, 1}}, + {865, {wxMenuBar, getLabel_0, 0}}, + {866, {wxMenuBar, getLabelTop, 1}}, + {867, {wxMenuBar, getMenu, 1}}, + {868, {wxMenuBar, getMenuCount, 0}}, + {869, {wxMenuBar, insert, 3}}, + {870, {wxMenuBar, isChecked, 1}}, + {871, {wxMenuBar, isEnabled_1, 1}}, + {872, {wxMenuBar, isEnabled_0, 0}}, + {873, {wxMenuBar, remove, 1}}, + {874, {wxMenuBar, replace, 3}}, + {875, {wxMenuBar, setHelpString, 2}}, + {876, {wxMenuBar, setLabel_2, 2}}, + {877, {wxMenuBar, setLabel_1, 1}}, + {878, {wxMenuBar, setLabelTop, 2}}, + {879, {wxControl, getLabel, 0}}, + {880, {wxControl, setLabel, 1}}, + {881, {wxControlWithItems, append_1, 1}}, + {882, {wxControlWithItems, append_2, 2}}, + {883, {wxControlWithItems, appendStrings_1, 1}}, + {884, {wxControlWithItems, clear, 0}}, + {885, {wxControlWithItems, delete, 1}}, + {886, {wxControlWithItems, findString, 2}}, + {887, {wxControlWithItems, getClientData, 1}}, + {888, {wxControlWithItems, setClientData, 2}}, + {889, {wxControlWithItems, getCount, 0}}, + {890, {wxControlWithItems, getSelection, 0}}, + {891, {wxControlWithItems, getString, 1}}, + {892, {wxControlWithItems, getStringSelection, 0}}, + {893, {wxControlWithItems, insert_2, 2}}, + {894, {wxControlWithItems, insert_3, 3}}, + {895, {wxControlWithItems, isEmpty, 0}}, + {896, {wxControlWithItems, select, 1}}, + {897, {wxControlWithItems, setSelection, 1}}, + {898, {wxControlWithItems, setString, 2}}, + {899, {wxControlWithItems, setStringSelection, 1}}, + {902, {wxMenu, new_2, 2}}, + {903, {wxMenu, new_1, 1}}, + {905, {wxMenu, destruct, 0}}, + {906, {wxMenu, append_3, 3}}, + {907, {wxMenu, append_1, 1}}, + {908, {wxMenu, append_4_0, 4}}, + {909, {wxMenu, append_4_1, 4}}, + {910, {wxMenu, appendCheckItem, 3}}, + {911, {wxMenu, appendRadioItem, 3}}, + {912, {wxMenu, appendSeparator, 0}}, + {913, {wxMenu, break, 0}}, + {914, {wxMenu, check, 2}}, + {915, {wxMenu, delete_1_0, 1}}, + {916, {wxMenu, delete_1_1, 1}}, + {917, {wxMenu, destroy_1_0, 1}}, + {918, {wxMenu, destroy_1_1, 1}}, + {919, {wxMenu, enable, 2}}, + {920, {wxMenu, findItem_1, 1}}, + {921, {wxMenu, findItem_2, 2}}, + {922, {wxMenu, findItemByPosition, 1}}, + {923, {wxMenu, getHelpString, 1}}, + {924, {wxMenu, getLabel, 1}}, + {925, {wxMenu, getMenuItemCount, 0}}, + {926, {wxMenu, getMenuItems, 0}}, + {928, {wxMenu, getTitle, 0}}, + {929, {wxMenu, insert_2, 2}}, + {930, {wxMenu, insert_3, 3}}, + {931, {wxMenu, insert_5_1, 5}}, + {932, {wxMenu, insert_5_0, 5}}, + {933, {wxMenu, insertCheckItem, 4}}, + {934, {wxMenu, insertRadioItem, 4}}, + {935, {wxMenu, insertSeparator, 1}}, + {936, {wxMenu, isChecked, 1}}, + {937, {wxMenu, isEnabled, 1}}, + {938, {wxMenu, prepend_1, 1}}, + {939, {wxMenu, prepend_2, 2}}, + {940, {wxMenu, prepend_4_1, 4}}, + {941, {wxMenu, prepend_4_0, 4}}, + {942, {wxMenu, prependCheckItem, 3}}, + {943, {wxMenu, prependRadioItem, 3}}, + {944, {wxMenu, prependSeparator, 0}}, + {945, {wxMenu, remove_1_0, 1}}, + {946, {wxMenu, remove_1_1, 1}}, + {947, {wxMenu, setHelpString, 2}}, + {948, {wxMenu, setLabel, 2}}, + {949, {wxMenu, setTitle, 1}}, + {950, {wxMenuItem, new, 1}}, + {952, {wxMenuItem, destruct, 0}}, + {953, {wxMenuItem, check, 1}}, + {954, {wxMenuItem, enable, 1}}, + {955, {wxMenuItem, getBitmap, 0}}, + {956, {wxMenuItem, getHelp, 0}}, + {957, {wxMenuItem, getId, 0}}, + {958, {wxMenuItem, getKind, 0}}, + {959, {wxMenuItem, getLabel, 0}}, + {960, {wxMenuItem, getLabelFromText, 1}}, + {961, {wxMenuItem, getMenu, 0}}, + {962, {wxMenuItem, getText, 0}}, + {963, {wxMenuItem, getSubMenu, 0}}, + {964, {wxMenuItem, isCheckable, 0}}, + {965, {wxMenuItem, isChecked, 0}}, + {966, {wxMenuItem, isEnabled, 0}}, + {967, {wxMenuItem, isSeparator, 0}}, + {968, {wxMenuItem, isSubMenu, 0}}, + {969, {wxMenuItem, setBitmap, 1}}, + {970, {wxMenuItem, setHelp, 1}}, + {971, {wxMenuItem, setMenu, 1}}, + {972, {wxMenuItem, setSubMenu, 1}}, + {973, {wxMenuItem, setText, 1}}, + {974, {wxToolBar, addControl, 1}}, + {975, {wxToolBar, addSeparator, 0}}, + {976, {wxToolBar, addTool_5, 5}}, + {977, {wxToolBar, addTool_4_0, 4}}, + {978, {wxToolBar, addTool_1, 1}}, + {979, {wxToolBar, addTool_4_1, 4}}, + {980, {wxToolBar, addTool_3, 3}}, + {981, {wxToolBar, addTool_6, 6}}, + {982, {wxToolBar, addCheckTool, 4}}, + {983, {wxToolBar, addRadioTool, 4}}, + {984, {wxToolBar, deleteTool, 1}}, + {985, {wxToolBar, deleteToolByPos, 1}}, + {986, {wxToolBar, enableTool, 2}}, + {987, {wxToolBar, findById, 1}}, + {988, {wxToolBar, findControl, 1}}, + {989, {wxToolBar, findToolForPosition, 2}}, + {990, {wxToolBar, getToolSize, 0}}, + {991, {wxToolBar, getToolBitmapSize, 0}}, + {992, {wxToolBar, getMargins, 0}}, + {993, {wxToolBar, getToolEnabled, 1}}, + {994, {wxToolBar, getToolLongHelp, 1}}, + {995, {wxToolBar, getToolPacking, 0}}, + {996, {wxToolBar, getToolPos, 1}}, + {997, {wxToolBar, getToolSeparation, 0}}, + {998, {wxToolBar, getToolShortHelp, 1}}, + {999, {wxToolBar, getToolState, 1}}, + {1000, {wxToolBar, insertControl, 2}}, + {1001, {wxToolBar, insertSeparator, 1}}, + {1002, {wxToolBar, insertTool_5, 5}}, + {1003, {wxToolBar, insertTool_2, 2}}, + {1004, {wxToolBar, insertTool_4, 4}}, + {1005, {wxToolBar, realize, 0}}, + {1006, {wxToolBar, removeTool, 1}}, + {1007, {wxToolBar, setMargins, 2}}, + {1008, {wxToolBar, setToolBitmapSize, 1}}, + {1009, {wxToolBar, setToolLongHelp, 2}}, + {1010, {wxToolBar, setToolPacking, 1}}, + {1011, {wxToolBar, setToolShortHelp, 2}}, + {1012, {wxToolBar, setToolSeparation, 1}}, + {1013, {wxToolBar, toggleTool, 2}}, + {1015, {wxStatusBar, new_0, 0}}, + {1016, {wxStatusBar, new_2, 2}}, + {1018, {wxStatusBar, destruct, 0}}, + {1019, {wxStatusBar, create, 2}}, + {1020, {wxStatusBar, getFieldRect, 2}}, + {1021, {wxStatusBar, getFieldsCount, 0}}, + {1022, {wxStatusBar, getStatusText, 1}}, + {1023, {wxStatusBar, popStatusText, 1}}, + {1024, {wxStatusBar, pushStatusText, 2}}, + {1025, {wxStatusBar, setFieldsCount, 2}}, + {1026, {wxStatusBar, setMinHeight, 1}}, + {1027, {wxStatusBar, setStatusText, 2}}, + {1028, {wxStatusBar, setStatusWidths, 2}}, + {1029, {wxStatusBar, setStatusStyles, 2}}, + {1030, {wxBitmap, new_0, 0}}, + {1031, {wxBitmap, new_3, 3}}, + {1032, {wxBitmap, new_4, 4}}, + {1033, {wxBitmap, new_2_0, 2}}, + {1034, {wxBitmap, new_2_1, 2}}, + {1035, {wxBitmap, destruct, 0}}, + {1036, {wxBitmap, convertToImage, 0}}, + {1037, {wxBitmap, copyFromIcon, 1}}, + {1038, {wxBitmap, create, 3}}, + {1039, {wxBitmap, getDepth, 0}}, + {1040, {wxBitmap, getHeight, 0}}, + {1041, {wxBitmap, getPalette, 0}}, + {1042, {wxBitmap, getMask, 0}}, + {1043, {wxBitmap, getWidth, 0}}, + {1044, {wxBitmap, getSubBitmap, 1}}, + {1045, {wxBitmap, loadFile, 2}}, + {1046, {wxBitmap, ok, 0}}, + {1047, {wxBitmap, saveFile, 3}}, + {1048, {wxBitmap, setDepth, 1}}, + {1049, {wxBitmap, setHeight, 1}}, + {1050, {wxBitmap, setMask, 1}}, + {1051, {wxBitmap, setPalette, 1}}, + {1052, {wxBitmap, setWidth, 1}}, + {1053, {wxIcon, new_0, 0}}, + {1054, {wxIcon, new_2, 2}}, + {1055, {wxIcon, new_1, 1}}, + {1056, {wxIcon, copyFromBitmap, 1}}, + {1057, {wxIcon, 'Destroy', undefined}}, + {1058, {wxIconBundle, new_0, 0}}, + {1059, {wxIconBundle, new_2, 2}}, + {1060, {wxIconBundle, new_1_0, 1}}, + {1061, {wxIconBundle, new_1_1, 1}}, + {1062, {wxIconBundle, destruct, 0}}, + {1063, {wxIconBundle, addIcon_2, 2}}, + {1064, {wxIconBundle, addIcon_1, 1}}, + {1065, {wxIconBundle, getIcon_1_1, 1}}, + {1066, {wxIconBundle, getIcon_1_0, 1}}, + {1067, {wxCursor, new_0, 0}}, + {1068, {wxCursor, new_1_0, 1}}, + {1069, {wxCursor, new_1_1, 1}}, + {1070, {wxCursor, new_4, 4}}, + {1071, {wxCursor, destruct, 0}}, + {1072, {wxCursor, ok, 0}}, + {1073, {wxMask, new_0, 0}}, + {1074, {wxMask, new_2_1, 2}}, + {1075, {wxMask, new_2_0, 2}}, + {1076, {wxMask, new_1, 1}}, + {1077, {wxMask, destruct, 0}}, + {1078, {wxMask, create_2_1, 2}}, + {1079, {wxMask, create_2_0, 2}}, + {1080, {wxMask, create_1, 1}}, + {1081, {wxImage, new_0, 0}}, + {1082, {wxImage, new_3_0, 3}}, + {1083, {wxImage, new_4, 4}}, + {1084, {wxImage, new_5, 5}}, + {1085, {wxImage, new_2, 2}}, + {1086, {wxImage, new_3_1, 3}}, + {1087, {wxImage, blur, 1}}, + {1088, {wxImage, blurHorizontal, 1}}, + {1089, {wxImage, blurVertical, 1}}, + {1090, {wxImage, convertAlphaToMask, 1}}, + {1091, {wxImage, convertToGreyscale, 1}}, + {1092, {wxImage, convertToMono, 3}}, + {1093, {wxImage, copy, 0}}, + {1094, {wxImage, create_3, 3}}, + {1095, {wxImage, create_4, 4}}, + {1096, {wxImage, create_5, 5}}, + {1097, {wxImage, 'Destroy', 0}}, + {1098, {wxImage, findFirstUnusedColour, 4}}, + {1099, {wxImage, getImageExtWildcard, 0}}, + {1100, {wxImage, getAlpha_2, 2}}, + {1101, {wxImage, getAlpha_0, 0}}, + {1102, {wxImage, getBlue, 2}}, + {1103, {wxImage, getData, 0}}, + {1104, {wxImage, getGreen, 2}}, + {1105, {wxImage, getImageCount, 2}}, + {1106, {wxImage, getHeight, 0}}, + {1107, {wxImage, getMaskBlue, 0}}, + {1108, {wxImage, getMaskGreen, 0}}, + {1109, {wxImage, getMaskRed, 0}}, + {1110, {wxImage, getOrFindMaskColour, 3}}, + {1111, {wxImage, getPalette, 0}}, + {1112, {wxImage, getRed, 2}}, + {1113, {wxImage, getSubImage, 1}}, + {1114, {wxImage, getWidth, 0}}, + {1115, {wxImage, hasAlpha, 0}}, + {1116, {wxImage, hasMask, 0}}, + {1117, {wxImage, getOption, 1}}, + {1118, {wxImage, getOptionInt, 1}}, + {1119, {wxImage, hasOption, 1}}, + {1120, {wxImage, initAlpha, 0}}, + {1121, {wxImage, initStandardHandlers, 0}}, + {1122, {wxImage, isTransparent, 3}}, + {1123, {wxImage, loadFile_2, 2}}, + {1124, {wxImage, loadFile_3, 3}}, + {1125, {wxImage, ok, 0}}, + {1126, {wxImage, removeHandler, 1}}, + {1127, {wxImage, mirror, 1}}, + {1128, {wxImage, replace, 6}}, + {1129, {wxImage, rescale, 3}}, + {1130, {wxImage, resize, 3}}, + {1131, {wxImage, rotate, 3}}, + {1132, {wxImage, rotateHue, 1}}, + {1133, {wxImage, rotate90, 1}}, + {1134, {wxImage, saveFile_1, 1}}, + {1135, {wxImage, saveFile_2_0, 2}}, + {1136, {wxImage, saveFile_2_1, 2}}, + {1137, {wxImage, scale, 3}}, + {1138, {wxImage, size, 3}}, + {1139, {wxImage, setAlpha_3, 3}}, + {1140, {wxImage, setAlpha_2, 2}}, + {1141, {wxImage, setData_2, 2}}, + {1142, {wxImage, setData_4, 4}}, + {1143, {wxImage, setMask, 1}}, + {1144, {wxImage, setMaskColour, 3}}, + {1145, {wxImage, setMaskFromImage, 4}}, + {1146, {wxImage, setOption_2_1, 2}}, + {1147, {wxImage, setOption_2_0, 2}}, + {1148, {wxImage, setPalette, 1}}, + {1149, {wxImage, setRGB_5, 5}}, + {1150, {wxImage, setRGB_4, 4}}, + {1151, {wxImage, 'Destroy', undefined}}, + {1152, {wxBrush, new_0, 0}}, + {1153, {wxBrush, new_2, 2}}, + {1154, {wxBrush, new_1, 1}}, + {1156, {wxBrush, destruct, 0}}, + {1157, {wxBrush, getColour, 0}}, + {1158, {wxBrush, getStipple, 0}}, + {1159, {wxBrush, getStyle, 0}}, + {1160, {wxBrush, isHatch, 0}}, + {1161, {wxBrush, isOk, 0}}, + {1162, {wxBrush, setColour_1, 1}}, + {1163, {wxBrush, setColour_3, 3}}, + {1164, {wxBrush, setStipple, 1}}, + {1165, {wxBrush, setStyle, 1}}, + {1166, {wxPen, new_0, 0}}, + {1167, {wxPen, new_2, 2}}, + {1168, {wxPen, destruct, 0}}, + {1169, {wxPen, getCap, 0}}, + {1170, {wxPen, getColour, 0}}, + {1171, {wxPen, getJoin, 0}}, + {1172, {wxPen, getStyle, 0}}, + {1173, {wxPen, getWidth, 0}}, + {1174, {wxPen, isOk, 0}}, + {1175, {wxPen, setCap, 1}}, + {1176, {wxPen, setColour_1, 1}}, + {1177, {wxPen, setColour_3, 3}}, + {1178, {wxPen, setJoin, 1}}, + {1179, {wxPen, setStyle, 1}}, + {1180, {wxPen, setWidth, 1}}, + {1181, {wxRegion, new_0, 0}}, + {1182, {wxRegion, new_4, 4}}, + {1183, {wxRegion, new_2, 2}}, + {1184, {wxRegion, new_1_1, 1}}, + {1186, {wxRegion, new_1_0, 1}}, + {1188, {wxRegion, destruct, 0}}, + {1189, {wxRegion, clear, 0}}, + {1190, {wxRegion, contains_2, 2}}, + {1191, {wxRegion, contains_1_0, 1}}, + {1192, {wxRegion, contains_4, 4}}, + {1193, {wxRegion, contains_1_1, 1}}, + {1194, {wxRegion, convertToBitmap, 0}}, + {1195, {wxRegion, getBox, 0}}, + {1196, {wxRegion, intersect_4, 4}}, + {1197, {wxRegion, intersect_1_1, 1}}, + {1198, {wxRegion, intersect_1_0, 1}}, + {1199, {wxRegion, isEmpty, 0}}, + {1200, {wxRegion, subtract_4, 4}}, + {1201, {wxRegion, subtract_1_1, 1}}, + {1202, {wxRegion, subtract_1_0, 1}}, + {1203, {wxRegion, offset_2, 2}}, + {1204, {wxRegion, offset_1, 1}}, + {1205, {wxRegion, union_4, 4}}, + {1206, {wxRegion, union_1_2, 1}}, + {1207, {wxRegion, union_1_1, 1}}, + {1208, {wxRegion, union_1_0, 1}}, + {1209, {wxRegion, union_3, 3}}, + {1210, {wxRegion, xor_4, 4}}, + {1211, {wxRegion, xor_1_1, 1}}, + {1212, {wxRegion, xor_1_0, 1}}, + {1213, {wxAcceleratorTable, new_0, 0}}, + {1214, {wxAcceleratorTable, new_2, 2}}, + {1215, {wxAcceleratorTable, destruct, 0}}, + {1216, {wxAcceleratorTable, ok, 0}}, + {1217, {wxAcceleratorEntry, new_1_0, 1}}, + {1218, {wxAcceleratorEntry, new_1_1, 1}}, + {1219, {wxAcceleratorEntry, getCommand, 0}}, + {1220, {wxAcceleratorEntry, getFlags, 0}}, + {1221, {wxAcceleratorEntry, getKeyCode, 0}}, + {1222, {wxAcceleratorEntry, set, 4}}, + {1223, {wxAcceleratorEntry, 'Destroy', undefined}}, + {1228, {wxCaret, new_3, 3}}, + {1229, {wxCaret, new_2, 2}}, + {1231, {wxCaret, destruct, 0}}, + {1232, {wxCaret, create_3, 3}}, + {1233, {wxCaret, create_2, 2}}, + {1234, {wxCaret, getBlinkTime, 0}}, + {1236, {wxCaret, getPosition, 0}}, + {1238, {wxCaret, getSize, 0}}, + {1239, {wxCaret, getWindow, 0}}, + {1240, {wxCaret, hide, 0}}, + {1241, {wxCaret, isOk, 0}}, + {1242, {wxCaret, isVisible, 0}}, + {1243, {wxCaret, move_2, 2}}, + {1244, {wxCaret, move_1, 1}}, + {1245, {wxCaret, setBlinkTime, 1}}, + {1246, {wxCaret, setSize_2, 2}}, + {1247, {wxCaret, setSize_1, 1}}, + {1248, {wxCaret, show, 1}}, + {1249, {wxSizer, add_2_1, 2}}, + {1250, {wxSizer, add_2_0, 2}}, + {1251, {wxSizer, add_3, 3}}, + {1252, {wxSizer, add_2_3, 2}}, + {1253, {wxSizer, add_2_2, 2}}, + {1254, {wxSizer, addSpacer, 1}}, + {1255, {wxSizer, addStretchSpacer, 1}}, + {1256, {wxSizer, calcMin, 0}}, + {1257, {wxSizer, clear, 1}}, + {1258, {wxSizer, detach_1_2, 1}}, + {1259, {wxSizer, detach_1_1, 1}}, + {1260, {wxSizer, detach_1_0, 1}}, + {1261, {wxSizer, fit, 1}}, + {1262, {wxSizer, fitInside, 1}}, + {1263, {wxSizer, getChildren, 0}}, + {1264, {wxSizer, getItem_2_1, 2}}, + {1265, {wxSizer, getItem_2_0, 2}}, + {1266, {wxSizer, getItem_1, 1}}, + {1267, {wxSizer, getSize, 0}}, + {1268, {wxSizer, getPosition, 0}}, + {1269, {wxSizer, getMinSize, 0}}, + {1270, {wxSizer, hide_2_0, 2}}, + {1271, {wxSizer, hide_2_1, 2}}, + {1272, {wxSizer, hide_1, 1}}, + {1273, {wxSizer, insert_3_1, 3}}, + {1274, {wxSizer, insert_3_0, 3}}, + {1275, {wxSizer, insert_4, 4}}, + {1276, {wxSizer, insert_3_3, 3}}, + {1277, {wxSizer, insert_3_2, 3}}, + {1278, {wxSizer, insert_2, 2}}, + {1279, {wxSizer, insertSpacer, 2}}, + {1280, {wxSizer, insertStretchSpacer, 2}}, + {1281, {wxSizer, isShown_1_2, 1}}, + {1282, {wxSizer, isShown_1_1, 1}}, + {1283, {wxSizer, isShown_1_0, 1}}, + {1284, {wxSizer, layout, 0}}, + {1285, {wxSizer, prepend_2_1, 2}}, + {1286, {wxSizer, prepend_2_0, 2}}, + {1287, {wxSizer, prepend_3, 3}}, + {1288, {wxSizer, prepend_2_3, 2}}, + {1289, {wxSizer, prepend_2_2, 2}}, + {1290, {wxSizer, prepend_1, 1}}, + {1291, {wxSizer, prependSpacer, 1}}, + {1292, {wxSizer, prependStretchSpacer, 1}}, + {1293, {wxSizer, recalcSizes, 0}}, + {1294, {wxSizer, remove_1_1, 1}}, + {1295, {wxSizer, remove_1_0, 1}}, + {1296, {wxSizer, replace_3_1, 3}}, + {1297, {wxSizer, replace_3_0, 3}}, + {1298, {wxSizer, replace_2, 2}}, + {1299, {wxSizer, setDimension, 4}}, + {1300, {wxSizer, setMinSize_2, 2}}, + {1301, {wxSizer, setMinSize_1, 1}}, + {1302, {wxSizer, setItemMinSize_3_2, 3}}, + {1303, {wxSizer, setItemMinSize_2_2, 2}}, + {1304, {wxSizer, setItemMinSize_3_1, 3}}, + {1305, {wxSizer, setItemMinSize_2_1, 2}}, + {1306, {wxSizer, setItemMinSize_3_0, 3}}, + {1307, {wxSizer, setItemMinSize_2_0, 2}}, + {1308, {wxSizer, setSizeHints, 1}}, + {1309, {wxSizer, setVirtualSizeHints, 1}}, + {1310, {wxSizer, show_2_2, 2}}, + {1311, {wxSizer, show_2_1, 2}}, + {1312, {wxSizer, show_2_0, 2}}, + {1313, {wxSizer, show_1, 1}}, + {1314, {wxSizerFlags, new, 1}}, + {1315, {wxSizerFlags, align, 1}}, + {1316, {wxSizerFlags, border_2, 2}}, + {1317, {wxSizerFlags, border_1, 1}}, + {1318, {wxSizerFlags, center, 0}}, + {1319, {wxSizerFlags, centre, 0}}, + {1320, {wxSizerFlags, expand, 0}}, + {1321, {wxSizerFlags, left, 0}}, + {1322, {wxSizerFlags, proportion, 1}}, + {1323, {wxSizerFlags, right, 0}}, + {1324, {wxSizerFlags, 'Destroy', undefined}}, + {1325, {wxSizerItem, new_5_1, 5}}, + {1326, {wxSizerItem, new_2_1, 2}}, + {1327, {wxSizerItem, new_5_0, 5}}, + {1328, {wxSizerItem, new_2_0, 2}}, + {1329, {wxSizerItem, new_6, 6}}, + {1330, {wxSizerItem, new_3, 3}}, + {1331, {wxSizerItem, new_0, 0}}, + {1332, {wxSizerItem, destruct, 0}}, + {1333, {wxSizerItem, calcMin, 0}}, + {1334, {wxSizerItem, deleteWindows, 0}}, + {1335, {wxSizerItem, detachSizer, 0}}, + {1336, {wxSizerItem, getBorder, 0}}, + {1337, {wxSizerItem, getFlag, 0}}, + {1338, {wxSizerItem, getMinSize, 0}}, + {1339, {wxSizerItem, getPosition, 0}}, + {1340, {wxSizerItem, getProportion, 0}}, + {1341, {wxSizerItem, getRatio, 0}}, + {1342, {wxSizerItem, getRect, 0}}, + {1343, {wxSizerItem, getSize, 0}}, + {1344, {wxSizerItem, getSizer, 0}}, + {1345, {wxSizerItem, getSpacer, 0}}, + {1346, {wxSizerItem, getUserData, 0}}, + {1347, {wxSizerItem, getWindow, 0}}, + {1348, {wxSizerItem, isSizer, 0}}, + {1349, {wxSizerItem, isShown, 0}}, + {1350, {wxSizerItem, isSpacer, 0}}, + {1351, {wxSizerItem, isWindow, 0}}, + {1352, {wxSizerItem, setBorder, 1}}, + {1353, {wxSizerItem, setDimension, 2}}, + {1354, {wxSizerItem, setFlag, 1}}, + {1355, {wxSizerItem, setInitSize, 2}}, + {1356, {wxSizerItem, setMinSize_1, 1}}, + {1357, {wxSizerItem, setMinSize_2, 2}}, + {1358, {wxSizerItem, setProportion, 1}}, + {1359, {wxSizerItem, setRatio_2, 2}}, + {1360, {wxSizerItem, setRatio_1_1, 1}}, + {1361, {wxSizerItem, setRatio_1_0, 1}}, + {1362, {wxSizerItem, setSizer, 1}}, + {1363, {wxSizerItem, setSpacer_1, 1}}, + {1364, {wxSizerItem, setSpacer_2, 2}}, + {1365, {wxSizerItem, setWindow, 1}}, + {1366, {wxSizerItem, show, 1}}, + {1367, {wxBoxSizer, new, 1}}, + {1368, {wxBoxSizer, getOrientation, 0}}, + {1369, {wxBoxSizer, 'Destroy', undefined}}, + {1370, {wxStaticBoxSizer, new_2, 2}}, + {1371, {wxStaticBoxSizer, new_3, 3}}, + {1372, {wxStaticBoxSizer, getStaticBox, 0}}, + {1373, {wxStaticBoxSizer, 'Destroy', undefined}}, + {1374, {wxGridSizer, new_4, 4}}, + {1375, {wxGridSizer, new_2, 2}}, + {1376, {wxGridSizer, getCols, 0}}, + {1377, {wxGridSizer, getHGap, 0}}, + {1378, {wxGridSizer, getRows, 0}}, + {1379, {wxGridSizer, getVGap, 0}}, + {1380, {wxGridSizer, setCols, 1}}, + {1381, {wxGridSizer, setHGap, 1}}, + {1382, {wxGridSizer, setRows, 1}}, + {1383, {wxGridSizer, setVGap, 1}}, + {1384, {wxGridSizer, 'Destroy', undefined}}, + {1385, {wxFlexGridSizer, new_4, 4}}, + {1386, {wxFlexGridSizer, new_2, 2}}, + {1387, {wxFlexGridSizer, addGrowableCol, 2}}, + {1388, {wxFlexGridSizer, addGrowableRow, 2}}, + {1389, {wxFlexGridSizer, getFlexibleDirection, 0}}, + {1390, {wxFlexGridSizer, getNonFlexibleGrowMode, 0}}, + {1391, {wxFlexGridSizer, removeGrowableCol, 1}}, + {1392, {wxFlexGridSizer, removeGrowableRow, 1}}, + {1393, {wxFlexGridSizer, setFlexibleDirection, 1}}, + {1394, {wxFlexGridSizer, setNonFlexibleGrowMode, 1}}, + {1395, {wxFlexGridSizer, 'Destroy', undefined}}, + {1396, {wxGridBagSizer, new, 1}}, + {1397, {wxGridBagSizer, add_3_2, 3}}, + {1398, {wxGridBagSizer, add_3_1, 3}}, + {1399, {wxGridBagSizer, add_4, 4}}, + {1400, {wxGridBagSizer, add_1_0, 1}}, + {1401, {wxGridBagSizer, add_2_1, 2}}, + {1402, {wxGridBagSizer, add_2_0, 2}}, + {1403, {wxGridBagSizer, add_3_0, 3}}, + {1404, {wxGridBagSizer, add_1_1, 1}}, + {1405, {wxGridBagSizer, calcMin, 0}}, + {1406, {wxGridBagSizer, checkForIntersection_2, 2}}, + {1407, {wxGridBagSizer, checkForIntersection_3, 3}}, + {1408, {wxGridBagSizer, findItem_1_1, 1}}, + {1409, {wxGridBagSizer, findItem_1_0, 1}}, + {1410, {wxGridBagSizer, findItemAtPoint, 1}}, + {1411, {wxGridBagSizer, findItemAtPosition, 1}}, + {1412, {wxGridBagSizer, findItemWithData, 1}}, + {1413, {wxGridBagSizer, getCellSize, 2}}, + {1414, {wxGridBagSizer, getEmptyCellSize, 0}}, + {1415, {wxGridBagSizer, getItemPosition_1_2, 1}}, + {1416, {wxGridBagSizer, getItemPosition_1_1, 1}}, + {1417, {wxGridBagSizer, getItemPosition_1_0, 1}}, + {1418, {wxGridBagSizer, getItemSpan_1_2, 1}}, + {1419, {wxGridBagSizer, getItemSpan_1_1, 1}}, + {1420, {wxGridBagSizer, getItemSpan_1_0, 1}}, + {1421, {wxGridBagSizer, setEmptyCellSize, 1}}, + {1422, {wxGridBagSizer, setItemPosition_2_2, 2}}, + {1423, {wxGridBagSizer, setItemPosition_2_1, 2}}, + {1424, {wxGridBagSizer, setItemPosition_2_0, 2}}, + {1425, {wxGridBagSizer, setItemSpan_2_2, 2}}, + {1426, {wxGridBagSizer, setItemSpan_2_1, 2}}, + {1427, {wxGridBagSizer, setItemSpan_2_0, 2}}, + {1428, {wxGridBagSizer, 'Destroy', undefined}}, + {1429, {wxStdDialogButtonSizer, new, 0}}, + {1430, {wxStdDialogButtonSizer, addButton, 1}}, + {1431, {wxStdDialogButtonSizer, realize, 0}}, + {1432, {wxStdDialogButtonSizer, setAffirmativeButton, 1}}, + {1433, {wxStdDialogButtonSizer, setCancelButton, 1}}, + {1434, {wxStdDialogButtonSizer, setNegativeButton, 1}}, + {1435, {wxStdDialogButtonSizer, 'Destroy', undefined}}, + {1436, {wxFont, new_0, 0}}, + {1437, {wxFont, new_1, 1}}, + {1438, {wxFont, new_5, 5}}, + {1440, {wxFont, destruct, 0}}, + {1441, {wxFont, isFixedWidth, 0}}, + {1442, {wxFont, getDefaultEncoding, 0}}, + {1443, {wxFont, getFaceName, 0}}, + {1444, {wxFont, getFamily, 0}}, + {1445, {wxFont, getNativeFontInfoDesc, 0}}, + {1446, {wxFont, getNativeFontInfoUserDesc, 0}}, + {1447, {wxFont, getPointSize, 0}}, + {1448, {wxFont, getStyle, 0}}, + {1449, {wxFont, getUnderlined, 0}}, + {1450, {wxFont, getWeight, 0}}, + {1451, {wxFont, ok, 0}}, + {1452, {wxFont, setDefaultEncoding, 1}}, + {1453, {wxFont, setFaceName, 1}}, + {1454, {wxFont, setFamily, 1}}, + {1455, {wxFont, setPointSize, 1}}, + {1456, {wxFont, setStyle, 1}}, + {1457, {wxFont, setUnderlined, 1}}, + {1458, {wxFont, setWeight, 1}}, + {1459, {wxToolTip, enable, 1}}, + {1460, {wxToolTip, setDelay, 1}}, + {1461, {wxToolTip, new, 1}}, + {1462, {wxToolTip, setTip, 1}}, + {1463, {wxToolTip, getTip, 0}}, + {1464, {wxToolTip, getWindow, 0}}, + {1465, {wxToolTip, 'Destroy', undefined}}, + {1467, {wxButton, new_3, 3}}, + {1468, {wxButton, new_0, 0}}, + {1469, {wxButton, destruct, 0}}, + {1470, {wxButton, create, 3}}, + {1471, {wxButton, getDefaultSize, 0}}, + {1472, {wxButton, setDefault, 0}}, + {1473, {wxButton, setLabel, 1}}, + {1475, {wxBitmapButton, new_4, 4}}, + {1476, {wxBitmapButton, new_0, 0}}, + {1477, {wxBitmapButton, create, 4}}, + {1478, {wxBitmapButton, getBitmapDisabled, 0}}, + {1480, {wxBitmapButton, getBitmapFocus, 0}}, + {1482, {wxBitmapButton, getBitmapLabel, 0}}, + {1484, {wxBitmapButton, getBitmapSelected, 0}}, + {1486, {wxBitmapButton, setBitmapDisabled, 1}}, + {1487, {wxBitmapButton, setBitmapFocus, 1}}, + {1488, {wxBitmapButton, setBitmapLabel, 1}}, + {1489, {wxBitmapButton, setBitmapSelected, 1}}, + {1490, {wxBitmapButton, 'Destroy', undefined}}, + {1491, {wxToggleButton, new_0, 0}}, + {1492, {wxToggleButton, new_4, 4}}, + {1493, {wxToggleButton, create, 4}}, + {1494, {wxToggleButton, getValue, 0}}, + {1495, {wxToggleButton, setValue, 1}}, + {1496, {wxToggleButton, 'Destroy', undefined}}, + {1497, {wxCalendarCtrl, new_0, 0}}, + {1498, {wxCalendarCtrl, new_3, 3}}, + {1499, {wxCalendarCtrl, create, 3}}, + {1500, {wxCalendarCtrl, destruct, 0}}, + {1501, {wxCalendarCtrl, setDate, 1}}, + {1502, {wxCalendarCtrl, getDate, 0}}, + {1503, {wxCalendarCtrl, enableYearChange, 1}}, + {1504, {wxCalendarCtrl, enableMonthChange, 1}}, + {1505, {wxCalendarCtrl, enableHolidayDisplay, 1}}, + {1506, {wxCalendarCtrl, setHeaderColours, 2}}, + {1507, {wxCalendarCtrl, getHeaderColourFg, 0}}, + {1508, {wxCalendarCtrl, getHeaderColourBg, 0}}, + {1509, {wxCalendarCtrl, setHighlightColours, 2}}, + {1510, {wxCalendarCtrl, getHighlightColourFg, 0}}, + {1511, {wxCalendarCtrl, getHighlightColourBg, 0}}, + {1512, {wxCalendarCtrl, setHolidayColours, 2}}, + {1513, {wxCalendarCtrl, getHolidayColourFg, 0}}, + {1514, {wxCalendarCtrl, getHolidayColourBg, 0}}, + {1515, {wxCalendarCtrl, getAttr, 1}}, + {1516, {wxCalendarCtrl, setAttr, 2}}, + {1517, {wxCalendarCtrl, setHoliday, 1}}, + {1518, {wxCalendarCtrl, resetAttr, 1}}, + {1519, {wxCalendarCtrl, hitTest, 2}}, + {1520, {wxCalendarDateAttr, new_0, 0}}, + {1521, {wxCalendarDateAttr, new_2_1, 2}}, + {1522, {wxCalendarDateAttr, new_2_0, 2}}, + {1523, {wxCalendarDateAttr, setTextColour, 1}}, + {1524, {wxCalendarDateAttr, setBackgroundColour, 1}}, + {1525, {wxCalendarDateAttr, setBorderColour, 1}}, + {1526, {wxCalendarDateAttr, setFont, 1}}, + {1527, {wxCalendarDateAttr, setBorder, 1}}, + {1528, {wxCalendarDateAttr, setHoliday, 1}}, + {1529, {wxCalendarDateAttr, hasTextColour, 0}}, + {1530, {wxCalendarDateAttr, hasBackgroundColour, 0}}, + {1531, {wxCalendarDateAttr, hasBorderColour, 0}}, + {1532, {wxCalendarDateAttr, hasFont, 0}}, + {1533, {wxCalendarDateAttr, hasBorder, 0}}, + {1534, {wxCalendarDateAttr, isHoliday, 0}}, + {1535, {wxCalendarDateAttr, getTextColour, 0}}, + {1536, {wxCalendarDateAttr, getBackgroundColour, 0}}, + {1537, {wxCalendarDateAttr, getBorderColour, 0}}, + {1538, {wxCalendarDateAttr, getFont, 0}}, + {1539, {wxCalendarDateAttr, getBorder, 0}}, + {1540, {wxCalendarDateAttr, 'Destroy', undefined}}, + {1542, {wxCheckBox, new_4, 4}}, + {1543, {wxCheckBox, new_0, 0}}, + {1544, {wxCheckBox, create, 4}}, + {1545, {wxCheckBox, getValue, 0}}, + {1546, {wxCheckBox, get3StateValue, 0}}, + {1547, {wxCheckBox, is3rdStateAllowedForUser, 0}}, + {1548, {wxCheckBox, is3State, 0}}, + {1549, {wxCheckBox, isChecked, 0}}, + {1550, {wxCheckBox, setValue, 1}}, + {1551, {wxCheckBox, set3StateValue, 1}}, + {1552, {wxCheckBox, 'Destroy', undefined}}, + {1553, {wxCheckListBox, new_0, 0}}, + {1555, {wxCheckListBox, new_3, 3}}, + {1556, {wxCheckListBox, check, 2}}, + {1557, {wxCheckListBox, isChecked, 1}}, + {1558, {wxCheckListBox, 'Destroy', undefined}}, + {1561, {wxChoice, new_3, 3}}, + {1562, {wxChoice, new_0, 0}}, + {1564, {wxChoice, destruct, 0}}, + {1566, {wxChoice, create, 6}}, + {1567, {wxChoice, delete, 1}}, + {1568, {wxChoice, getColumns, 0}}, + {1569, {wxChoice, setColumns, 1}}, + {1570, {wxComboBox, new_0, 0}}, + {1572, {wxComboBox, new_3, 3}}, + {1573, {wxComboBox, destruct, 0}}, + {1575, {wxComboBox, create, 7}}, + {1576, {wxComboBox, canCopy, 0}}, + {1577, {wxComboBox, canCut, 0}}, + {1578, {wxComboBox, canPaste, 0}}, + {1579, {wxComboBox, canRedo, 0}}, + {1580, {wxComboBox, canUndo, 0}}, + {1581, {wxComboBox, copy, 0}}, + {1582, {wxComboBox, cut, 0}}, + {1583, {wxComboBox, getInsertionPoint, 0}}, + {1584, {wxComboBox, getLastPosition, 0}}, + {1585, {wxComboBox, getValue, 0}}, + {1586, {wxComboBox, paste, 0}}, + {1587, {wxComboBox, redo, 0}}, + {1588, {wxComboBox, replace, 3}}, + {1589, {wxComboBox, remove, 2}}, + {1590, {wxComboBox, setInsertionPoint, 1}}, + {1591, {wxComboBox, setInsertionPointEnd, 0}}, + {1592, {wxComboBox, setSelection_1, 1}}, + {1593, {wxComboBox, setSelection_2, 2}}, + {1594, {wxComboBox, setValue, 1}}, + {1595, {wxComboBox, undo, 0}}, + {1596, {wxGauge, new_0, 0}}, + {1597, {wxGauge, new_4, 4}}, + {1598, {wxGauge, create, 4}}, + {1599, {wxGauge, getBezelFace, 0}}, + {1600, {wxGauge, getRange, 0}}, + {1601, {wxGauge, getShadowWidth, 0}}, + {1602, {wxGauge, getValue, 0}}, + {1603, {wxGauge, isVertical, 0}}, + {1604, {wxGauge, setBezelFace, 1}}, + {1605, {wxGauge, setRange, 1}}, + {1606, {wxGauge, setShadowWidth, 1}}, + {1607, {wxGauge, setValue, 1}}, + {1608, {wxGauge, pulse, 0}}, + {1609, {wxGauge, 'Destroy', undefined}}, + {1610, {wxGenericDirCtrl, new_0, 0}}, + {1611, {wxGenericDirCtrl, new_2, 2}}, + {1612, {wxGenericDirCtrl, destruct, 0}}, + {1613, {wxGenericDirCtrl, create, 2}}, + {1614, {wxGenericDirCtrl, init, 0}}, + {1615, {wxGenericDirCtrl, collapseTree, 0}}, + {1616, {wxGenericDirCtrl, expandPath, 1}}, + {1617, {wxGenericDirCtrl, getDefaultPath, 0}}, + {1618, {wxGenericDirCtrl, getPath, 0}}, + {1619, {wxGenericDirCtrl, getFilePath, 0}}, + {1620, {wxGenericDirCtrl, getFilter, 0}}, + {1621, {wxGenericDirCtrl, getFilterIndex, 0}}, + {1622, {wxGenericDirCtrl, getRootId, 0}}, + {1623, {wxGenericDirCtrl, getTreeCtrl, 0}}, + {1624, {wxGenericDirCtrl, reCreateTree, 0}}, + {1625, {wxGenericDirCtrl, setDefaultPath, 1}}, + {1626, {wxGenericDirCtrl, setFilter, 1}}, + {1627, {wxGenericDirCtrl, setFilterIndex, 1}}, + {1628, {wxGenericDirCtrl, setPath, 1}}, + {1630, {wxStaticBox, new_4, 4}}, + {1631, {wxStaticBox, new_0, 0}}, + {1632, {wxStaticBox, create, 4}}, + {1633, {wxStaticBox, 'Destroy', undefined}}, + {1635, {wxStaticLine, new_2, 2}}, + {1636, {wxStaticLine, new_0, 0}}, + {1637, {wxStaticLine, create, 2}}, + {1638, {wxStaticLine, isVertical, 0}}, + {1639, {wxStaticLine, getDefaultSize, 0}}, + {1640, {wxStaticLine, 'Destroy', undefined}}, + {1643, {wxListBox, new_3, 3}}, + {1644, {wxListBox, new_0, 0}}, + {1646, {wxListBox, destruct, 0}}, + {1648, {wxListBox, create, 6}}, + {1649, {wxListBox, deselect, 1}}, + {1650, {wxListBox, getSelections, 1}}, + {1651, {wxListBox, insertItems, 2}}, + {1652, {wxListBox, isSelected, 1}}, + {1654, {wxListBox, set, 2}}, + {1655, {wxListBox, hitTest, 1}}, + {1656, {wxListBox, setFirstItem_1_0, 1}}, + {1657, {wxListBox, setFirstItem_1_1, 1}}, + {1658, {wxListCtrl, new_0, 0}}, + {1659, {wxListCtrl, new_2, 2}}, + {1660, {wxListCtrl, arrange, 1}}, + {1661, {wxListCtrl, assignImageList, 2}}, + {1662, {wxListCtrl, clearAll, 0}}, + {1663, {wxListCtrl, create, 2}}, + {1664, {wxListCtrl, deleteAllItems, 0}}, + {1665, {wxListCtrl, deleteColumn, 1}}, + {1666, {wxListCtrl, deleteItem, 1}}, + {1667, {wxListCtrl, editLabel, 1}}, + {1668, {wxListCtrl, ensureVisible, 1}}, + {1669, {wxListCtrl, findItem_3_0, 3}}, + {1670, {wxListCtrl, findItem_3_1, 3}}, + {1671, {wxListCtrl, getColumn, 2}}, + {1672, {wxListCtrl, getColumnCount, 0}}, + {1673, {wxListCtrl, getColumnWidth, 1}}, + {1674, {wxListCtrl, getCountPerPage, 0}}, + {1675, {wxListCtrl, getEditControl, 0}}, + {1676, {wxListCtrl, getImageList, 1}}, + {1677, {wxListCtrl, getItem, 1}}, + {1678, {wxListCtrl, getItemBackgroundColour, 1}}, + {1679, {wxListCtrl, getItemCount, 0}}, + {1680, {wxListCtrl, getItemData, 1}}, + {1681, {wxListCtrl, getItemFont, 1}}, + {1682, {wxListCtrl, getItemPosition, 2}}, + {1683, {wxListCtrl, getItemRect, 3}}, + {1684, {wxListCtrl, getItemSpacing, 0}}, + {1685, {wxListCtrl, getItemState, 2}}, + {1686, {wxListCtrl, getItemText, 1}}, + {1687, {wxListCtrl, getItemTextColour, 1}}, + {1688, {wxListCtrl, getNextItem, 2}}, + {1689, {wxListCtrl, getSelectedItemCount, 0}}, + {1690, {wxListCtrl, getTextColour, 0}}, + {1691, {wxListCtrl, getTopItem, 0}}, + {1692, {wxListCtrl, getViewRect, 0}}, + {1693, {wxListCtrl, hitTest, 2}}, + {1694, {wxListCtrl, insertColumn_2, 2}}, + {1695, {wxListCtrl, insertColumn_3, 3}}, + {1696, {wxListCtrl, insertItem_1, 1}}, + {1697, {wxListCtrl, insertItem_2_1, 2}}, + {1698, {wxListCtrl, insertItem_2_0, 2}}, + {1699, {wxListCtrl, insertItem_3, 3}}, + {1700, {wxListCtrl, refreshItem, 1}}, + {1701, {wxListCtrl, refreshItems, 2}}, + {1702, {wxListCtrl, scrollList, 2}}, + {1703, {wxListCtrl, setBackgroundColour, 1}}, + {1704, {wxListCtrl, setColumn, 2}}, + {1705, {wxListCtrl, setColumnWidth, 2}}, + {1706, {wxListCtrl, setImageList, 2}}, + {1707, {wxListCtrl, setItem_1, 1}}, + {1708, {wxListCtrl, setItem_4, 4}}, + {1709, {wxListCtrl, setItemBackgroundColour, 2}}, + {1710, {wxListCtrl, setItemCount, 1}}, + {1711, {wxListCtrl, setItemData, 2}}, + {1712, {wxListCtrl, setItemFont, 2}}, + {1713, {wxListCtrl, setItemImage, 3}}, + {1714, {wxListCtrl, setItemColumnImage, 3}}, + {1715, {wxListCtrl, setItemPosition, 2}}, + {1716, {wxListCtrl, setItemState, 3}}, + {1717, {wxListCtrl, setItemText, 2}}, + {1718, {wxListCtrl, setItemTextColour, 2}}, + {1719, {wxListCtrl, setSingleStyle, 2}}, + {1720, {wxListCtrl, setTextColour, 1}}, + {1721, {wxListCtrl, setWindowStyleFlag, 1}}, + {1722, {wxListCtrl, sortItems, 2}}, + {1723, {wxListCtrl, 'Destroy', undefined}}, + {1724, {wxListView, clearColumnImage, 1}}, + {1725, {wxListView, focus, 1}}, + {1726, {wxListView, getFirstSelected, 0}}, + {1727, {wxListView, getFocusedItem, 0}}, + {1728, {wxListView, getNextSelected, 1}}, + {1729, {wxListView, isSelected, 1}}, + {1730, {wxListView, select, 2}}, + {1731, {wxListView, setColumnImage, 2}}, + {1732, {wxListItem, new_0, 0}}, + {1733, {wxListItem, new_1, 1}}, + {1734, {wxListItem, destruct, 0}}, + {1735, {wxListItem, clear, 0}}, + {1736, {wxListItem, getAlign, 0}}, + {1737, {wxListItem, getBackgroundColour, 0}}, + {1738, {wxListItem, getColumn, 0}}, + {1739, {wxListItem, getFont, 0}}, + {1740, {wxListItem, getId, 0}}, + {1741, {wxListItem, getImage, 0}}, + {1742, {wxListItem, getMask, 0}}, + {1743, {wxListItem, getState, 0}}, + {1744, {wxListItem, getText, 0}}, + {1745, {wxListItem, getTextColour, 0}}, + {1746, {wxListItem, getWidth, 0}}, + {1747, {wxListItem, setAlign, 1}}, + {1748, {wxListItem, setBackgroundColour, 1}}, + {1749, {wxListItem, setColumn, 1}}, + {1750, {wxListItem, setFont, 1}}, + {1751, {wxListItem, setId, 1}}, + {1752, {wxListItem, setImage, 1}}, + {1753, {wxListItem, setMask, 1}}, + {1754, {wxListItem, setState, 1}}, + {1755, {wxListItem, setStateMask, 1}}, + {1756, {wxListItem, setText, 1}}, + {1757, {wxListItem, setTextColour, 1}}, + {1758, {wxListItem, setWidth, 1}}, + {1759, {wxListItemAttr, new_0, 0}}, + {1760, {wxListItemAttr, new_3, 3}}, + {1761, {wxListItemAttr, getBackgroundColour, 0}}, + {1762, {wxListItemAttr, getFont, 0}}, + {1763, {wxListItemAttr, getTextColour, 0}}, + {1764, {wxListItemAttr, hasBackgroundColour, 0}}, + {1765, {wxListItemAttr, hasFont, 0}}, + {1766, {wxListItemAttr, hasTextColour, 0}}, + {1767, {wxListItemAttr, setBackgroundColour, 1}}, + {1768, {wxListItemAttr, setFont, 1}}, + {1769, {wxListItemAttr, setTextColour, 1}}, + {1770, {wxListItemAttr, 'Destroy', undefined}}, + {1771, {wxImageList, new_0, 0}}, + {1772, {wxImageList, new_3, 3}}, + {1773, {wxImageList, add_1, 1}}, + {1774, {wxImageList, add_2_0, 2}}, + {1775, {wxImageList, add_2_1, 2}}, + {1776, {wxImageList, create, 3}}, + {1778, {wxImageList, draw, 5}}, + {1779, {wxImageList, getBitmap, 1}}, + {1780, {wxImageList, getIcon, 1}}, + {1781, {wxImageList, getImageCount, 0}}, + {1782, {wxImageList, getSize, 3}}, + {1783, {wxImageList, remove, 1}}, + {1784, {wxImageList, removeAll, 0}}, + {1785, {wxImageList, replace_2, 2}}, + {1786, {wxImageList, replace_3, 3}}, + {1787, {wxImageList, 'Destroy', undefined}}, + {1788, {wxTextAttr, new_0, 0}}, + {1789, {wxTextAttr, new_2, 2}}, + {1790, {wxTextAttr, getAlignment, 0}}, + {1791, {wxTextAttr, getBackgroundColour, 0}}, + {1792, {wxTextAttr, getFont, 0}}, + {1793, {wxTextAttr, getLeftIndent, 0}}, + {1794, {wxTextAttr, getLeftSubIndent, 0}}, + {1795, {wxTextAttr, getRightIndent, 0}}, + {1796, {wxTextAttr, getTabs, 0}}, + {1797, {wxTextAttr, getTextColour, 0}}, + {1798, {wxTextAttr, hasBackgroundColour, 0}}, + {1799, {wxTextAttr, hasFont, 0}}, + {1800, {wxTextAttr, hasTextColour, 0}}, + {1801, {wxTextAttr, getFlags, 0}}, + {1802, {wxTextAttr, isDefault, 0}}, + {1803, {wxTextAttr, setAlignment, 1}}, + {1804, {wxTextAttr, setBackgroundColour, 1}}, + {1805, {wxTextAttr, setFlags, 1}}, + {1806, {wxTextAttr, setFont, 2}}, + {1807, {wxTextAttr, setLeftIndent, 2}}, + {1808, {wxTextAttr, setRightIndent, 1}}, + {1809, {wxTextAttr, setTabs, 1}}, + {1810, {wxTextAttr, setTextColour, 1}}, + {1811, {wxTextAttr, 'Destroy', undefined}}, + {1813, {wxTextCtrl, new_3, 3}}, + {1814, {wxTextCtrl, new_0, 0}}, + {1816, {wxTextCtrl, destruct, 0}}, + {1817, {wxTextCtrl, appendText, 1}}, + {1818, {wxTextCtrl, canCopy, 0}}, + {1819, {wxTextCtrl, canCut, 0}}, + {1820, {wxTextCtrl, canPaste, 0}}, + {1821, {wxTextCtrl, canRedo, 0}}, + {1822, {wxTextCtrl, canUndo, 0}}, + {1823, {wxTextCtrl, clear, 0}}, + {1824, {wxTextCtrl, copy, 0}}, + {1825, {wxTextCtrl, create, 3}}, + {1826, {wxTextCtrl, cut, 0}}, + {1827, {wxTextCtrl, discardEdits, 0}}, + {1828, {wxTextCtrl, emulateKeyPress, 1}}, + {1829, {wxTextCtrl, getDefaultStyle, 0}}, + {1830, {wxTextCtrl, getInsertionPoint, 0}}, + {1831, {wxTextCtrl, getLastPosition, 0}}, + {1832, {wxTextCtrl, getLineLength, 1}}, + {1833, {wxTextCtrl, getLineText, 1}}, + {1834, {wxTextCtrl, getNumberOfLines, 0}}, + {1835, {wxTextCtrl, getRange, 2}}, + {1836, {wxTextCtrl, getSelection, 2}}, + {1837, {wxTextCtrl, getStringSelection, 0}}, + {1838, {wxTextCtrl, getStyle, 2}}, + {1839, {wxTextCtrl, getValue, 0}}, + {1840, {wxTextCtrl, isEditable, 0}}, + {1841, {wxTextCtrl, isModified, 0}}, + {1842, {wxTextCtrl, isMultiLine, 0}}, + {1843, {wxTextCtrl, isSingleLine, 0}}, + {1844, {wxTextCtrl, loadFile, 2}}, + {1845, {wxTextCtrl, markDirty, 0}}, + {1846, {wxTextCtrl, paste, 0}}, + {1847, {wxTextCtrl, positionToXY, 3}}, + {1848, {wxTextCtrl, redo, 0}}, + {1849, {wxTextCtrl, remove, 2}}, + {1850, {wxTextCtrl, replace, 3}}, + {1851, {wxTextCtrl, saveFile, 1}}, + {1852, {wxTextCtrl, setDefaultStyle, 1}}, + {1853, {wxTextCtrl, setEditable, 1}}, + {1854, {wxTextCtrl, setInsertionPoint, 1}}, + {1855, {wxTextCtrl, setInsertionPointEnd, 0}}, + {1857, {wxTextCtrl, setMaxLength, 1}}, + {1858, {wxTextCtrl, setSelection, 2}}, + {1859, {wxTextCtrl, setStyle, 3}}, + {1860, {wxTextCtrl, setValue, 1}}, + {1861, {wxTextCtrl, showPosition, 1}}, + {1862, {wxTextCtrl, undo, 0}}, + {1863, {wxTextCtrl, writeText, 1}}, + {1864, {wxTextCtrl, xYToPosition, 2}}, + {1867, {wxNotebook, new_0, 0}}, + {1868, {wxNotebook, new_3, 3}}, + {1869, {wxNotebook, destruct, 0}}, + {1870, {wxNotebook, addPage, 3}}, + {1871, {wxNotebook, advanceSelection, 1}}, + {1872, {wxNotebook, assignImageList, 1}}, + {1873, {wxNotebook, create, 3}}, + {1874, {wxNotebook, deleteAllPages, 0}}, + {1875, {wxNotebook, deletePage, 1}}, + {1876, {wxNotebook, removePage, 1}}, + {1877, {wxNotebook, getCurrentPage, 0}}, + {1878, {wxNotebook, getImageList, 0}}, + {1880, {wxNotebook, getPage, 1}}, + {1881, {wxNotebook, getPageCount, 0}}, + {1882, {wxNotebook, getPageImage, 1}}, + {1883, {wxNotebook, getPageText, 1}}, + {1884, {wxNotebook, getRowCount, 0}}, + {1885, {wxNotebook, getSelection, 0}}, + {1886, {wxNotebook, getThemeBackgroundColour, 0}}, + {1888, {wxNotebook, hitTest, 2}}, + {1890, {wxNotebook, insertPage, 4}}, + {1891, {wxNotebook, setImageList, 1}}, + {1892, {wxNotebook, setPadding, 1}}, + {1893, {wxNotebook, setPageSize, 1}}, + {1894, {wxNotebook, setPageImage, 2}}, + {1895, {wxNotebook, setPageText, 2}}, + {1896, {wxNotebook, setSelection, 1}}, + {1897, {wxNotebook, changeSelection, 1}}, + {1898, {wxChoicebook, new_0, 0}}, + {1899, {wxChoicebook, new_3, 3}}, + {1900, {wxChoicebook, addPage, 3}}, + {1901, {wxChoicebook, advanceSelection, 1}}, + {1902, {wxChoicebook, assignImageList, 1}}, + {1903, {wxChoicebook, create, 3}}, + {1904, {wxChoicebook, deleteAllPages, 0}}, + {1905, {wxChoicebook, deletePage, 1}}, + {1906, {wxChoicebook, removePage, 1}}, + {1907, {wxChoicebook, getCurrentPage, 0}}, + {1908, {wxChoicebook, getImageList, 0}}, + {1910, {wxChoicebook, getPage, 1}}, + {1911, {wxChoicebook, getPageCount, 0}}, + {1912, {wxChoicebook, getPageImage, 1}}, + {1913, {wxChoicebook, getPageText, 1}}, + {1914, {wxChoicebook, getSelection, 0}}, + {1915, {wxChoicebook, hitTest, 2}}, + {1916, {wxChoicebook, insertPage, 4}}, + {1917, {wxChoicebook, setImageList, 1}}, + {1918, {wxChoicebook, setPageSize, 1}}, + {1919, {wxChoicebook, setPageImage, 2}}, + {1920, {wxChoicebook, setPageText, 2}}, + {1921, {wxChoicebook, setSelection, 1}}, + {1922, {wxChoicebook, changeSelection, 1}}, + {1923, {wxChoicebook, 'Destroy', undefined}}, + {1924, {wxToolbook, new_0, 0}}, + {1925, {wxToolbook, new_3, 3}}, + {1926, {wxToolbook, addPage, 3}}, + {1927, {wxToolbook, advanceSelection, 1}}, + {1928, {wxToolbook, assignImageList, 1}}, + {1929, {wxToolbook, create, 3}}, + {1930, {wxToolbook, deleteAllPages, 0}}, + {1931, {wxToolbook, deletePage, 1}}, + {1932, {wxToolbook, removePage, 1}}, + {1933, {wxToolbook, getCurrentPage, 0}}, + {1934, {wxToolbook, getImageList, 0}}, + {1936, {wxToolbook, getPage, 1}}, + {1937, {wxToolbook, getPageCount, 0}}, + {1938, {wxToolbook, getPageImage, 1}}, + {1939, {wxToolbook, getPageText, 1}}, + {1940, {wxToolbook, getSelection, 0}}, + {1942, {wxToolbook, hitTest, 2}}, + {1943, {wxToolbook, insertPage, 4}}, + {1944, {wxToolbook, setImageList, 1}}, + {1945, {wxToolbook, setPageSize, 1}}, + {1946, {wxToolbook, setPageImage, 2}}, + {1947, {wxToolbook, setPageText, 2}}, + {1948, {wxToolbook, setSelection, 1}}, + {1949, {wxToolbook, changeSelection, 1}}, + {1950, {wxToolbook, 'Destroy', undefined}}, + {1951, {wxListbook, new_0, 0}}, + {1952, {wxListbook, new_3, 3}}, + {1953, {wxListbook, addPage, 3}}, + {1954, {wxListbook, advanceSelection, 1}}, + {1955, {wxListbook, assignImageList, 1}}, + {1956, {wxListbook, create, 3}}, + {1957, {wxListbook, deleteAllPages, 0}}, + {1958, {wxListbook, deletePage, 1}}, + {1959, {wxListbook, removePage, 1}}, + {1960, {wxListbook, getCurrentPage, 0}}, + {1961, {wxListbook, getImageList, 0}}, + {1963, {wxListbook, getPage, 1}}, + {1964, {wxListbook, getPageCount, 0}}, + {1965, {wxListbook, getPageImage, 1}}, + {1966, {wxListbook, getPageText, 1}}, + {1967, {wxListbook, getSelection, 0}}, + {1969, {wxListbook, hitTest, 2}}, + {1970, {wxListbook, insertPage, 4}}, + {1971, {wxListbook, setImageList, 1}}, + {1972, {wxListbook, setPageSize, 1}}, + {1973, {wxListbook, setPageImage, 2}}, + {1974, {wxListbook, setPageText, 2}}, + {1975, {wxListbook, setSelection, 1}}, + {1976, {wxListbook, changeSelection, 1}}, + {1977, {wxListbook, 'Destroy', undefined}}, + {1978, {wxTreebook, new_0, 0}}, + {1979, {wxTreebook, new_3, 3}}, + {1980, {wxTreebook, addPage, 3}}, + {1981, {wxTreebook, advanceSelection, 1}}, + {1982, {wxTreebook, assignImageList, 1}}, + {1983, {wxTreebook, create, 3}}, + {1984, {wxTreebook, deleteAllPages, 0}}, + {1985, {wxTreebook, deletePage, 1}}, + {1986, {wxTreebook, removePage, 1}}, + {1987, {wxTreebook, getCurrentPage, 0}}, + {1988, {wxTreebook, getImageList, 0}}, + {1990, {wxTreebook, getPage, 1}}, + {1991, {wxTreebook, getPageCount, 0}}, + {1992, {wxTreebook, getPageImage, 1}}, + {1993, {wxTreebook, getPageText, 1}}, + {1994, {wxTreebook, getSelection, 0}}, + {1995, {wxTreebook, expandNode, 2}}, + {1996, {wxTreebook, isNodeExpanded, 1}}, + {1998, {wxTreebook, hitTest, 2}}, + {1999, {wxTreebook, insertPage, 4}}, + {2000, {wxTreebook, insertSubPage, 4}}, + {2001, {wxTreebook, setImageList, 1}}, + {2002, {wxTreebook, setPageSize, 1}}, + {2003, {wxTreebook, setPageImage, 2}}, + {2004, {wxTreebook, setPageText, 2}}, + {2005, {wxTreebook, setSelection, 1}}, + {2006, {wxTreebook, changeSelection, 1}}, + {2007, {wxTreebook, 'Destroy', undefined}}, + {2010, {wxTreeCtrl, new_2, 2}}, + {2011, {wxTreeCtrl, new_0, 0}}, + {2013, {wxTreeCtrl, destruct, 0}}, + {2014, {wxTreeCtrl, addRoot, 2}}, + {2015, {wxTreeCtrl, appendItem, 3}}, + {2016, {wxTreeCtrl, assignImageList, 1}}, + {2017, {wxTreeCtrl, assignStateImageList, 1}}, + {2018, {wxTreeCtrl, collapse, 1}}, + {2019, {wxTreeCtrl, collapseAndReset, 1}}, + {2020, {wxTreeCtrl, create, 2}}, + {2021, {wxTreeCtrl, delete, 1}}, + {2022, {wxTreeCtrl, deleteAllItems, 0}}, + {2023, {wxTreeCtrl, deleteChildren, 1}}, + {2024, {wxTreeCtrl, editLabel, 1}}, + {2025, {wxTreeCtrl, ensureVisible, 1}}, + {2026, {wxTreeCtrl, expand, 1}}, + {2027, {wxTreeCtrl, getBoundingRect, 3}}, + {2029, {wxTreeCtrl, getChildrenCount, 2}}, + {2030, {wxTreeCtrl, getCount, 0}}, + {2031, {wxTreeCtrl, getEditControl, 0}}, + {2032, {wxTreeCtrl, getFirstChild, 2}}, + {2033, {wxTreeCtrl, getNextChild, 2}}, + {2034, {wxTreeCtrl, getFirstVisibleItem, 0}}, + {2035, {wxTreeCtrl, getImageList, 0}}, + {2036, {wxTreeCtrl, getIndent, 0}}, + {2037, {wxTreeCtrl, getItemBackgroundColour, 1}}, + {2038, {wxTreeCtrl, getItemData, 1}}, + {2039, {wxTreeCtrl, getItemFont, 1}}, + {2040, {wxTreeCtrl, getItemImage_1, 1}}, + {2041, {wxTreeCtrl, getItemImage_2, 2}}, + {2042, {wxTreeCtrl, getItemText, 1}}, + {2043, {wxTreeCtrl, getItemTextColour, 1}}, + {2044, {wxTreeCtrl, getLastChild, 1}}, + {2045, {wxTreeCtrl, getNextSibling, 1}}, + {2046, {wxTreeCtrl, getNextVisible, 1}}, + {2047, {wxTreeCtrl, getItemParent, 1}}, + {2048, {wxTreeCtrl, getPrevSibling, 1}}, + {2049, {wxTreeCtrl, getPrevVisible, 1}}, + {2050, {wxTreeCtrl, getRootItem, 0}}, + {2051, {wxTreeCtrl, getSelection, 0}}, + {2052, {wxTreeCtrl, getSelections, 1}}, + {2053, {wxTreeCtrl, getStateImageList, 0}}, + {2054, {wxTreeCtrl, hitTest, 2}}, + {2056, {wxTreeCtrl, insertItem, 4}}, + {2057, {wxTreeCtrl, isBold, 1}}, + {2058, {wxTreeCtrl, isExpanded, 1}}, + {2059, {wxTreeCtrl, isSelected, 1}}, + {2060, {wxTreeCtrl, isVisible, 1}}, + {2061, {wxTreeCtrl, itemHasChildren, 1}}, + {2062, {wxTreeCtrl, isTreeItemIdOk, 1}}, + {2063, {wxTreeCtrl, prependItem, 3}}, + {2064, {wxTreeCtrl, scrollTo, 1}}, + {2065, {wxTreeCtrl, selectItem_1, 1}}, + {2066, {wxTreeCtrl, selectItem_2, 2}}, + {2067, {wxTreeCtrl, setIndent, 1}}, + {2068, {wxTreeCtrl, setImageList, 1}}, + {2069, {wxTreeCtrl, setItemBackgroundColour, 2}}, + {2070, {wxTreeCtrl, setItemBold, 2}}, + {2071, {wxTreeCtrl, setItemData, 2}}, + {2072, {wxTreeCtrl, setItemDropHighlight, 2}}, + {2073, {wxTreeCtrl, setItemFont, 2}}, + {2074, {wxTreeCtrl, setItemHasChildren, 2}}, + {2075, {wxTreeCtrl, setItemImage_2, 2}}, + {2076, {wxTreeCtrl, setItemImage_3, 3}}, + {2077, {wxTreeCtrl, setItemText, 2}}, + {2078, {wxTreeCtrl, setItemTextColour, 2}}, + {2079, {wxTreeCtrl, setStateImageList, 1}}, + {2080, {wxTreeCtrl, setWindowStyle, 1}}, + {2081, {wxTreeCtrl, sortChildren, 1}}, + {2082, {wxTreeCtrl, toggle, 1}}, + {2083, {wxTreeCtrl, toggleItemSelection, 1}}, + {2084, {wxTreeCtrl, unselect, 0}}, + {2085, {wxTreeCtrl, unselectAll, 0}}, + {2086, {wxTreeCtrl, unselectItem, 1}}, + {2087, {wxScrollBar, new_0, 0}}, + {2088, {wxScrollBar, new_3, 3}}, + {2089, {wxScrollBar, destruct, 0}}, + {2090, {wxScrollBar, create, 3}}, + {2091, {wxScrollBar, getRange, 0}}, + {2092, {wxScrollBar, getPageSize, 0}}, + {2093, {wxScrollBar, getThumbPosition, 0}}, + {2094, {wxScrollBar, getThumbSize, 0}}, + {2095, {wxScrollBar, setThumbPosition, 1}}, + {2096, {wxScrollBar, setScrollbar, 5}}, + {2098, {wxSpinButton, new_2, 2}}, + {2099, {wxSpinButton, new_0, 0}}, + {2100, {wxSpinButton, create, 2}}, + {2101, {wxSpinButton, getMax, 0}}, + {2102, {wxSpinButton, getMin, 0}}, + {2103, {wxSpinButton, getValue, 0}}, + {2104, {wxSpinButton, setRange, 2}}, + {2105, {wxSpinButton, setValue, 1}}, + {2106, {wxSpinButton, 'Destroy', undefined}}, + {2107, {wxSpinCtrl, new_0, 0}}, + {2108, {wxSpinCtrl, new_2, 2}}, + {2110, {wxSpinCtrl, create, 2}}, + {2113, {wxSpinCtrl, setValue_1_1, 1}}, + {2114, {wxSpinCtrl, setValue_1_0, 1}}, + {2116, {wxSpinCtrl, getValue, 0}}, + {2118, {wxSpinCtrl, setRange, 2}}, + {2119, {wxSpinCtrl, setSelection, 2}}, + {2121, {wxSpinCtrl, getMin, 0}}, + {2123, {wxSpinCtrl, getMax, 0}}, + {2124, {wxSpinCtrl, 'Destroy', undefined}}, + {2125, {wxStaticText, new_0, 0}}, + {2126, {wxStaticText, new_4, 4}}, + {2127, {wxStaticText, create, 4}}, + {2128, {wxStaticText, getLabel, 0}}, + {2129, {wxStaticText, setLabel, 1}}, + {2130, {wxStaticText, wrap, 1}}, + {2131, {wxStaticText, 'Destroy', undefined}}, + {2132, {wxStaticBitmap, new_0, 0}}, + {2133, {wxStaticBitmap, new_4, 4}}, + {2134, {wxStaticBitmap, create, 4}}, + {2135, {wxStaticBitmap, getBitmap, 0}}, + {2136, {wxStaticBitmap, setBitmap, 1}}, + {2137, {wxStaticBitmap, 'Destroy', undefined}}, + {2138, {wxRadioBox, new, 7}}, + {2140, {wxRadioBox, destruct, 0}}, + {2141, {wxRadioBox, create, 7}}, + {2142, {wxRadioBox, enable_2, 2}}, + {2143, {wxRadioBox, enable_1, 1}}, + {2144, {wxRadioBox, getSelection, 0}}, + {2145, {wxRadioBox, getString, 1}}, + {2146, {wxRadioBox, setSelection, 1}}, + {2147, {wxRadioBox, show_2, 2}}, + {2148, {wxRadioBox, show_1, 1}}, + {2149, {wxRadioBox, getColumnCount, 0}}, + {2150, {wxRadioBox, getItemHelpText, 1}}, + {2151, {wxRadioBox, getItemToolTip, 1}}, + {2153, {wxRadioBox, getItemFromPoint, 1}}, + {2154, {wxRadioBox, getRowCount, 0}}, + {2155, {wxRadioBox, isItemEnabled, 1}}, + {2156, {wxRadioBox, isItemShown, 1}}, + {2157, {wxRadioBox, setItemHelpText, 2}}, + {2158, {wxRadioBox, setItemToolTip, 2}}, + {2159, {wxRadioButton, new_0, 0}}, + {2160, {wxRadioButton, new_4, 4}}, + {2161, {wxRadioButton, create, 4}}, + {2162, {wxRadioButton, getValue, 0}}, + {2163, {wxRadioButton, setValue, 1}}, + {2164, {wxRadioButton, 'Destroy', undefined}}, + {2166, {wxSlider, new_6, 6}}, + {2167, {wxSlider, new_0, 0}}, + {2168, {wxSlider, create, 6}}, + {2169, {wxSlider, getLineSize, 0}}, + {2170, {wxSlider, getMax, 0}}, + {2171, {wxSlider, getMin, 0}}, + {2172, {wxSlider, getPageSize, 0}}, + {2173, {wxSlider, getThumbLength, 0}}, + {2174, {wxSlider, getValue, 0}}, + {2175, {wxSlider, setLineSize, 1}}, + {2176, {wxSlider, setPageSize, 1}}, + {2177, {wxSlider, setRange, 2}}, + {2178, {wxSlider, setThumbLength, 1}}, + {2179, {wxSlider, setValue, 1}}, + {2180, {wxSlider, 'Destroy', undefined}}, + {2182, {wxDialog, new_4, 4}}, + {2183, {wxDialog, new_0, 0}}, + {2185, {wxDialog, destruct, 0}}, + {2186, {wxDialog, create, 4}}, + {2187, {wxDialog, createButtonSizer, 1}}, + {2188, {wxDialog, createStdDialogButtonSizer, 1}}, + {2189, {wxDialog, endModal, 1}}, + {2190, {wxDialog, getAffirmativeId, 0}}, + {2191, {wxDialog, getReturnCode, 0}}, + {2192, {wxDialog, isModal, 0}}, + {2193, {wxDialog, setAffirmativeId, 1}}, + {2194, {wxDialog, setReturnCode, 1}}, + {2195, {wxDialog, show, 1}}, + {2196, {wxDialog, showModal, 0}}, + {2197, {wxColourDialog, new_0, 0}}, + {2198, {wxColourDialog, new_2, 2}}, + {2199, {wxColourDialog, destruct, 0}}, + {2200, {wxColourDialog, create, 2}}, + {2201, {wxColourDialog, getColourData, 0}}, + {2202, {wxColourData, new_0, 0}}, + {2203, {wxColourData, new_1, 1}}, + {2204, {wxColourData, destruct, 0}}, + {2205, {wxColourData, getChooseFull, 0}}, + {2206, {wxColourData, getColour, 0}}, + {2208, {wxColourData, getCustomColour, 1}}, + {2209, {wxColourData, setChooseFull, 1}}, + {2210, {wxColourData, setColour, 1}}, + {2211, {wxColourData, setCustomColour, 2}}, + {2212, {wxPalette, new_0, 0}}, + {2213, {wxPalette, new_4, 4}}, + {2215, {wxPalette, destruct, 0}}, + {2216, {wxPalette, create, 4}}, + {2217, {wxPalette, getColoursCount, 0}}, + {2218, {wxPalette, getPixel, 3}}, + {2219, {wxPalette, getRGB, 4}}, + {2220, {wxPalette, isOk, 0}}, + {2224, {wxDirDialog, new, 2}}, + {2225, {wxDirDialog, destruct, 0}}, + {2226, {wxDirDialog, getPath, 0}}, + {2227, {wxDirDialog, getMessage, 0}}, + {2228, {wxDirDialog, setMessage, 1}}, + {2229, {wxDirDialog, setPath, 1}}, + {2233, {wxFileDialog, new, 2}}, + {2234, {wxFileDialog, destruct, 0}}, + {2235, {wxFileDialog, getDirectory, 0}}, + {2236, {wxFileDialog, getFilename, 0}}, + {2237, {wxFileDialog, getFilenames, 1}}, + {2238, {wxFileDialog, getFilterIndex, 0}}, + {2239, {wxFileDialog, getMessage, 0}}, + {2240, {wxFileDialog, getPath, 0}}, + {2241, {wxFileDialog, getPaths, 1}}, + {2242, {wxFileDialog, getWildcard, 0}}, + {2243, {wxFileDialog, setDirectory, 1}}, + {2244, {wxFileDialog, setFilename, 1}}, + {2245, {wxFileDialog, setFilterIndex, 1}}, + {2246, {wxFileDialog, setMessage, 1}}, + {2247, {wxFileDialog, setPath, 1}}, + {2248, {wxFileDialog, setWildcard, 1}}, + {2249, {wxPickerBase, setInternalMargin, 1}}, + {2250, {wxPickerBase, getInternalMargin, 0}}, + {2251, {wxPickerBase, setTextCtrlProportion, 1}}, + {2252, {wxPickerBase, setPickerCtrlProportion, 1}}, + {2253, {wxPickerBase, getTextCtrlProportion, 0}}, + {2254, {wxPickerBase, getPickerCtrlProportion, 0}}, + {2255, {wxPickerBase, hasTextCtrl, 0}}, + {2256, {wxPickerBase, getTextCtrl, 0}}, + {2257, {wxPickerBase, isTextCtrlGrowable, 0}}, + {2258, {wxPickerBase, setPickerCtrlGrowable, 1}}, + {2259, {wxPickerBase, setTextCtrlGrowable, 1}}, + {2260, {wxPickerBase, isPickerCtrlGrowable, 0}}, + {2261, {wxFilePickerCtrl, new_0, 0}}, + {2262, {wxFilePickerCtrl, new_3, 3}}, + {2263, {wxFilePickerCtrl, create, 3}}, + {2264, {wxFilePickerCtrl, getPath, 0}}, + {2265, {wxFilePickerCtrl, setPath, 1}}, + {2266, {wxFilePickerCtrl, 'Destroy', undefined}}, + {2267, {wxDirPickerCtrl, new_0, 0}}, + {2268, {wxDirPickerCtrl, new_3, 3}}, + {2269, {wxDirPickerCtrl, create, 3}}, + {2270, {wxDirPickerCtrl, getPath, 0}}, + {2271, {wxDirPickerCtrl, setPath, 1}}, + {2272, {wxDirPickerCtrl, 'Destroy', undefined}}, + {2273, {wxColourPickerCtrl, new_0, 0}}, + {2274, {wxColourPickerCtrl, new_3, 3}}, + {2275, {wxColourPickerCtrl, create, 3}}, + {2276, {wxColourPickerCtrl, getColour, 0}}, + {2277, {wxColourPickerCtrl, setColour_1_1, 1}}, + {2278, {wxColourPickerCtrl, setColour_1_0, 1}}, + {2279, {wxColourPickerCtrl, 'Destroy', undefined}}, + {2280, {wxDatePickerCtrl, new_0, 0}}, + {2281, {wxDatePickerCtrl, new_3, 3}}, + {2282, {wxDatePickerCtrl, getRange, 2}}, + {2283, {wxDatePickerCtrl, getValue, 0}}, + {2284, {wxDatePickerCtrl, setRange, 2}}, + {2285, {wxDatePickerCtrl, setValue, 1}}, + {2286, {wxDatePickerCtrl, 'Destroy', undefined}}, + {2287, {wxFontPickerCtrl, new_0, 0}}, + {2288, {wxFontPickerCtrl, new_3, 3}}, + {2289, {wxFontPickerCtrl, create, 3}}, + {2290, {wxFontPickerCtrl, getSelectedFont, 0}}, + {2291, {wxFontPickerCtrl, setSelectedFont, 1}}, + {2292, {wxFontPickerCtrl, getMaxPointSize, 0}}, + {2293, {wxFontPickerCtrl, setMaxPointSize, 1}}, + {2294, {wxFontPickerCtrl, 'Destroy', undefined}}, + {2297, {wxFindReplaceDialog, new_0, 0}}, + {2298, {wxFindReplaceDialog, new_4, 4}}, + {2299, {wxFindReplaceDialog, destruct, 0}}, + {2300, {wxFindReplaceDialog, create, 4}}, + {2301, {wxFindReplaceDialog, getData, 0}}, + {2302, {wxFindReplaceData, new_0, 0}}, + {2303, {wxFindReplaceData, new_1, 1}}, + {2304, {wxFindReplaceData, getFindString, 0}}, + {2305, {wxFindReplaceData, getReplaceString, 0}}, + {2306, {wxFindReplaceData, getFlags, 0}}, + {2307, {wxFindReplaceData, setFlags, 1}}, + {2308, {wxFindReplaceData, setFindString, 1}}, + {2309, {wxFindReplaceData, setReplaceString, 1}}, + {2310, {wxFindReplaceData, 'Destroy', undefined}}, + {2311, {wxMultiChoiceDialog, new_0, 0}}, + {2313, {wxMultiChoiceDialog, new_5, 5}}, + {2314, {wxMultiChoiceDialog, getSelections, 0}}, + {2315, {wxMultiChoiceDialog, setSelections, 1}}, + {2316, {wxMultiChoiceDialog, 'Destroy', undefined}}, + {2317, {wxSingleChoiceDialog, new_0, 0}}, + {2319, {wxSingleChoiceDialog, new_5, 5}}, + {2320, {wxSingleChoiceDialog, getSelection, 0}}, + {2321, {wxSingleChoiceDialog, getStringSelection, 0}}, + {2322, {wxSingleChoiceDialog, setSelection, 1}}, + {2323, {wxSingleChoiceDialog, 'Destroy', undefined}}, + {2324, {wxTextEntryDialog, new, 3}}, + {2325, {wxTextEntryDialog, getValue, 0}}, + {2326, {wxTextEntryDialog, setValue, 1}}, + {2327, {wxTextEntryDialog, 'Destroy', undefined}}, + {2328, {wxPasswordEntryDialog, new, 3}}, + {2329, {wxPasswordEntryDialog, 'Destroy', undefined}}, + {2330, {wxFontData, new_0, 0}}, + {2331, {wxFontData, new_1, 1}}, + {2332, {wxFontData, destruct, 0}}, + {2333, {wxFontData, enableEffects, 1}}, + {2334, {wxFontData, getAllowSymbols, 0}}, + {2335, {wxFontData, getColour, 0}}, + {2336, {wxFontData, getChosenFont, 0}}, + {2337, {wxFontData, getEnableEffects, 0}}, + {2338, {wxFontData, getInitialFont, 0}}, + {2339, {wxFontData, getShowHelp, 0}}, + {2340, {wxFontData, setAllowSymbols, 1}}, + {2341, {wxFontData, setChosenFont, 1}}, + {2342, {wxFontData, setColour, 1}}, + {2343, {wxFontData, setInitialFont, 1}}, + {2344, {wxFontData, setRange, 2}}, + {2345, {wxFontData, setShowHelp, 1}}, + {2349, {wxFontDialog, new_0, 0}}, + {2351, {wxFontDialog, new_2, 2}}, + {2353, {wxFontDialog, create, 2}}, + {2354, {wxFontDialog, getFontData, 0}}, + {2356, {wxFontDialog, 'Destroy', undefined}}, + {2357, {wxProgressDialog, new, 3}}, + {2358, {wxProgressDialog, destruct, 0}}, + {2359, {wxProgressDialog, resume, 0}}, + {2360, {wxProgressDialog, update_2, 2}}, + {2361, {wxProgressDialog, update_0, 0}}, + {2362, {wxMessageDialog, new, 3}}, + {2363, {wxMessageDialog, destruct, 0}}, + {2364, {wxPageSetupDialog, new, 2}}, + {2365, {wxPageSetupDialog, destruct, 0}}, + {2366, {wxPageSetupDialog, getPageSetupData, 0}}, + {2367, {wxPageSetupDialog, showModal, 0}}, + {2368, {wxPageSetupDialogData, new_0, 0}}, + {2369, {wxPageSetupDialogData, new_1_0, 1}}, + {2370, {wxPageSetupDialogData, new_1_1, 1}}, + {2371, {wxPageSetupDialogData, destruct, 0}}, + {2372, {wxPageSetupDialogData, enableHelp, 1}}, + {2373, {wxPageSetupDialogData, enableMargins, 1}}, + {2374, {wxPageSetupDialogData, enableOrientation, 1}}, + {2375, {wxPageSetupDialogData, enablePaper, 1}}, + {2376, {wxPageSetupDialogData, enablePrinter, 1}}, + {2377, {wxPageSetupDialogData, getDefaultMinMargins, 0}}, + {2378, {wxPageSetupDialogData, getEnableMargins, 0}}, + {2379, {wxPageSetupDialogData, getEnableOrientation, 0}}, + {2380, {wxPageSetupDialogData, getEnablePaper, 0}}, + {2381, {wxPageSetupDialogData, getEnablePrinter, 0}}, + {2382, {wxPageSetupDialogData, getEnableHelp, 0}}, + {2383, {wxPageSetupDialogData, getDefaultInfo, 0}}, + {2384, {wxPageSetupDialogData, getMarginTopLeft, 0}}, + {2385, {wxPageSetupDialogData, getMarginBottomRight, 0}}, + {2386, {wxPageSetupDialogData, getMinMarginTopLeft, 0}}, + {2387, {wxPageSetupDialogData, getMinMarginBottomRight, 0}}, + {2388, {wxPageSetupDialogData, getPaperId, 0}}, + {2389, {wxPageSetupDialogData, getPaperSize, 0}}, + {2391, {wxPageSetupDialogData, getPrintData, 0}}, + {2392, {wxPageSetupDialogData, isOk, 0}}, + {2393, {wxPageSetupDialogData, setDefaultInfo, 1}}, + {2394, {wxPageSetupDialogData, setDefaultMinMargins, 1}}, + {2395, {wxPageSetupDialogData, setMarginTopLeft, 1}}, + {2396, {wxPageSetupDialogData, setMarginBottomRight, 1}}, + {2397, {wxPageSetupDialogData, setMinMarginTopLeft, 1}}, + {2398, {wxPageSetupDialogData, setMinMarginBottomRight, 1}}, + {2399, {wxPageSetupDialogData, setPaperId, 1}}, + {2400, {wxPageSetupDialogData, setPaperSize_1_1, 1}}, + {2401, {wxPageSetupDialogData, setPaperSize_1_0, 1}}, + {2402, {wxPageSetupDialogData, setPrintData, 1}}, + {2403, {wxPrintDialog, new_2_0, 2}}, + {2404, {wxPrintDialog, new_2_1, 2}}, + {2405, {wxPrintDialog, destruct, 0}}, + {2406, {wxPrintDialog, getPrintDialogData, 0}}, + {2407, {wxPrintDialog, getPrintDC, 0}}, + {2408, {wxPrintDialogData, new_0, 0}}, + {2409, {wxPrintDialogData, new_1_1, 1}}, + {2410, {wxPrintDialogData, new_1_0, 1}}, + {2411, {wxPrintDialogData, destruct, 0}}, + {2412, {wxPrintDialogData, enableHelp, 1}}, + {2413, {wxPrintDialogData, enablePageNumbers, 1}}, + {2414, {wxPrintDialogData, enablePrintToFile, 1}}, + {2415, {wxPrintDialogData, enableSelection, 1}}, + {2416, {wxPrintDialogData, getAllPages, 0}}, + {2417, {wxPrintDialogData, getCollate, 0}}, + {2418, {wxPrintDialogData, getFromPage, 0}}, + {2419, {wxPrintDialogData, getMaxPage, 0}}, + {2420, {wxPrintDialogData, getMinPage, 0}}, + {2421, {wxPrintDialogData, getNoCopies, 0}}, + {2422, {wxPrintDialogData, getPrintData, 0}}, + {2423, {wxPrintDialogData, getPrintToFile, 0}}, + {2424, {wxPrintDialogData, getSelection, 0}}, + {2425, {wxPrintDialogData, getToPage, 0}}, + {2426, {wxPrintDialogData, isOk, 0}}, + {2427, {wxPrintDialogData, setCollate, 1}}, + {2428, {wxPrintDialogData, setFromPage, 1}}, + {2429, {wxPrintDialogData, setMaxPage, 1}}, + {2430, {wxPrintDialogData, setMinPage, 1}}, + {2431, {wxPrintDialogData, setNoCopies, 1}}, + {2432, {wxPrintDialogData, setPrintData, 1}}, + {2433, {wxPrintDialogData, setPrintToFile, 1}}, + {2434, {wxPrintDialogData, setSelection, 1}}, + {2435, {wxPrintDialogData, setToPage, 1}}, + {2436, {wxPrintData, new_0, 0}}, + {2437, {wxPrintData, new_1, 1}}, + {2438, {wxPrintData, destruct, 0}}, + {2439, {wxPrintData, getCollate, 0}}, + {2440, {wxPrintData, getBin, 0}}, + {2441, {wxPrintData, getColour, 0}}, + {2442, {wxPrintData, getDuplex, 0}}, + {2443, {wxPrintData, getNoCopies, 0}}, + {2444, {wxPrintData, getOrientation, 0}}, + {2445, {wxPrintData, getPaperId, 0}}, + {2446, {wxPrintData, getPrinterName, 0}}, + {2447, {wxPrintData, getQuality, 0}}, + {2448, {wxPrintData, isOk, 0}}, + {2449, {wxPrintData, setBin, 1}}, + {2450, {wxPrintData, setCollate, 1}}, + {2451, {wxPrintData, setColour, 1}}, + {2452, {wxPrintData, setDuplex, 1}}, + {2453, {wxPrintData, setNoCopies, 1}}, + {2454, {wxPrintData, setOrientation, 1}}, + {2455, {wxPrintData, setPaperId, 1}}, + {2456, {wxPrintData, setPrinterName, 1}}, + {2457, {wxPrintData, setQuality, 1}}, + {2460, {wxPrintPreview, new_2, 2}}, + {2461, {wxPrintPreview, new_3, 3}}, + {2463, {wxPrintPreview, destruct, 0}}, + {2464, {wxPrintPreview, getCanvas, 0}}, + {2465, {wxPrintPreview, getCurrentPage, 0}}, + {2466, {wxPrintPreview, getFrame, 0}}, + {2467, {wxPrintPreview, getMaxPage, 0}}, + {2468, {wxPrintPreview, getMinPage, 0}}, + {2469, {wxPrintPreview, getPrintout, 0}}, + {2470, {wxPrintPreview, getPrintoutForPrinting, 0}}, + {2471, {wxPrintPreview, isOk, 0}}, + {2472, {wxPrintPreview, paintPage, 2}}, + {2473, {wxPrintPreview, print, 1}}, + {2474, {wxPrintPreview, renderPage, 1}}, + {2475, {wxPrintPreview, setCanvas, 1}}, + {2476, {wxPrintPreview, setCurrentPage, 1}}, + {2477, {wxPrintPreview, setFrame, 1}}, + {2478, {wxPrintPreview, setPrintout, 1}}, + {2479, {wxPrintPreview, setZoom, 1}}, + {2480, {wxPreviewFrame, new, 3}}, + {2481, {wxPreviewFrame, destruct, 0}}, + {2482, {wxPreviewFrame, createControlBar, 0}}, + {2483, {wxPreviewFrame, createCanvas, 0}}, + {2484, {wxPreviewFrame, initialize, 0}}, + {2485, {wxPreviewFrame, onCloseWindow, 1}}, + {2486, {wxPreviewControlBar, new, 4}}, + {2487, {wxPreviewControlBar, destruct, 0}}, + {2488, {wxPreviewControlBar, createButtons, 0}}, + {2489, {wxPreviewControlBar, getPrintPreview, 0}}, + {2490, {wxPreviewControlBar, getZoomControl, 0}}, + {2491, {wxPreviewControlBar, setZoomControl, 1}}, + {2493, {wxPrinter, new, 1}}, + {2494, {wxPrinter, createAbortWindow, 2}}, + {2495, {wxPrinter, getAbort, 0}}, + {2496, {wxPrinter, getLastError, 0}}, + {2497, {wxPrinter, getPrintDialogData, 0}}, + {2498, {wxPrinter, print, 3}}, + {2499, {wxPrinter, printDialog, 1}}, + {2500, {wxPrinter, reportError, 3}}, + {2501, {wxPrinter, setup, 1}}, + {2502, {wxPrinter, 'Destroy', undefined}}, + {2503, {wxXmlResource, new_1, 1}}, + {2504, {wxXmlResource, new_2, 2}}, + {2505, {wxXmlResource, destruct, 0}}, + {2506, {wxXmlResource, attachUnknownControl, 3}}, + {2507, {wxXmlResource, clearHandlers, 0}}, + {2508, {wxXmlResource, compareVersion, 4}}, + {2509, {wxXmlResource, get, 0}}, + {2510, {wxXmlResource, getFlags, 0}}, + {2511, {wxXmlResource, getVersion, 0}}, + {2512, {wxXmlResource, getXRCID, 2}}, + {2513, {wxXmlResource, initAllHandlers, 0}}, + {2514, {wxXmlResource, load, 1}}, + {2515, {wxXmlResource, loadBitmap, 1}}, + {2516, {wxXmlResource, loadDialog_2, 2}}, + {2517, {wxXmlResource, loadDialog_3, 3}}, + {2518, {wxXmlResource, loadFrame_2, 2}}, + {2519, {wxXmlResource, loadFrame_3, 3}}, + {2520, {wxXmlResource, loadIcon, 1}}, + {2521, {wxXmlResource, loadMenu, 1}}, + {2522, {wxXmlResource, loadMenuBar_2, 2}}, + {2523, {wxXmlResource, loadMenuBar_1, 1}}, + {2524, {wxXmlResource, loadPanel_2, 2}}, + {2525, {wxXmlResource, loadPanel_3, 3}}, + {2526, {wxXmlResource, loadToolBar, 2}}, + {2527, {wxXmlResource, set, 1}}, + {2528, {wxXmlResource, setFlags, 1}}, + {2529, {wxXmlResource, unload, 1}}, + {2530, {wxXmlResource, xrcctrl, 3}}, + {2531, {wxHtmlEasyPrinting, new, 1}}, + {2532, {wxHtmlEasyPrinting, destruct, 0}}, + {2533, {wxHtmlEasyPrinting, getPrintData, 0}}, + {2534, {wxHtmlEasyPrinting, getPageSetupData, 0}}, + {2535, {wxHtmlEasyPrinting, previewFile, 1}}, + {2536, {wxHtmlEasyPrinting, previewText, 2}}, + {2537, {wxHtmlEasyPrinting, printFile, 1}}, + {2538, {wxHtmlEasyPrinting, printText, 2}}, + {2539, {wxHtmlEasyPrinting, pageSetup, 0}}, + {2540, {wxHtmlEasyPrinting, setFonts, 3}}, + {2541, {wxHtmlEasyPrinting, setHeader, 2}}, + {2542, {wxHtmlEasyPrinting, setFooter, 2}}, + {2544, {wxGLCanvas, new_2, 2}}, + {2545, {wxGLCanvas, new_3_1, 3}}, + {2546, {wxGLCanvas, new_3_0, 3}}, + {2547, {wxGLCanvas, getContext, 0}}, + {2549, {wxGLCanvas, setCurrent, 0}}, + {2550, {wxGLCanvas, swapBuffers, 0}}, + {2551, {wxGLCanvas, 'Destroy', undefined}}, + {2552, {wxAuiManager, new, 1}}, + {2553, {wxAuiManager, destruct, 0}}, + {2554, {wxAuiManager, addPane_2_1, 2}}, + {2555, {wxAuiManager, addPane_3, 3}}, + {2556, {wxAuiManager, addPane_2_0, 2}}, + {2557, {wxAuiManager, detachPane, 1}}, + {2558, {wxAuiManager, getAllPanes, 0}}, + {2559, {wxAuiManager, getArtProvider, 0}}, + {2560, {wxAuiManager, getDockSizeConstraint, 2}}, + {2561, {wxAuiManager, getFlags, 0}}, + {2562, {wxAuiManager, getManagedWindow, 0}}, + {2563, {wxAuiManager, getManager, 1}}, + {2564, {wxAuiManager, getPane_1_1, 1}}, + {2565, {wxAuiManager, getPane_1_0, 1}}, + {2566, {wxAuiManager, hideHint, 0}}, + {2567, {wxAuiManager, insertPane, 3}}, + {2568, {wxAuiManager, loadPaneInfo, 2}}, + {2569, {wxAuiManager, loadPerspective, 2}}, + {2570, {wxAuiManager, savePaneInfo, 1}}, + {2571, {wxAuiManager, savePerspective, 0}}, + {2572, {wxAuiManager, setArtProvider, 1}}, + {2573, {wxAuiManager, setDockSizeConstraint, 2}}, + {2574, {wxAuiManager, setFlags, 1}}, + {2575, {wxAuiManager, setManagedWindow, 1}}, + {2576, {wxAuiManager, showHint, 1}}, + {2577, {wxAuiManager, unInit, 0}}, + {2578, {wxAuiManager, update, 0}}, + {2579, {wxAuiPaneInfo, new_0, 0}}, + {2580, {wxAuiPaneInfo, new_1, 1}}, + {2581, {wxAuiPaneInfo, destruct, 0}}, + {2582, {wxAuiPaneInfo, bestSize_1, 1}}, + {2583, {wxAuiPaneInfo, bestSize_2, 2}}, + {2584, {wxAuiPaneInfo, bottom, 0}}, + {2585, {wxAuiPaneInfo, bottomDockable, 1}}, + {2586, {wxAuiPaneInfo, caption, 1}}, + {2587, {wxAuiPaneInfo, captionVisible, 1}}, + {2588, {wxAuiPaneInfo, centre, 0}}, + {2589, {wxAuiPaneInfo, centrePane, 0}}, + {2590, {wxAuiPaneInfo, closeButton, 1}}, + {2591, {wxAuiPaneInfo, defaultPane, 0}}, + {2592, {wxAuiPaneInfo, destroyOnClose, 1}}, + {2593, {wxAuiPaneInfo, direction, 1}}, + {2594, {wxAuiPaneInfo, dock, 0}}, + {2595, {wxAuiPaneInfo, dockable, 1}}, + {2596, {wxAuiPaneInfo, fixed, 0}}, + {2597, {wxAuiPaneInfo, float, 0}}, + {2598, {wxAuiPaneInfo, floatable, 1}}, + {2599, {wxAuiPaneInfo, floatingPosition_1, 1}}, + {2600, {wxAuiPaneInfo, floatingPosition_2, 2}}, + {2601, {wxAuiPaneInfo, floatingSize_1, 1}}, + {2602, {wxAuiPaneInfo, floatingSize_2, 2}}, + {2603, {wxAuiPaneInfo, gripper, 1}}, + {2604, {wxAuiPaneInfo, gripperTop, 1}}, + {2605, {wxAuiPaneInfo, hasBorder, 0}}, + {2606, {wxAuiPaneInfo, hasCaption, 0}}, + {2607, {wxAuiPaneInfo, hasCloseButton, 0}}, + {2608, {wxAuiPaneInfo, hasFlag, 1}}, + {2609, {wxAuiPaneInfo, hasGripper, 0}}, + {2610, {wxAuiPaneInfo, hasGripperTop, 0}}, + {2611, {wxAuiPaneInfo, hasMaximizeButton, 0}}, + {2612, {wxAuiPaneInfo, hasMinimizeButton, 0}}, + {2613, {wxAuiPaneInfo, hasPinButton, 0}}, + {2614, {wxAuiPaneInfo, hide, 0}}, + {2615, {wxAuiPaneInfo, isBottomDockable, 0}}, + {2616, {wxAuiPaneInfo, isDocked, 0}}, + {2617, {wxAuiPaneInfo, isFixed, 0}}, + {2618, {wxAuiPaneInfo, isFloatable, 0}}, + {2619, {wxAuiPaneInfo, isFloating, 0}}, + {2620, {wxAuiPaneInfo, isLeftDockable, 0}}, + {2621, {wxAuiPaneInfo, isMovable, 0}}, + {2622, {wxAuiPaneInfo, isOk, 0}}, + {2623, {wxAuiPaneInfo, isResizable, 0}}, + {2624, {wxAuiPaneInfo, isRightDockable, 0}}, + {2625, {wxAuiPaneInfo, isShown, 0}}, + {2626, {wxAuiPaneInfo, isToolbar, 0}}, + {2627, {wxAuiPaneInfo, isTopDockable, 0}}, + {2628, {wxAuiPaneInfo, layer, 1}}, + {2629, {wxAuiPaneInfo, left, 0}}, + {2630, {wxAuiPaneInfo, leftDockable, 1}}, + {2631, {wxAuiPaneInfo, maxSize_1, 1}}, + {2632, {wxAuiPaneInfo, maxSize_2, 2}}, + {2633, {wxAuiPaneInfo, maximizeButton, 1}}, + {2634, {wxAuiPaneInfo, minSize_1, 1}}, + {2635, {wxAuiPaneInfo, minSize_2, 2}}, + {2636, {wxAuiPaneInfo, minimizeButton, 1}}, + {2637, {wxAuiPaneInfo, movable, 1}}, + {2638, {wxAuiPaneInfo, name, 1}}, + {2639, {wxAuiPaneInfo, paneBorder, 1}}, + {2640, {wxAuiPaneInfo, pinButton, 1}}, + {2641, {wxAuiPaneInfo, position, 1}}, + {2642, {wxAuiPaneInfo, resizable, 1}}, + {2643, {wxAuiPaneInfo, right, 0}}, + {2644, {wxAuiPaneInfo, rightDockable, 1}}, + {2645, {wxAuiPaneInfo, row, 1}}, + {2646, {wxAuiPaneInfo, safeSet, 1}}, + {2647, {wxAuiPaneInfo, setFlag, 2}}, + {2648, {wxAuiPaneInfo, show, 1}}, + {2649, {wxAuiPaneInfo, toolbarPane, 0}}, + {2650, {wxAuiPaneInfo, top, 0}}, + {2651, {wxAuiPaneInfo, topDockable, 1}}, + {2652, {wxAuiPaneInfo, window, 1}}, + {2653, {wxAuiNotebook, new_0, 0}}, + {2654, {wxAuiNotebook, new_2, 2}}, + {2655, {wxAuiNotebook, addPage, 3}}, + {2656, {wxAuiNotebook, create, 2}}, + {2657, {wxAuiNotebook, deletePage, 1}}, + {2658, {wxAuiNotebook, getArtProvider, 0}}, + {2659, {wxAuiNotebook, getPage, 1}}, + {2660, {wxAuiNotebook, getPageBitmap, 1}}, + {2661, {wxAuiNotebook, getPageCount, 0}}, + {2662, {wxAuiNotebook, getPageIndex, 1}}, + {2663, {wxAuiNotebook, getPageText, 1}}, + {2664, {wxAuiNotebook, getSelection, 0}}, + {2665, {wxAuiNotebook, insertPage, 4}}, + {2666, {wxAuiNotebook, removePage, 1}}, + {2667, {wxAuiNotebook, setArtProvider, 1}}, + {2668, {wxAuiNotebook, setFont, 1}}, + {2669, {wxAuiNotebook, setPageBitmap, 2}}, + {2670, {wxAuiNotebook, setPageText, 2}}, + {2671, {wxAuiNotebook, setSelection, 1}}, + {2672, {wxAuiNotebook, setTabCtrlHeight, 1}}, + {2673, {wxAuiNotebook, setUniformBitmapSize, 1}}, + {2674, {wxAuiNotebook, 'Destroy', undefined}}, + {2675, {wxMDIParentFrame, new_0, 0}}, + {2676, {wxMDIParentFrame, new_4, 4}}, + {2677, {wxMDIParentFrame, destruct, 0}}, + {2678, {wxMDIParentFrame, activateNext, 0}}, + {2679, {wxMDIParentFrame, activatePrevious, 0}}, + {2680, {wxMDIParentFrame, arrangeIcons, 0}}, + {2681, {wxMDIParentFrame, cascade, 0}}, + {2682, {wxMDIParentFrame, create, 4}}, + {2683, {wxMDIParentFrame, getActiveChild, 0}}, + {2684, {wxMDIParentFrame, getClientWindow, 0}}, + {2685, {wxMDIParentFrame, tile, 1}}, + {2686, {wxMDIChildFrame, new_0, 0}}, + {2687, {wxMDIChildFrame, new_4, 4}}, + {2688, {wxMDIChildFrame, destruct, 0}}, + {2689, {wxMDIChildFrame, activate, 0}}, + {2690, {wxMDIChildFrame, create, 4}}, + {2691, {wxMDIChildFrame, maximize, 1}}, + {2692, {wxMDIChildFrame, restore, 0}}, + {2693, {wxMDIClientWindow, new_0, 0}}, + {2694, {wxMDIClientWindow, new_2, 2}}, + {2695, {wxMDIClientWindow, destruct, 0}}, + {2696, {wxMDIClientWindow, createClient, 2}}, + {2697, {wxLayoutAlgorithm, new, 0}}, + {2698, {wxLayoutAlgorithm, layoutFrame, 2}}, + {2699, {wxLayoutAlgorithm, layoutMDIFrame, 2}}, + {2700, {wxLayoutAlgorithm, layoutWindow, 2}}, + {2701, {wxLayoutAlgorithm, 'Destroy', undefined}}, + {2702, {wxEvent, getId, 0}}, + {2703, {wxEvent, getSkipped, 0}}, + {2704, {wxEvent, getTimestamp, 0}}, + {2705, {wxEvent, isCommandEvent, 0}}, + {2706, {wxEvent, resumePropagation, 1}}, + {2707, {wxEvent, shouldPropagate, 0}}, + {2708, {wxEvent, skip, 1}}, + {2709, {wxEvent, stopPropagation, 0}}, + {2710, {wxCommandEvent, getClientData, 0}}, + {2711, {wxCommandEvent, getExtraLong, 0}}, + {2712, {wxCommandEvent, getInt, 0}}, + {2713, {wxCommandEvent, getSelection, 0}}, + {2714, {wxCommandEvent, getString, 0}}, + {2715, {wxCommandEvent, isChecked, 0}}, + {2716, {wxCommandEvent, isSelection, 0}}, + {2717, {wxCommandEvent, setInt, 1}}, + {2718, {wxCommandEvent, setString, 1}}, + {2719, {wxScrollEvent, getOrientation, 0}}, + {2720, {wxScrollEvent, getPosition, 0}}, + {2721, {wxScrollWinEvent, getOrientation, 0}}, + {2722, {wxScrollWinEvent, getPosition, 0}}, + {2723, {wxMouseEvent, altDown, 0}}, + {2724, {wxMouseEvent, button, 1}}, + {2725, {wxMouseEvent, buttonDClick, 1}}, + {2726, {wxMouseEvent, buttonDown, 1}}, + {2727, {wxMouseEvent, buttonUp, 1}}, + {2728, {wxMouseEvent, cmdDown, 0}}, + {2729, {wxMouseEvent, controlDown, 0}}, + {2730, {wxMouseEvent, dragging, 0}}, + {2731, {wxMouseEvent, entering, 0}}, + {2732, {wxMouseEvent, getButton, 0}}, + {2735, {wxMouseEvent, getPosition, 0}}, + {2736, {wxMouseEvent, getLogicalPosition, 1}}, + {2737, {wxMouseEvent, getLinesPerAction, 0}}, + {2738, {wxMouseEvent, getWheelRotation, 0}}, + {2739, {wxMouseEvent, getWheelDelta, 0}}, + {2740, {wxMouseEvent, getX, 0}}, + {2741, {wxMouseEvent, getY, 0}}, + {2742, {wxMouseEvent, isButton, 0}}, + {2743, {wxMouseEvent, isPageScroll, 0}}, + {2744, {wxMouseEvent, leaving, 0}}, + {2745, {wxMouseEvent, leftDClick, 0}}, + {2746, {wxMouseEvent, leftDown, 0}}, + {2747, {wxMouseEvent, leftIsDown, 0}}, + {2748, {wxMouseEvent, leftUp, 0}}, + {2749, {wxMouseEvent, metaDown, 0}}, + {2750, {wxMouseEvent, middleDClick, 0}}, + {2751, {wxMouseEvent, middleDown, 0}}, + {2752, {wxMouseEvent, middleIsDown, 0}}, + {2753, {wxMouseEvent, middleUp, 0}}, + {2754, {wxMouseEvent, moving, 0}}, + {2755, {wxMouseEvent, rightDClick, 0}}, + {2756, {wxMouseEvent, rightDown, 0}}, + {2757, {wxMouseEvent, rightIsDown, 0}}, + {2758, {wxMouseEvent, rightUp, 0}}, + {2759, {wxMouseEvent, shiftDown, 0}}, + {2760, {wxSetCursorEvent, getCursor, 0}}, + {2761, {wxSetCursorEvent, getX, 0}}, + {2762, {wxSetCursorEvent, getY, 0}}, + {2763, {wxSetCursorEvent, hasCursor, 0}}, + {2764, {wxSetCursorEvent, setCursor, 1}}, + {2765, {wxKeyEvent, altDown, 0}}, + {2766, {wxKeyEvent, cmdDown, 0}}, + {2767, {wxKeyEvent, controlDown, 0}}, + {2768, {wxKeyEvent, getKeyCode, 0}}, + {2769, {wxKeyEvent, getModifiers, 0}}, + {2772, {wxKeyEvent, getPosition, 0}}, + {2773, {wxKeyEvent, getRawKeyCode, 0}}, + {2774, {wxKeyEvent, getRawKeyFlags, 0}}, + {2775, {wxKeyEvent, getUnicodeKey, 0}}, + {2776, {wxKeyEvent, getX, 0}}, + {2777, {wxKeyEvent, getY, 0}}, + {2778, {wxKeyEvent, hasModifiers, 0}}, + {2779, {wxKeyEvent, metaDown, 0}}, + {2780, {wxKeyEvent, shiftDown, 0}}, + {2781, {wxSizeEvent, getSize, 0}}, + {2782, {wxMoveEvent, getPosition, 0}}, + {2783, {wxEraseEvent, getDC, 0}}, + {2784, {wxFocusEvent, getWindow, 0}}, + {2785, {wxChildFocusEvent, getWindow, 0}}, + {2786, {wxMenuEvent, getMenu, 0}}, + {2787, {wxMenuEvent, getMenuId, 0}}, + {2788, {wxMenuEvent, isPopup, 0}}, + {2789, {wxCloseEvent, canVeto, 0}}, + {2790, {wxCloseEvent, getLoggingOff, 0}}, + {2791, {wxCloseEvent, setCanVeto, 1}}, + {2792, {wxCloseEvent, setLoggingOff, 1}}, + {2793, {wxCloseEvent, veto, 1}}, + {2794, {wxShowEvent, setShow, 1}}, + {2795, {wxShowEvent, getShow, 0}}, + {2796, {wxIconizeEvent, iconized, 0}}, + {2797, {wxJoystickEvent, buttonDown, 1}}, + {2798, {wxJoystickEvent, buttonIsDown, 1}}, + {2799, {wxJoystickEvent, buttonUp, 1}}, + {2800, {wxJoystickEvent, getButtonChange, 0}}, + {2801, {wxJoystickEvent, getButtonState, 0}}, + {2802, {wxJoystickEvent, getJoystick, 0}}, + {2803, {wxJoystickEvent, getPosition, 0}}, + {2804, {wxJoystickEvent, getZPosition, 0}}, + {2805, {wxJoystickEvent, isButton, 0}}, + {2806, {wxJoystickEvent, isMove, 0}}, + {2807, {wxJoystickEvent, isZMove, 0}}, + {2808, {wxUpdateUIEvent, canUpdate, 1}}, + {2809, {wxUpdateUIEvent, check, 1}}, + {2810, {wxUpdateUIEvent, enable, 1}}, + {2811, {wxUpdateUIEvent, show, 1}}, + {2812, {wxUpdateUIEvent, getChecked, 0}}, + {2813, {wxUpdateUIEvent, getEnabled, 0}}, + {2814, {wxUpdateUIEvent, getShown, 0}}, + {2815, {wxUpdateUIEvent, getSetChecked, 0}}, + {2816, {wxUpdateUIEvent, getSetEnabled, 0}}, + {2817, {wxUpdateUIEvent, getSetShown, 0}}, + {2818, {wxUpdateUIEvent, getSetText, 0}}, + {2819, {wxUpdateUIEvent, getText, 0}}, + {2820, {wxUpdateUIEvent, getMode, 0}}, + {2821, {wxUpdateUIEvent, getUpdateInterval, 0}}, + {2822, {wxUpdateUIEvent, resetUpdateTime, 0}}, + {2823, {wxUpdateUIEvent, setMode, 1}}, + {2824, {wxUpdateUIEvent, setText, 1}}, + {2825, {wxUpdateUIEvent, setUpdateInterval, 1}}, + {2826, {wxMouseCaptureChangedEvent, getCapturedWindow, 0}}, + {2827, {wxPaletteChangedEvent, setChangedWindow, 1}}, + {2828, {wxPaletteChangedEvent, getChangedWindow, 0}}, + {2829, {wxQueryNewPaletteEvent, setPaletteRealized, 1}}, + {2830, {wxQueryNewPaletteEvent, getPaletteRealized, 0}}, + {2831, {wxNavigationKeyEvent, getDirection, 0}}, + {2832, {wxNavigationKeyEvent, setDirection, 1}}, + {2833, {wxNavigationKeyEvent, isWindowChange, 0}}, + {2834, {wxNavigationKeyEvent, setWindowChange, 1}}, + {2835, {wxNavigationKeyEvent, isFromTab, 0}}, + {2836, {wxNavigationKeyEvent, setFromTab, 1}}, + {2837, {wxNavigationKeyEvent, getCurrentFocus, 0}}, + {2838, {wxNavigationKeyEvent, setCurrentFocus, 1}}, + {2839, {wxHelpEvent, getOrigin, 0}}, + {2840, {wxHelpEvent, getPosition, 0}}, + {2841, {wxHelpEvent, setOrigin, 1}}, + {2842, {wxHelpEvent, setPosition, 1}}, + {2843, {wxContextMenuEvent, getPosition, 0}}, + {2844, {wxContextMenuEvent, setPosition, 1}}, + {2845, {wxIdleEvent, canSend, 1}}, + {2846, {wxIdleEvent, getMode, 0}}, + {2847, {wxIdleEvent, requestMore, 1}}, + {2848, {wxIdleEvent, moreRequested, 0}}, + {2849, {wxIdleEvent, setMode, 1}}, + {2850, {wxGridEvent, altDown, 0}}, + {2851, {wxGridEvent, controlDown, 0}}, + {2852, {wxGridEvent, getCol, 0}}, + {2853, {wxGridEvent, getPosition, 0}}, + {2854, {wxGridEvent, getRow, 0}}, + {2855, {wxGridEvent, metaDown, 0}}, + {2856, {wxGridEvent, selecting, 0}}, + {2857, {wxGridEvent, shiftDown, 0}}, + {2858, {wxNotifyEvent, allow, 0}}, + {2859, {wxNotifyEvent, isAllowed, 0}}, + {2860, {wxNotifyEvent, veto, 0}}, + {2861, {wxSashEvent, getEdge, 0}}, + {2862, {wxSashEvent, getDragRect, 0}}, + {2863, {wxSashEvent, getDragStatus, 0}}, + {2864, {wxListEvent, getCacheFrom, 0}}, + {2865, {wxListEvent, getCacheTo, 0}}, + {2866, {wxListEvent, getKeyCode, 0}}, + {2867, {wxListEvent, getIndex, 0}}, + {2868, {wxListEvent, getColumn, 0}}, + {2869, {wxListEvent, getPoint, 0}}, + {2870, {wxListEvent, getLabel, 0}}, + {2871, {wxListEvent, getText, 0}}, + {2872, {wxListEvent, getImage, 0}}, + {2873, {wxListEvent, getData, 0}}, + {2874, {wxListEvent, getMask, 0}}, + {2875, {wxListEvent, getItem, 0}}, + {2876, {wxListEvent, isEditCancelled, 0}}, + {2877, {wxDateEvent, getDate, 0}}, + {2878, {wxCalendarEvent, getWeekDay, 0}}, + {2879, {wxFileDirPickerEvent, getPath, 0}}, + {2880, {wxColourPickerEvent, getColour, 0}}, + {2881, {wxFontPickerEvent, getFont, 0}}, + {2882, {wxStyledTextEvent, getPosition, 0}}, + {2883, {wxStyledTextEvent, getKey, 0}}, + {2884, {wxStyledTextEvent, getModifiers, 0}}, + {2885, {wxStyledTextEvent, getModificationType, 0}}, + {2886, {wxStyledTextEvent, getText, 0}}, + {2887, {wxStyledTextEvent, getLength, 0}}, + {2888, {wxStyledTextEvent, getLinesAdded, 0}}, + {2889, {wxStyledTextEvent, getLine, 0}}, + {2890, {wxStyledTextEvent, getFoldLevelNow, 0}}, + {2891, {wxStyledTextEvent, getFoldLevelPrev, 0}}, + {2892, {wxStyledTextEvent, getMargin, 0}}, + {2893, {wxStyledTextEvent, getMessage, 0}}, + {2894, {wxStyledTextEvent, getWParam, 0}}, + {2895, {wxStyledTextEvent, getLParam, 0}}, + {2896, {wxStyledTextEvent, getListType, 0}}, + {2897, {wxStyledTextEvent, getX, 0}}, + {2898, {wxStyledTextEvent, getY, 0}}, + {2899, {wxStyledTextEvent, getDragText, 0}}, + {2900, {wxStyledTextEvent, getDragAllowMove, 0}}, + {2901, {wxStyledTextEvent, getDragResult, 0}}, + {2902, {wxStyledTextEvent, getShift, 0}}, + {2903, {wxStyledTextEvent, getControl, 0}}, + {2904, {wxStyledTextEvent, getAlt, 0}}, + {2905, {utils, getKeyState, 1}}, + {2906, {utils, getMousePosition, 2}}, + {2907, {utils, getMouseState, 0}}, + {2908, {utils, setDetectableAutoRepeat, 1}}, + {2909, {utils, bell, 0}}, + {2910, {utils, findMenuItemId, 3}}, + {2911, {utils, genericFindWindowAtPoint, 1}}, + {2912, {utils, findWindowAtPoint, 1}}, + {2913, {utils, beginBusyCursor, 1}}, + {2914, {utils, endBusyCursor, 0}}, + {2915, {utils, isBusy, 0}}, + {2916, {utils, shutdown, 1}}, + {2917, {utils, shell, 1}}, + {2918, {utils, launchDefaultBrowser, 2}}, + {2919, {utils, getEmailAddress, 0}}, + {2920, {utils, getUserId, 0}}, + {2921, {utils, getHomeDir, 0}}, + {2922, {utils, newId, 0}}, + {2923, {utils, registerId, 1}}, + {2924, {utils, getCurrentId, 0}}, + {2925, {utils, getOsDescription, 0}}, + {2926, {utils, isPlatformLittleEndian, 0}}, + {2927, {utils, isPlatform64Bit, 0}}, + {2928, {wxPrintout, new, 1}}, + {2929, {wxPrintout, destruct, 0}}, + {2930, {wxPrintout, getDC, 0}}, + {2931, {wxPrintout, getPageSizeMM, 2}}, + {2932, {wxPrintout, getPageSizePixels, 2}}, + {2933, {wxPrintout, getPaperRectPixels, 0}}, + {2934, {wxPrintout, getPPIPrinter, 2}}, + {2935, {wxPrintout, getPPIScreen, 2}}, + {2936, {wxPrintout, getTitle, 0}}, + {2937, {wxPrintout, isPreview, 0}}, + {2938, {wxPrintout, fitThisSizeToPaper, 1}}, + {2939, {wxPrintout, fitThisSizeToPage, 1}}, + {2940, {wxPrintout, fitThisSizeToPageMargins, 2}}, + {2941, {wxPrintout, mapScreenSizeToPaper, 0}}, + {2942, {wxPrintout, mapScreenSizeToPage, 0}}, + {2943, {wxPrintout, mapScreenSizeToPageMargins, 1}}, + {2944, {wxPrintout, mapScreenSizeToDevice, 0}}, + {2945, {wxPrintout, getLogicalPaperRect, 0}}, + {2946, {wxPrintout, getLogicalPageRect, 0}}, + {2947, {wxPrintout, getLogicalPageMarginsRect, 1}}, + {2948, {wxPrintout, setLogicalOrigin, 2}}, + {2949, {wxPrintout, offsetLogicalOrigin, 2}}, + {2950, {wxStyledTextCtrl, new_2, 2}}, + {2951, {wxStyledTextCtrl, new_0, 0}}, + {2952, {wxStyledTextCtrl, destruct, 0}}, + {2953, {wxStyledTextCtrl, create, 2}}, + {2954, {wxStyledTextCtrl, addText, 1}}, + {2955, {wxStyledTextCtrl, addStyledText, 1}}, + {2956, {wxStyledTextCtrl, insertText, 2}}, + {2957, {wxStyledTextCtrl, clearAll, 0}}, + {2958, {wxStyledTextCtrl, clearDocumentStyle, 0}}, + {2959, {wxStyledTextCtrl, getLength, 0}}, + {2960, {wxStyledTextCtrl, getCharAt, 1}}, + {2961, {wxStyledTextCtrl, getCurrentPos, 0}}, + {2962, {wxStyledTextCtrl, getAnchor, 0}}, + {2963, {wxStyledTextCtrl, getStyleAt, 1}}, + {2964, {wxStyledTextCtrl, redo, 0}}, + {2965, {wxStyledTextCtrl, setUndoCollection, 1}}, + {2966, {wxStyledTextCtrl, selectAll, 0}}, + {2967, {wxStyledTextCtrl, setSavePoint, 0}}, + {2968, {wxStyledTextCtrl, getStyledText, 2}}, + {2969, {wxStyledTextCtrl, canRedo, 0}}, + {2970, {wxStyledTextCtrl, markerLineFromHandle, 1}}, + {2971, {wxStyledTextCtrl, markerDeleteHandle, 1}}, + {2972, {wxStyledTextCtrl, getUndoCollection, 0}}, + {2973, {wxStyledTextCtrl, getViewWhiteSpace, 0}}, + {2974, {wxStyledTextCtrl, setViewWhiteSpace, 1}}, + {2975, {wxStyledTextCtrl, positionFromPoint, 1}}, + {2976, {wxStyledTextCtrl, positionFromPointClose, 2}}, + {2977, {wxStyledTextCtrl, gotoLine, 1}}, + {2978, {wxStyledTextCtrl, gotoPos, 1}}, + {2979, {wxStyledTextCtrl, setAnchor, 1}}, + {2980, {wxStyledTextCtrl, getCurLine, 1}}, + {2981, {wxStyledTextCtrl, getEndStyled, 0}}, + {2982, {wxStyledTextCtrl, convertEOLs, 1}}, + {2983, {wxStyledTextCtrl, getEOLMode, 0}}, + {2984, {wxStyledTextCtrl, setEOLMode, 1}}, + {2985, {wxStyledTextCtrl, startStyling, 2}}, + {2986, {wxStyledTextCtrl, setStyling, 2}}, + {2987, {wxStyledTextCtrl, getBufferedDraw, 0}}, + {2988, {wxStyledTextCtrl, setBufferedDraw, 1}}, + {2989, {wxStyledTextCtrl, setTabWidth, 1}}, + {2990, {wxStyledTextCtrl, getTabWidth, 0}}, + {2991, {wxStyledTextCtrl, setCodePage, 1}}, + {2992, {wxStyledTextCtrl, markerDefine, 3}}, + {2993, {wxStyledTextCtrl, markerSetForeground, 2}}, + {2994, {wxStyledTextCtrl, markerSetBackground, 2}}, + {2995, {wxStyledTextCtrl, markerAdd, 2}}, + {2996, {wxStyledTextCtrl, markerDelete, 2}}, + {2997, {wxStyledTextCtrl, markerDeleteAll, 1}}, + {2998, {wxStyledTextCtrl, markerGet, 1}}, + {2999, {wxStyledTextCtrl, markerNext, 2}}, + {3000, {wxStyledTextCtrl, markerPrevious, 2}}, + {3001, {wxStyledTextCtrl, markerDefineBitmap, 2}}, + {3002, {wxStyledTextCtrl, markerAddSet, 2}}, + {3003, {wxStyledTextCtrl, markerSetAlpha, 2}}, + {3004, {wxStyledTextCtrl, setMarginType, 2}}, + {3005, {wxStyledTextCtrl, getMarginType, 1}}, + {3006, {wxStyledTextCtrl, setMarginWidth, 2}}, + {3007, {wxStyledTextCtrl, getMarginWidth, 1}}, + {3008, {wxStyledTextCtrl, setMarginMask, 2}}, + {3009, {wxStyledTextCtrl, getMarginMask, 1}}, + {3010, {wxStyledTextCtrl, setMarginSensitive, 2}}, + {3011, {wxStyledTextCtrl, getMarginSensitive, 1}}, + {3012, {wxStyledTextCtrl, styleClearAll, 0}}, + {3013, {wxStyledTextCtrl, styleSetForeground, 2}}, + {3014, {wxStyledTextCtrl, styleSetBackground, 2}}, + {3015, {wxStyledTextCtrl, styleSetBold, 2}}, + {3016, {wxStyledTextCtrl, styleSetItalic, 2}}, + {3017, {wxStyledTextCtrl, styleSetSize, 2}}, + {3018, {wxStyledTextCtrl, styleSetFaceName, 2}}, + {3019, {wxStyledTextCtrl, styleSetEOLFilled, 2}}, + {3020, {wxStyledTextCtrl, styleResetDefault, 0}}, + {3021, {wxStyledTextCtrl, styleSetUnderline, 2}}, + {3022, {wxStyledTextCtrl, styleSetCase, 2}}, + {3023, {wxStyledTextCtrl, styleSetHotSpot, 2}}, + {3024, {wxStyledTextCtrl, setSelForeground, 2}}, + {3025, {wxStyledTextCtrl, setSelBackground, 2}}, + {3026, {wxStyledTextCtrl, getSelAlpha, 0}}, + {3027, {wxStyledTextCtrl, setSelAlpha, 1}}, + {3028, {wxStyledTextCtrl, setCaretForeground, 1}}, + {3029, {wxStyledTextCtrl, cmdKeyAssign, 3}}, + {3030, {wxStyledTextCtrl, cmdKeyClear, 2}}, + {3031, {wxStyledTextCtrl, cmdKeyClearAll, 0}}, + {3032, {wxStyledTextCtrl, setStyleBytes, 2}}, + {3033, {wxStyledTextCtrl, styleSetVisible, 2}}, + {3034, {wxStyledTextCtrl, getCaretPeriod, 0}}, + {3035, {wxStyledTextCtrl, setCaretPeriod, 1}}, + {3036, {wxStyledTextCtrl, setWordChars, 1}}, + {3037, {wxStyledTextCtrl, beginUndoAction, 0}}, + {3038, {wxStyledTextCtrl, endUndoAction, 0}}, + {3039, {wxStyledTextCtrl, indicatorSetStyle, 2}}, + {3040, {wxStyledTextCtrl, indicatorGetStyle, 1}}, + {3041, {wxStyledTextCtrl, indicatorSetForeground, 2}}, + {3042, {wxStyledTextCtrl, indicatorGetForeground, 1}}, + {3043, {wxStyledTextCtrl, setWhitespaceForeground, 2}}, + {3044, {wxStyledTextCtrl, setWhitespaceBackground, 2}}, + {3045, {wxStyledTextCtrl, getStyleBits, 0}}, + {3046, {wxStyledTextCtrl, setLineState, 2}}, + {3047, {wxStyledTextCtrl, getLineState, 1}}, + {3048, {wxStyledTextCtrl, getMaxLineState, 0}}, + {3049, {wxStyledTextCtrl, getCaretLineVisible, 0}}, + {3050, {wxStyledTextCtrl, setCaretLineVisible, 1}}, + {3051, {wxStyledTextCtrl, getCaretLineBackground, 0}}, + {3052, {wxStyledTextCtrl, setCaretLineBackground, 1}}, + {3053, {wxStyledTextCtrl, autoCompShow, 2}}, + {3054, {wxStyledTextCtrl, autoCompCancel, 0}}, + {3055, {wxStyledTextCtrl, autoCompActive, 0}}, + {3056, {wxStyledTextCtrl, autoCompPosStart, 0}}, + {3057, {wxStyledTextCtrl, autoCompComplete, 0}}, + {3058, {wxStyledTextCtrl, autoCompStops, 1}}, + {3059, {wxStyledTextCtrl, autoCompSetSeparator, 1}}, + {3060, {wxStyledTextCtrl, autoCompGetSeparator, 0}}, + {3061, {wxStyledTextCtrl, autoCompSelect, 1}}, + {3062, {wxStyledTextCtrl, autoCompSetCancelAtStart, 1}}, + {3063, {wxStyledTextCtrl, autoCompGetCancelAtStart, 0}}, + {3064, {wxStyledTextCtrl, autoCompSetFillUps, 1}}, + {3065, {wxStyledTextCtrl, autoCompSetChooseSingle, 1}}, + {3066, {wxStyledTextCtrl, autoCompGetChooseSingle, 0}}, + {3067, {wxStyledTextCtrl, autoCompSetIgnoreCase, 1}}, + {3068, {wxStyledTextCtrl, autoCompGetIgnoreCase, 0}}, + {3069, {wxStyledTextCtrl, userListShow, 2}}, + {3070, {wxStyledTextCtrl, autoCompSetAutoHide, 1}}, + {3071, {wxStyledTextCtrl, autoCompGetAutoHide, 0}}, + {3072, {wxStyledTextCtrl, autoCompSetDropRestOfWord, 1}}, + {3073, {wxStyledTextCtrl, autoCompGetDropRestOfWord, 0}}, + {3074, {wxStyledTextCtrl, registerImage, 2}}, + {3075, {wxStyledTextCtrl, clearRegisteredImages, 0}}, + {3076, {wxStyledTextCtrl, autoCompGetTypeSeparator, 0}}, + {3077, {wxStyledTextCtrl, autoCompSetTypeSeparator, 1}}, + {3078, {wxStyledTextCtrl, autoCompSetMaxWidth, 1}}, + {3079, {wxStyledTextCtrl, autoCompGetMaxWidth, 0}}, + {3080, {wxStyledTextCtrl, autoCompSetMaxHeight, 1}}, + {3081, {wxStyledTextCtrl, autoCompGetMaxHeight, 0}}, + {3082, {wxStyledTextCtrl, setIndent, 1}}, + {3083, {wxStyledTextCtrl, getIndent, 0}}, + {3084, {wxStyledTextCtrl, setUseTabs, 1}}, + {3085, {wxStyledTextCtrl, getUseTabs, 0}}, + {3086, {wxStyledTextCtrl, setLineIndentation, 2}}, + {3087, {wxStyledTextCtrl, getLineIndentation, 1}}, + {3088, {wxStyledTextCtrl, getLineIndentPosition, 1}}, + {3089, {wxStyledTextCtrl, getColumn, 1}}, + {3090, {wxStyledTextCtrl, setUseHorizontalScrollBar, 1}}, + {3091, {wxStyledTextCtrl, getUseHorizontalScrollBar, 0}}, + {3092, {wxStyledTextCtrl, setIndentationGuides, 1}}, + {3093, {wxStyledTextCtrl, getIndentationGuides, 0}}, + {3094, {wxStyledTextCtrl, setHighlightGuide, 1}}, + {3095, {wxStyledTextCtrl, getHighlightGuide, 0}}, + {3096, {wxStyledTextCtrl, getLineEndPosition, 1}}, + {3097, {wxStyledTextCtrl, getCodePage, 0}}, + {3098, {wxStyledTextCtrl, getCaretForeground, 0}}, + {3099, {wxStyledTextCtrl, getReadOnly, 0}}, + {3100, {wxStyledTextCtrl, setCurrentPos, 1}}, + {3101, {wxStyledTextCtrl, setSelectionStart, 1}}, + {3102, {wxStyledTextCtrl, getSelectionStart, 0}}, + {3103, {wxStyledTextCtrl, setSelectionEnd, 1}}, + {3104, {wxStyledTextCtrl, getSelectionEnd, 0}}, + {3105, {wxStyledTextCtrl, setPrintMagnification, 1}}, + {3106, {wxStyledTextCtrl, getPrintMagnification, 0}}, + {3107, {wxStyledTextCtrl, setPrintColourMode, 1}}, + {3108, {wxStyledTextCtrl, getPrintColourMode, 0}}, + {3109, {wxStyledTextCtrl, findText, 4}}, + {3110, {wxStyledTextCtrl, formatRange, 7}}, + {3111, {wxStyledTextCtrl, getFirstVisibleLine, 0}}, + {3112, {wxStyledTextCtrl, getLine, 1}}, + {3113, {wxStyledTextCtrl, getLineCount, 0}}, + {3114, {wxStyledTextCtrl, setMarginLeft, 1}}, + {3115, {wxStyledTextCtrl, getMarginLeft, 0}}, + {3116, {wxStyledTextCtrl, setMarginRight, 1}}, + {3117, {wxStyledTextCtrl, getMarginRight, 0}}, + {3118, {wxStyledTextCtrl, getModify, 0}}, + {3119, {wxStyledTextCtrl, setSelection, 2}}, + {3120, {wxStyledTextCtrl, getSelectedText, 0}}, + {3121, {wxStyledTextCtrl, getTextRange, 2}}, + {3122, {wxStyledTextCtrl, hideSelection, 1}}, + {3123, {wxStyledTextCtrl, lineFromPosition, 1}}, + {3124, {wxStyledTextCtrl, positionFromLine, 1}}, + {3125, {wxStyledTextCtrl, lineScroll, 2}}, + {3126, {wxStyledTextCtrl, ensureCaretVisible, 0}}, + {3127, {wxStyledTextCtrl, replaceSelection, 1}}, + {3128, {wxStyledTextCtrl, setReadOnly, 1}}, + {3129, {wxStyledTextCtrl, canPaste, 0}}, + {3130, {wxStyledTextCtrl, canUndo, 0}}, + {3131, {wxStyledTextCtrl, emptyUndoBuffer, 0}}, + {3132, {wxStyledTextCtrl, undo, 0}}, + {3133, {wxStyledTextCtrl, cut, 0}}, + {3134, {wxStyledTextCtrl, copy, 0}}, + {3135, {wxStyledTextCtrl, paste, 0}}, + {3136, {wxStyledTextCtrl, clear, 0}}, + {3137, {wxStyledTextCtrl, setText, 1}}, + {3138, {wxStyledTextCtrl, getText, 0}}, + {3139, {wxStyledTextCtrl, getTextLength, 0}}, + {3140, {wxStyledTextCtrl, getOvertype, 0}}, + {3141, {wxStyledTextCtrl, setCaretWidth, 1}}, + {3142, {wxStyledTextCtrl, getCaretWidth, 0}}, + {3143, {wxStyledTextCtrl, setTargetStart, 1}}, + {3144, {wxStyledTextCtrl, getTargetStart, 0}}, + {3145, {wxStyledTextCtrl, setTargetEnd, 1}}, + {3146, {wxStyledTextCtrl, getTargetEnd, 0}}, + {3147, {wxStyledTextCtrl, replaceTarget, 1}}, + {3148, {wxStyledTextCtrl, searchInTarget, 1}}, + {3149, {wxStyledTextCtrl, setSearchFlags, 1}}, + {3150, {wxStyledTextCtrl, getSearchFlags, 0}}, + {3151, {wxStyledTextCtrl, callTipShow, 2}}, + {3152, {wxStyledTextCtrl, callTipCancel, 0}}, + {3153, {wxStyledTextCtrl, callTipActive, 0}}, + {3154, {wxStyledTextCtrl, callTipPosAtStart, 0}}, + {3155, {wxStyledTextCtrl, callTipSetHighlight, 2}}, + {3156, {wxStyledTextCtrl, callTipSetBackground, 1}}, + {3157, {wxStyledTextCtrl, callTipSetForeground, 1}}, + {3158, {wxStyledTextCtrl, callTipSetForegroundHighlight, 1}}, + {3159, {wxStyledTextCtrl, callTipUseStyle, 1}}, + {3160, {wxStyledTextCtrl, visibleFromDocLine, 1}}, + {3161, {wxStyledTextCtrl, docLineFromVisible, 1}}, + {3162, {wxStyledTextCtrl, wrapCount, 1}}, + {3163, {wxStyledTextCtrl, setFoldLevel, 2}}, + {3164, {wxStyledTextCtrl, getFoldLevel, 1}}, + {3165, {wxStyledTextCtrl, getLastChild, 2}}, + {3166, {wxStyledTextCtrl, getFoldParent, 1}}, + {3167, {wxStyledTextCtrl, showLines, 2}}, + {3168, {wxStyledTextCtrl, hideLines, 2}}, + {3169, {wxStyledTextCtrl, getLineVisible, 1}}, + {3170, {wxStyledTextCtrl, setFoldExpanded, 2}}, + {3171, {wxStyledTextCtrl, getFoldExpanded, 1}}, + {3172, {wxStyledTextCtrl, toggleFold, 1}}, + {3173, {wxStyledTextCtrl, ensureVisible, 1}}, + {3174, {wxStyledTextCtrl, setFoldFlags, 1}}, + {3175, {wxStyledTextCtrl, ensureVisibleEnforcePolicy, 1}}, + {3176, {wxStyledTextCtrl, setTabIndents, 1}}, + {3177, {wxStyledTextCtrl, getTabIndents, 0}}, + {3178, {wxStyledTextCtrl, setBackSpaceUnIndents, 1}}, + {3179, {wxStyledTextCtrl, getBackSpaceUnIndents, 0}}, + {3180, {wxStyledTextCtrl, setMouseDwellTime, 1}}, + {3181, {wxStyledTextCtrl, getMouseDwellTime, 0}}, + {3182, {wxStyledTextCtrl, wordStartPosition, 2}}, + {3183, {wxStyledTextCtrl, wordEndPosition, 2}}, + {3184, {wxStyledTextCtrl, setWrapMode, 1}}, + {3185, {wxStyledTextCtrl, getWrapMode, 0}}, + {3186, {wxStyledTextCtrl, setWrapVisualFlags, 1}}, + {3187, {wxStyledTextCtrl, getWrapVisualFlags, 0}}, + {3188, {wxStyledTextCtrl, setWrapVisualFlagsLocation, 1}}, + {3189, {wxStyledTextCtrl, getWrapVisualFlagsLocation, 0}}, + {3190, {wxStyledTextCtrl, setWrapStartIndent, 1}}, + {3191, {wxStyledTextCtrl, getWrapStartIndent, 0}}, + {3192, {wxStyledTextCtrl, setLayoutCache, 1}}, + {3193, {wxStyledTextCtrl, getLayoutCache, 0}}, + {3194, {wxStyledTextCtrl, setScrollWidth, 1}}, + {3195, {wxStyledTextCtrl, getScrollWidth, 0}}, + {3196, {wxStyledTextCtrl, textWidth, 2}}, + {3197, {wxStyledTextCtrl, getEndAtLastLine, 0}}, + {3198, {wxStyledTextCtrl, textHeight, 1}}, + {3199, {wxStyledTextCtrl, setUseVerticalScrollBar, 1}}, + {3200, {wxStyledTextCtrl, getUseVerticalScrollBar, 0}}, + {3201, {wxStyledTextCtrl, appendText, 1}}, + {3202, {wxStyledTextCtrl, getTwoPhaseDraw, 0}}, + {3203, {wxStyledTextCtrl, setTwoPhaseDraw, 1}}, + {3204, {wxStyledTextCtrl, targetFromSelection, 0}}, + {3205, {wxStyledTextCtrl, linesJoin, 0}}, + {3206, {wxStyledTextCtrl, linesSplit, 1}}, + {3207, {wxStyledTextCtrl, setFoldMarginColour, 2}}, + {3208, {wxStyledTextCtrl, setFoldMarginHiColour, 2}}, + {3209, {wxStyledTextCtrl, lineDown, 0}}, + {3210, {wxStyledTextCtrl, lineDownExtend, 0}}, + {3211, {wxStyledTextCtrl, lineUp, 0}}, + {3212, {wxStyledTextCtrl, lineUpExtend, 0}}, + {3213, {wxStyledTextCtrl, charLeft, 0}}, + {3214, {wxStyledTextCtrl, charLeftExtend, 0}}, + {3215, {wxStyledTextCtrl, charRight, 0}}, + {3216, {wxStyledTextCtrl, charRightExtend, 0}}, + {3217, {wxStyledTextCtrl, wordLeft, 0}}, + {3218, {wxStyledTextCtrl, wordLeftExtend, 0}}, + {3219, {wxStyledTextCtrl, wordRight, 0}}, + {3220, {wxStyledTextCtrl, wordRightExtend, 0}}, + {3221, {wxStyledTextCtrl, home, 0}}, + {3222, {wxStyledTextCtrl, homeExtend, 0}}, + {3223, {wxStyledTextCtrl, lineEnd, 0}}, + {3224, {wxStyledTextCtrl, lineEndExtend, 0}}, + {3225, {wxStyledTextCtrl, documentStart, 0}}, + {3226, {wxStyledTextCtrl, documentStartExtend, 0}}, + {3227, {wxStyledTextCtrl, documentEnd, 0}}, + {3228, {wxStyledTextCtrl, documentEndExtend, 0}}, + {3229, {wxStyledTextCtrl, pageUp, 0}}, + {3230, {wxStyledTextCtrl, pageUpExtend, 0}}, + {3231, {wxStyledTextCtrl, pageDown, 0}}, + {3232, {wxStyledTextCtrl, pageDownExtend, 0}}, + {3233, {wxStyledTextCtrl, editToggleOvertype, 0}}, + {3234, {wxStyledTextCtrl, cancel, 0}}, + {3235, {wxStyledTextCtrl, deleteBack, 0}}, + {3236, {wxStyledTextCtrl, tab, 0}}, + {3237, {wxStyledTextCtrl, backTab, 0}}, + {3238, {wxStyledTextCtrl, newLine, 0}}, + {3239, {wxStyledTextCtrl, formFeed, 0}}, + {3240, {wxStyledTextCtrl, vCHome, 0}}, + {3241, {wxStyledTextCtrl, vCHomeExtend, 0}}, + {3242, {wxStyledTextCtrl, zoomIn, 0}}, + {3243, {wxStyledTextCtrl, zoomOut, 0}}, + {3244, {wxStyledTextCtrl, delWordLeft, 0}}, + {3245, {wxStyledTextCtrl, delWordRight, 0}}, + {3246, {wxStyledTextCtrl, lineCut, 0}}, + {3247, {wxStyledTextCtrl, lineDelete, 0}}, + {3248, {wxStyledTextCtrl, lineTranspose, 0}}, + {3249, {wxStyledTextCtrl, lineDuplicate, 0}}, + {3250, {wxStyledTextCtrl, lowerCase, 0}}, + {3251, {wxStyledTextCtrl, upperCase, 0}}, + {3252, {wxStyledTextCtrl, lineScrollDown, 0}}, + {3253, {wxStyledTextCtrl, lineScrollUp, 0}}, + {3254, {wxStyledTextCtrl, deleteBackNotLine, 0}}, + {3255, {wxStyledTextCtrl, homeDisplay, 0}}, + {3256, {wxStyledTextCtrl, homeDisplayExtend, 0}}, + {3257, {wxStyledTextCtrl, lineEndDisplay, 0}}, + {3258, {wxStyledTextCtrl, lineEndDisplayExtend, 0}}, + {3259, {wxStyledTextCtrl, homeWrapExtend, 0}}, + {3260, {wxStyledTextCtrl, lineEndWrap, 0}}, + {3261, {wxStyledTextCtrl, lineEndWrapExtend, 0}}, + {3262, {wxStyledTextCtrl, vCHomeWrap, 0}}, + {3263, {wxStyledTextCtrl, vCHomeWrapExtend, 0}}, + {3264, {wxStyledTextCtrl, lineCopy, 0}}, + {3265, {wxStyledTextCtrl, moveCaretInsideView, 0}}, + {3266, {wxStyledTextCtrl, lineLength, 1}}, + {3267, {wxStyledTextCtrl, braceHighlight, 2}}, + {3268, {wxStyledTextCtrl, braceBadLight, 1}}, + {3269, {wxStyledTextCtrl, braceMatch, 1}}, + {3270, {wxStyledTextCtrl, getViewEOL, 0}}, + {3271, {wxStyledTextCtrl, setViewEOL, 1}}, + {3272, {wxStyledTextCtrl, setModEventMask, 1}}, + {3273, {wxStyledTextCtrl, getEdgeColumn, 0}}, + {3274, {wxStyledTextCtrl, setEdgeColumn, 1}}, + {3275, {wxStyledTextCtrl, setEdgeMode, 1}}, + {3276, {wxStyledTextCtrl, getEdgeMode, 0}}, + {3277, {wxStyledTextCtrl, getEdgeColour, 0}}, + {3278, {wxStyledTextCtrl, setEdgeColour, 1}}, + {3279, {wxStyledTextCtrl, searchAnchor, 0}}, + {3280, {wxStyledTextCtrl, searchNext, 2}}, + {3281, {wxStyledTextCtrl, searchPrev, 2}}, + {3282, {wxStyledTextCtrl, linesOnScreen, 0}}, + {3283, {wxStyledTextCtrl, usePopUp, 1}}, + {3284, {wxStyledTextCtrl, selectionIsRectangle, 0}}, + {3285, {wxStyledTextCtrl, setZoom, 1}}, + {3286, {wxStyledTextCtrl, getZoom, 0}}, + {3287, {wxStyledTextCtrl, getModEventMask, 0}}, + {3288, {wxStyledTextCtrl, setSTCFocus, 1}}, + {3289, {wxStyledTextCtrl, getSTCFocus, 0}}, + {3290, {wxStyledTextCtrl, setStatus, 1}}, + {3291, {wxStyledTextCtrl, getStatus, 0}}, + {3292, {wxStyledTextCtrl, setMouseDownCaptures, 1}}, + {3293, {wxStyledTextCtrl, getMouseDownCaptures, 0}}, + {3294, {wxStyledTextCtrl, setSTCCursor, 1}}, + {3295, {wxStyledTextCtrl, getSTCCursor, 0}}, + {3296, {wxStyledTextCtrl, setControlCharSymbol, 1}}, + {3297, {wxStyledTextCtrl, getControlCharSymbol, 0}}, + {3298, {wxStyledTextCtrl, wordPartLeft, 0}}, + {3299, {wxStyledTextCtrl, wordPartLeftExtend, 0}}, + {3300, {wxStyledTextCtrl, wordPartRight, 0}}, + {3301, {wxStyledTextCtrl, wordPartRightExtend, 0}}, + {3302, {wxStyledTextCtrl, setVisiblePolicy, 2}}, + {3303, {wxStyledTextCtrl, delLineLeft, 0}}, + {3304, {wxStyledTextCtrl, delLineRight, 0}}, + {3305, {wxStyledTextCtrl, getXOffset, 0}}, + {3306, {wxStyledTextCtrl, chooseCaretX, 0}}, + {3307, {wxStyledTextCtrl, setXCaretPolicy, 2}}, + {3308, {wxStyledTextCtrl, setYCaretPolicy, 2}}, + {3309, {wxStyledTextCtrl, getPrintWrapMode, 0}}, + {3310, {wxStyledTextCtrl, setHotspotActiveForeground, 2}}, + {3311, {wxStyledTextCtrl, setHotspotActiveBackground, 2}}, + {3312, {wxStyledTextCtrl, setHotspotActiveUnderline, 1}}, + {3313, {wxStyledTextCtrl, setHotspotSingleLine, 1}}, + {3314, {wxStyledTextCtrl, paraDownExtend, 0}}, + {3315, {wxStyledTextCtrl, paraUp, 0}}, + {3316, {wxStyledTextCtrl, paraUpExtend, 0}}, + {3317, {wxStyledTextCtrl, positionBefore, 1}}, + {3318, {wxStyledTextCtrl, positionAfter, 1}}, + {3319, {wxStyledTextCtrl, copyRange, 2}}, + {3320, {wxStyledTextCtrl, copyText, 2}}, + {3321, {wxStyledTextCtrl, setSelectionMode, 1}}, + {3322, {wxStyledTextCtrl, getSelectionMode, 0}}, + {3323, {wxStyledTextCtrl, lineDownRectExtend, 0}}, + {3324, {wxStyledTextCtrl, lineUpRectExtend, 0}}, + {3325, {wxStyledTextCtrl, charLeftRectExtend, 0}}, + {3326, {wxStyledTextCtrl, charRightRectExtend, 0}}, + {3327, {wxStyledTextCtrl, homeRectExtend, 0}}, + {3328, {wxStyledTextCtrl, vCHomeRectExtend, 0}}, + {3329, {wxStyledTextCtrl, lineEndRectExtend, 0}}, + {3330, {wxStyledTextCtrl, pageUpRectExtend, 0}}, + {3331, {wxStyledTextCtrl, pageDownRectExtend, 0}}, + {3332, {wxStyledTextCtrl, stutteredPageUp, 0}}, + {3333, {wxStyledTextCtrl, stutteredPageUpExtend, 0}}, + {3334, {wxStyledTextCtrl, stutteredPageDown, 0}}, + {3335, {wxStyledTextCtrl, stutteredPageDownExtend, 0}}, + {3336, {wxStyledTextCtrl, wordLeftEnd, 0}}, + {3337, {wxStyledTextCtrl, wordLeftEndExtend, 0}}, + {3338, {wxStyledTextCtrl, wordRightEnd, 0}}, + {3339, {wxStyledTextCtrl, wordRightEndExtend, 0}}, + {3340, {wxStyledTextCtrl, setWhitespaceChars, 1}}, + {3341, {wxStyledTextCtrl, setCharsDefault, 0}}, + {3342, {wxStyledTextCtrl, autoCompGetCurrent, 0}}, + {3343, {wxStyledTextCtrl, allocate, 1}}, + {3344, {wxStyledTextCtrl, findColumn, 2}}, + {3345, {wxStyledTextCtrl, getCaretSticky, 0}}, + {3346, {wxStyledTextCtrl, setCaretSticky, 1}}, + {3347, {wxStyledTextCtrl, toggleCaretSticky, 0}}, + {3348, {wxStyledTextCtrl, setPasteConvertEndings, 1}}, + {3349, {wxStyledTextCtrl, getPasteConvertEndings, 0}}, + {3350, {wxStyledTextCtrl, selectionDuplicate, 0}}, + {3351, {wxStyledTextCtrl, setCaretLineBackAlpha, 1}}, + {3352, {wxStyledTextCtrl, getCaretLineBackAlpha, 0}}, + {3353, {wxStyledTextCtrl, startRecord, 0}}, + {3354, {wxStyledTextCtrl, stopRecord, 0}}, + {3355, {wxStyledTextCtrl, setLexer, 1}}, + {3356, {wxStyledTextCtrl, getLexer, 0}}, + {3357, {wxStyledTextCtrl, colourise, 2}}, + {3358, {wxStyledTextCtrl, setProperty, 2}}, + {3359, {wxStyledTextCtrl, setKeyWords, 2}}, + {3360, {wxStyledTextCtrl, setLexerLanguage, 1}}, + {3361, {wxStyledTextCtrl, getProperty, 1}}, + {3362, {wxStyledTextCtrl, getStyleBitsNeeded, 0}}, + {3363, {wxStyledTextCtrl, getCurrentLine, 0}}, + {3364, {wxStyledTextCtrl, styleSetSpec, 2}}, + {3365, {wxStyledTextCtrl, styleSetFont, 2}}, + {3366, {wxStyledTextCtrl, styleSetFontAttr, 7}}, + {3367, {wxStyledTextCtrl, styleSetCharacterSet, 2}}, + {3368, {wxStyledTextCtrl, styleSetFontEncoding, 2}}, + {3369, {wxStyledTextCtrl, cmdKeyExecute, 1}}, + {3370, {wxStyledTextCtrl, setMargins, 2}}, + {3371, {wxStyledTextCtrl, getSelection, 2}}, + {3372, {wxStyledTextCtrl, pointFromPosition, 1}}, + {3373, {wxStyledTextCtrl, scrollToLine, 1}}, + {3374, {wxStyledTextCtrl, scrollToColumn, 1}}, + {3375, {wxStyledTextCtrl, setVScrollBar, 1}}, + {3376, {wxStyledTextCtrl, setHScrollBar, 1}}, + {3377, {wxStyledTextCtrl, getLastKeydownProcessed, 0}}, + {3378, {wxStyledTextCtrl, setLastKeydownProcessed, 1}}, + {3379, {wxStyledTextCtrl, saveFile, 1}}, + {3380, {wxStyledTextCtrl, loadFile, 1}}, + {3381, {wxStyledTextCtrl, doDragOver, 3}}, + {3382, {wxStyledTextCtrl, doDropText, 3}}, + {3383, {wxStyledTextCtrl, getUseAntiAliasing, 0}}, + {3384, {wxStyledTextCtrl, addTextRaw, 1}}, + {3385, {wxStyledTextCtrl, insertTextRaw, 2}}, + {3386, {wxStyledTextCtrl, getCurLineRaw, 1}}, + {3387, {wxStyledTextCtrl, getLineRaw, 1}}, + {3388, {wxStyledTextCtrl, getSelectedTextRaw, 0}}, + {3389, {wxStyledTextCtrl, getTextRangeRaw, 2}}, + {3390, {wxStyledTextCtrl, setTextRaw, 1}}, + {3391, {wxStyledTextCtrl, getTextRaw, 0}}, + {3392, {wxStyledTextCtrl, appendTextRaw, 1}}, + {3393, {wxArtProvider, getBitmap, 2}}, + {3394, {wxArtProvider, getIcon, 2}}, + {3395, {wxTreeEvent, getKeyCode, 0}}, + {3396, {wxTreeEvent, getItem, 0}}, + {3397, {wxTreeEvent, getKeyEvent, 0}}, + {3398, {wxTreeEvent, getLabel, 0}}, + {3399, {wxTreeEvent, getOldItem, 0}}, + {3400, {wxTreeEvent, getPoint, 0}}, + {3401, {wxTreeEvent, isEditCancelled, 0}}, + {3402, {wxTreeEvent, setToolTip, 1}}, + {3403, {wxNotebookEvent, getOldSelection, 0}}, + {3404, {wxNotebookEvent, getSelection, 0}}, + {3405, {wxNotebookEvent, setOldSelection, 1}}, + {3406, {wxNotebookEvent, setSelection, 1}}, + {3407, {wxFileDataObject, new, 0}}, + {3408, {wxFileDataObject, addFile, 1}}, + {3409, {wxFileDataObject, getFilenames, 0}}, + {3410, {wxFileDataObject, 'Destroy', undefined}}, + {3411, {wxTextDataObject, new, 1}}, + {3412, {wxTextDataObject, getTextLength, 0}}, + {3413, {wxTextDataObject, getText, 0}}, + {3414, {wxTextDataObject, setText, 1}}, + {3415, {wxTextDataObject, 'Destroy', undefined}}, + {3416, {wxBitmapDataObject, new_1_1, 1}}, + {3417, {wxBitmapDataObject, new_1_0, 1}}, + {3418, {wxBitmapDataObject, getBitmap, 0}}, + {3419, {wxBitmapDataObject, setBitmap, 1}}, + {3420, {wxBitmapDataObject, 'Destroy', undefined}}, + {3422, {wxClipboard, new, 0}}, + {3423, {wxClipboard, destruct, 0}}, + {3424, {wxClipboard, addData, 1}}, + {3425, {wxClipboard, clear, 0}}, + {3426, {wxClipboard, close, 0}}, + {3427, {wxClipboard, flush, 0}}, + {3428, {wxClipboard, getData, 1}}, + {3429, {wxClipboard, isOpened, 0}}, + {3430, {wxClipboard, open, 0}}, + {3431, {wxClipboard, setData, 1}}, + {3433, {wxClipboard, usePrimarySelection, 1}}, + {3434, {wxClipboard, isSupported, 1}}, + {3435, {wxClipboard, get, 0}}, + {3436, {wxSpinEvent, getPosition, 0}}, + {3437, {wxSpinEvent, setPosition, 1}}, + {3438, {wxSplitterWindow, new_0, 0}}, + {3439, {wxSplitterWindow, new_2, 2}}, + {3440, {wxSplitterWindow, destruct, 0}}, + {3441, {wxSplitterWindow, create, 2}}, + {3442, {wxSplitterWindow, getMinimumPaneSize, 0}}, + {3443, {wxSplitterWindow, getSashGravity, 0}}, + {3444, {wxSplitterWindow, getSashPosition, 0}}, + {3445, {wxSplitterWindow, getSplitMode, 0}}, + {3446, {wxSplitterWindow, getWindow1, 0}}, + {3447, {wxSplitterWindow, getWindow2, 0}}, + {3448, {wxSplitterWindow, initialize, 1}}, + {3449, {wxSplitterWindow, isSplit, 0}}, + {3450, {wxSplitterWindow, replaceWindow, 2}}, + {3451, {wxSplitterWindow, setSashGravity, 1}}, + {3452, {wxSplitterWindow, setSashPosition, 2}}, + {3453, {wxSplitterWindow, setSashSize, 1}}, + {3454, {wxSplitterWindow, setMinimumPaneSize, 1}}, + {3455, {wxSplitterWindow, setSplitMode, 1}}, + {3456, {wxSplitterWindow, splitHorizontally, 3}}, + {3457, {wxSplitterWindow, splitVertically, 3}}, + {3458, {wxSplitterWindow, unsplit, 1}}, + {3459, {wxSplitterWindow, updateSize, 0}}, + {3460, {wxSplitterEvent, getSashPosition, 0}}, + {3461, {wxSplitterEvent, getX, 0}}, + {3462, {wxSplitterEvent, getY, 0}}, + {3463, {wxSplitterEvent, getWindowBeingRemoved, 0}}, + {3464, {wxSplitterEvent, setSashPosition, 1}}, + {3465, {wxHtmlWindow, new_0, 0}}, + {3466, {wxHtmlWindow, new_2, 2}}, + {3467, {wxHtmlWindow, appendToPage, 1}}, + {3468, {wxHtmlWindow, getOpenedAnchor, 0}}, + {3469, {wxHtmlWindow, getOpenedPage, 0}}, + {3470, {wxHtmlWindow, getOpenedPageTitle, 0}}, + {3471, {wxHtmlWindow, getRelatedFrame, 0}}, + {3472, {wxHtmlWindow, historyBack, 0}}, + {3473, {wxHtmlWindow, historyCanBack, 0}}, + {3474, {wxHtmlWindow, historyCanForward, 0}}, + {3475, {wxHtmlWindow, historyClear, 0}}, + {3476, {wxHtmlWindow, historyForward, 0}}, + {3477, {wxHtmlWindow, loadFile, 1}}, + {3478, {wxHtmlWindow, loadPage, 1}}, + {3479, {wxHtmlWindow, selectAll, 0}}, + {3480, {wxHtmlWindow, selectionToText, 0}}, + {3481, {wxHtmlWindow, selectLine, 1}}, + {3482, {wxHtmlWindow, selectWord, 1}}, + {3483, {wxHtmlWindow, setBorders, 1}}, + {3484, {wxHtmlWindow, setFonts, 3}}, + {3485, {wxHtmlWindow, setPage, 1}}, + {3486, {wxHtmlWindow, setRelatedFrame, 2}}, + {3487, {wxHtmlWindow, setRelatedStatusBar, 1}}, + {3488, {wxHtmlWindow, toText, 0}}, + {3489, {wxHtmlWindow, 'Destroy', undefined}}, + {3490, {wxHtmlLinkEvent, getLinkInfo, 0}}, + {3491, {wxSystemSettings, getColour, 1}}, + {3492, {wxSystemSettings, getFont, 1}}, + {3493, {wxSystemSettings, getMetric, 2}}, + {3494, {wxSystemSettings, getScreenType, 0}}, + {3495, {wxSystemOptions, getOption, 1}}, + {3496, {wxSystemOptions, getOptionInt, 1}}, + {3497, {wxSystemOptions, hasOption, 1}}, + {3498, {wxSystemOptions, isFalse, 1}}, + {3499, {wxSystemOptions, setOption_2_1, 2}}, + {3500, {wxSystemOptions, setOption_2_0, 2}}, + {3501, {wxAuiNotebookEvent, setSelection, 1}}, + {3502, {wxAuiNotebookEvent, getSelection, 0}}, + {3503, {wxAuiNotebookEvent, setOldSelection, 1}}, + {3504, {wxAuiNotebookEvent, getOldSelection, 0}}, + {3505, {wxAuiNotebookEvent, setDragSource, 1}}, + {3506, {wxAuiNotebookEvent, getDragSource, 0}}, + {3507, {wxAuiManagerEvent, setManager, 1}}, + {3508, {wxAuiManagerEvent, getManager, 0}}, + {3509, {wxAuiManagerEvent, setPane, 1}}, + {3510, {wxAuiManagerEvent, getPane, 0}}, + {3511, {wxAuiManagerEvent, setButton, 1}}, + {3512, {wxAuiManagerEvent, getButton, 0}}, + {3513, {wxAuiManagerEvent, setDC, 1}}, + {3514, {wxAuiManagerEvent, getDC, 0}}, + {3515, {wxAuiManagerEvent, veto, 1}}, + {3516, {wxAuiManagerEvent, getVeto, 0}}, + {3517, {wxAuiManagerEvent, setCanVeto, 1}}, + {3518, {wxAuiManagerEvent, canVeto, 0}}, + {3519, {wxLogNull, new, 0}}, + {3520, {wxLogNull, 'Destroy', undefined}}, + {3521, {wxTaskBarIcon, new, 0}}, + {3522, {wxTaskBarIcon, destruct, 0}}, + {3523, {wxTaskBarIcon, popupMenu, 1}}, + {3524, {wxTaskBarIcon, removeIcon, 0}}, + {3525, {wxTaskBarIcon, setIcon, 2}}, {-1, {mod, func, -1}} ]. diff --git a/lib/wx/src/gen/wxe_funcs.hrl b/lib/wx/src/gen/wxe_funcs.hrl index b6e507b11d..213a2e5be1 100644 --- a/lib/wx/src/gen/wxe_funcs.hrl +++ b/lib/wx/src/gen/wxe_funcs.hrl @@ -238,3066 +238,3067 @@ -define(wxPanel_new_2, 334). -define(wxPanel_destruct, 335). -define(wxPanel_InitDialog, 336). --define(wxScrolledWindow_new_0, 337). --define(wxScrolledWindow_new_2, 338). --define(wxScrolledWindow_destruct, 339). --define(wxScrolledWindow_CalcScrolledPosition_4, 340). --define(wxScrolledWindow_CalcScrolledPosition_1, 341). --define(wxScrolledWindow_CalcUnscrolledPosition_4, 342). --define(wxScrolledWindow_CalcUnscrolledPosition_1, 343). --define(wxScrolledWindow_EnableScrolling, 344). --define(wxScrolledWindow_GetScrollPixelsPerUnit, 345). --define(wxScrolledWindow_GetViewStart, 346). --define(wxScrolledWindow_DoPrepareDC, 347). --define(wxScrolledWindow_PrepareDC, 348). --define(wxScrolledWindow_Scroll, 349). --define(wxScrolledWindow_SetScrollbars, 350). --define(wxScrolledWindow_SetScrollRate, 351). --define(wxScrolledWindow_SetTargetWindow, 352). --define(wxSashWindow_new_0, 353). --define(wxSashWindow_new_2, 354). --define(wxSashWindow_destruct, 355). --define(wxSashWindow_GetSashVisible, 356). --define(wxSashWindow_GetMaximumSizeX, 357). --define(wxSashWindow_GetMaximumSizeY, 358). --define(wxSashWindow_GetMinimumSizeX, 359). --define(wxSashWindow_GetMinimumSizeY, 360). --define(wxSashWindow_SetMaximumSizeX, 361). --define(wxSashWindow_SetMaximumSizeY, 362). --define(wxSashWindow_SetMinimumSizeX, 363). --define(wxSashWindow_SetMinimumSizeY, 364). --define(wxSashWindow_SetSashVisible, 365). --define(wxSashLayoutWindow_new_0, 366). --define(wxSashLayoutWindow_new_2, 367). --define(wxSashLayoutWindow_Create, 368). --define(wxSashLayoutWindow_GetAlignment, 369). --define(wxSashLayoutWindow_GetOrientation, 370). --define(wxSashLayoutWindow_SetAlignment, 371). --define(wxSashLayoutWindow_SetDefaultSize, 372). --define(wxSashLayoutWindow_SetOrientation, 373). --define(wxSashLayoutWindow_destroy, 374). --define(wxGrid_new_0, 375). --define(wxGrid_new_3, 376). --define(wxGrid_new_4, 377). --define(wxGrid_destruct, 378). --define(wxGrid_AppendCols, 379). --define(wxGrid_AppendRows, 380). --define(wxGrid_AutoSize, 381). --define(wxGrid_AutoSizeColumn, 382). --define(wxGrid_AutoSizeColumns, 383). --define(wxGrid_AutoSizeRow, 384). --define(wxGrid_AutoSizeRows, 385). --define(wxGrid_BeginBatch, 386). --define(wxGrid_BlockToDeviceRect, 387). --define(wxGrid_CanDragColSize, 388). --define(wxGrid_CanDragRowSize, 389). --define(wxGrid_CanDragGridSize, 390). --define(wxGrid_CanEnableCellControl, 391). --define(wxGrid_CellToRect_2, 392). --define(wxGrid_CellToRect_1, 393). --define(wxGrid_ClearGrid, 394). --define(wxGrid_ClearSelection, 395). --define(wxGrid_CreateGrid, 396). --define(wxGrid_DeleteCols, 397). --define(wxGrid_DeleteRows, 398). --define(wxGrid_DisableCellEditControl, 399). --define(wxGrid_DisableDragColSize, 400). --define(wxGrid_DisableDragGridSize, 401). --define(wxGrid_DisableDragRowSize, 402). --define(wxGrid_EnableCellEditControl, 403). --define(wxGrid_EnableDragColSize, 404). --define(wxGrid_EnableDragGridSize, 405). --define(wxGrid_EnableDragRowSize, 406). --define(wxGrid_EnableEditing, 407). --define(wxGrid_EnableGridLines, 408). --define(wxGrid_EndBatch, 409). --define(wxGrid_Fit, 410). --define(wxGrid_ForceRefresh, 411). --define(wxGrid_GetBatchCount, 412). --define(wxGrid_GetCellAlignment, 413). --define(wxGrid_GetCellBackgroundColour, 414). --define(wxGrid_GetCellEditor, 415). --define(wxGrid_GetCellFont, 416). --define(wxGrid_GetCellRenderer, 417). --define(wxGrid_GetCellTextColour, 418). --define(wxGrid_GetCellValue_2, 419). --define(wxGrid_GetCellValue_1, 420). --define(wxGrid_GetColLabelAlignment, 421). --define(wxGrid_GetColLabelSize, 422). --define(wxGrid_GetColLabelValue, 423). --define(wxGrid_GetColMinimalAcceptableWidth, 424). --define(wxGrid_GetDefaultCellAlignment, 425). --define(wxGrid_GetDefaultCellBackgroundColour, 426). --define(wxGrid_GetDefaultCellFont, 427). --define(wxGrid_GetDefaultCellTextColour, 428). --define(wxGrid_GetDefaultColLabelSize, 429). --define(wxGrid_GetDefaultColSize, 430). --define(wxGrid_GetDefaultEditor, 431). --define(wxGrid_GetDefaultEditorForCell_2, 432). --define(wxGrid_GetDefaultEditorForCell_1, 433). --define(wxGrid_GetDefaultEditorForType, 434). --define(wxGrid_GetDefaultRenderer, 435). --define(wxGrid_GetDefaultRendererForCell, 436). --define(wxGrid_GetDefaultRendererForType, 437). --define(wxGrid_GetDefaultRowLabelSize, 438). --define(wxGrid_GetDefaultRowSize, 439). --define(wxGrid_GetGridCursorCol, 440). --define(wxGrid_GetGridCursorRow, 441). --define(wxGrid_GetGridLineColour, 442). --define(wxGrid_GridLinesEnabled, 443). --define(wxGrid_GetLabelBackgroundColour, 444). --define(wxGrid_GetLabelFont, 445). --define(wxGrid_GetLabelTextColour, 446). --define(wxGrid_GetNumberCols, 447). --define(wxGrid_GetNumberRows, 448). --define(wxGrid_GetOrCreateCellAttr, 449). --define(wxGrid_GetRowMinimalAcceptableHeight, 450). --define(wxGrid_GetRowLabelAlignment, 451). --define(wxGrid_GetRowLabelSize, 452). --define(wxGrid_GetRowLabelValue, 453). --define(wxGrid_GetRowSize, 454). --define(wxGrid_GetScrollLineX, 455). --define(wxGrid_GetScrollLineY, 456). --define(wxGrid_GetSelectedCells, 457). --define(wxGrid_GetSelectedCols, 458). --define(wxGrid_GetSelectedRows, 459). --define(wxGrid_GetSelectionBackground, 460). --define(wxGrid_GetSelectionBlockTopLeft, 461). --define(wxGrid_GetSelectionBlockBottomRight, 462). --define(wxGrid_GetSelectionForeground, 463). --define(wxGrid_GetViewWidth, 464). --define(wxGrid_GetGridWindow, 465). --define(wxGrid_GetGridRowLabelWindow, 466). --define(wxGrid_GetGridColLabelWindow, 467). --define(wxGrid_GetGridCornerLabelWindow, 468). --define(wxGrid_HideCellEditControl, 469). --define(wxGrid_InsertCols, 470). --define(wxGrid_InsertRows, 471). --define(wxGrid_IsCellEditControlEnabled, 472). --define(wxGrid_IsCurrentCellReadOnly, 473). --define(wxGrid_IsEditable, 474). --define(wxGrid_IsInSelection_2, 475). --define(wxGrid_IsInSelection_1, 476). --define(wxGrid_IsReadOnly, 477). --define(wxGrid_IsSelection, 478). --define(wxGrid_IsVisible_3, 479). --define(wxGrid_IsVisible_2, 480). --define(wxGrid_MakeCellVisible_2, 481). --define(wxGrid_MakeCellVisible_1, 482). --define(wxGrid_MoveCursorDown, 483). --define(wxGrid_MoveCursorLeft, 484). --define(wxGrid_MoveCursorRight, 485). --define(wxGrid_MoveCursorUp, 486). --define(wxGrid_MoveCursorDownBlock, 487). --define(wxGrid_MoveCursorLeftBlock, 488). --define(wxGrid_MoveCursorRightBlock, 489). --define(wxGrid_MoveCursorUpBlock, 490). --define(wxGrid_MovePageDown, 491). --define(wxGrid_MovePageUp, 492). --define(wxGrid_RegisterDataType, 493). --define(wxGrid_SaveEditControlValue, 494). --define(wxGrid_SelectAll, 495). --define(wxGrid_SelectBlock_5, 496). --define(wxGrid_SelectBlock_3, 497). --define(wxGrid_SelectCol, 498). --define(wxGrid_SelectRow, 499). --define(wxGrid_SetCellAlignment_4, 500). --define(wxGrid_SetCellAlignment_3, 501). --define(wxGrid_SetCellAlignment_1, 502). --define(wxGrid_SetCellBackgroundColour_3_0, 503). --define(wxGrid_SetCellBackgroundColour_1, 504). --define(wxGrid_SetCellBackgroundColour_3_1, 505). --define(wxGrid_SetCellEditor, 506). --define(wxGrid_SetCellFont, 507). --define(wxGrid_SetCellRenderer, 508). --define(wxGrid_SetCellTextColour_3_0, 509). --define(wxGrid_SetCellTextColour_3_1, 510). --define(wxGrid_SetCellTextColour_1, 511). --define(wxGrid_SetCellValue_3_0, 512). --define(wxGrid_SetCellValue_2, 513). --define(wxGrid_SetCellValue_3_1, 514). --define(wxGrid_SetColAttr, 515). --define(wxGrid_SetColFormatBool, 516). --define(wxGrid_SetColFormatNumber, 517). --define(wxGrid_SetColFormatFloat, 518). --define(wxGrid_SetColFormatCustom, 519). --define(wxGrid_SetColLabelAlignment, 520). --define(wxGrid_SetColLabelSize, 521). --define(wxGrid_SetColLabelValue, 522). --define(wxGrid_SetColMinimalWidth, 523). --define(wxGrid_SetColMinimalAcceptableWidth, 524). --define(wxGrid_SetColSize, 525). --define(wxGrid_SetDefaultCellAlignment, 526). --define(wxGrid_SetDefaultCellBackgroundColour, 527). --define(wxGrid_SetDefaultCellFont, 528). --define(wxGrid_SetDefaultCellTextColour, 529). --define(wxGrid_SetDefaultEditor, 530). --define(wxGrid_SetDefaultRenderer, 531). --define(wxGrid_SetDefaultColSize, 532). --define(wxGrid_SetDefaultRowSize, 533). --define(wxGrid_SetGridCursor, 534). --define(wxGrid_SetGridLineColour, 535). --define(wxGrid_SetLabelBackgroundColour, 536). --define(wxGrid_SetLabelFont, 537). --define(wxGrid_SetLabelTextColour, 538). --define(wxGrid_SetMargins, 539). --define(wxGrid_SetReadOnly, 540). --define(wxGrid_SetRowAttr, 541). --define(wxGrid_SetRowLabelAlignment, 542). --define(wxGrid_SetRowLabelSize, 543). --define(wxGrid_SetRowLabelValue, 544). --define(wxGrid_SetRowMinimalHeight, 545). --define(wxGrid_SetRowMinimalAcceptableHeight, 546). --define(wxGrid_SetRowSize, 547). --define(wxGrid_SetScrollLineX, 548). --define(wxGrid_SetScrollLineY, 549). --define(wxGrid_SetSelectionBackground, 550). --define(wxGrid_SetSelectionForeground, 551). --define(wxGrid_SetSelectionMode, 552). --define(wxGrid_ShowCellEditControl, 553). --define(wxGrid_XToCol, 554). --define(wxGrid_XToEdgeOfCol, 555). --define(wxGrid_YToEdgeOfRow, 556). --define(wxGrid_YToRow, 557). --define(wxGridCellRenderer_Draw, 558). --define(wxGridCellRenderer_GetBestSize, 559). --define(wxGridCellEditor_Create, 560). --define(wxGridCellEditor_IsCreated, 561). --define(wxGridCellEditor_SetSize, 562). --define(wxGridCellEditor_Show, 563). --define(wxGridCellEditor_PaintBackground, 564). --define(wxGridCellEditor_BeginEdit, 565). --define(wxGridCellEditor_EndEdit, 566). --define(wxGridCellEditor_Reset, 567). --define(wxGridCellEditor_StartingKey, 568). --define(wxGridCellEditor_StartingClick, 569). --define(wxGridCellEditor_HandleReturn, 570). --define(wxGridCellBoolRenderer_new, 571). --define(wxGridCellBoolRenderer_destroy, 572). --define(wxGridCellBoolEditor_new, 573). --define(wxGridCellBoolEditor_IsTrueValue, 574). --define(wxGridCellBoolEditor_UseStringValues, 575). --define(wxGridCellBoolEditor_destroy, 576). --define(wxGridCellFloatRenderer_new, 577). --define(wxGridCellFloatRenderer_GetPrecision, 578). --define(wxGridCellFloatRenderer_GetWidth, 579). --define(wxGridCellFloatRenderer_SetParameters, 580). --define(wxGridCellFloatRenderer_SetPrecision, 581). --define(wxGridCellFloatRenderer_SetWidth, 582). --define(wxGridCellFloatRenderer_destroy, 583). --define(wxGridCellFloatEditor_new, 584). --define(wxGridCellFloatEditor_SetParameters, 585). --define(wxGridCellFloatEditor_destroy, 586). --define(wxGridCellStringRenderer_new, 587). --define(wxGridCellStringRenderer_destroy, 588). --define(wxGridCellTextEditor_new, 589). --define(wxGridCellTextEditor_SetParameters, 590). --define(wxGridCellTextEditor_destroy, 591). --define(wxGridCellChoiceEditor_new, 593). --define(wxGridCellChoiceEditor_SetParameters, 594). --define(wxGridCellChoiceEditor_destroy, 595). --define(wxGridCellNumberRenderer_new, 596). --define(wxGridCellNumberRenderer_destroy, 597). --define(wxGridCellNumberEditor_new, 598). --define(wxGridCellNumberEditor_GetValue, 599). --define(wxGridCellNumberEditor_SetParameters, 600). --define(wxGridCellNumberEditor_destroy, 601). --define(wxGridCellAttr_SetTextColour, 602). --define(wxGridCellAttr_SetBackgroundColour, 603). --define(wxGridCellAttr_SetFont, 604). --define(wxGridCellAttr_SetAlignment, 605). --define(wxGridCellAttr_SetReadOnly, 606). --define(wxGridCellAttr_SetRenderer, 607). --define(wxGridCellAttr_SetEditor, 608). --define(wxGridCellAttr_HasTextColour, 609). --define(wxGridCellAttr_HasBackgroundColour, 610). --define(wxGridCellAttr_HasFont, 611). --define(wxGridCellAttr_HasAlignment, 612). --define(wxGridCellAttr_HasRenderer, 613). --define(wxGridCellAttr_HasEditor, 614). --define(wxGridCellAttr_GetTextColour, 615). --define(wxGridCellAttr_GetBackgroundColour, 616). --define(wxGridCellAttr_GetFont, 617). --define(wxGridCellAttr_GetAlignment, 618). --define(wxGridCellAttr_GetRenderer, 619). --define(wxGridCellAttr_GetEditor, 620). --define(wxGridCellAttr_IsReadOnly, 621). --define(wxGridCellAttr_SetDefAttr, 622). --define(wxDC_Blit, 623). --define(wxDC_CalcBoundingBox, 624). --define(wxDC_Clear, 625). --define(wxDC_ComputeScaleAndOrigin, 626). --define(wxDC_CrossHair, 627). --define(wxDC_DestroyClippingRegion, 628). --define(wxDC_DeviceToLogicalX, 629). --define(wxDC_DeviceToLogicalXRel, 630). --define(wxDC_DeviceToLogicalY, 631). --define(wxDC_DeviceToLogicalYRel, 632). --define(wxDC_DrawArc, 633). --define(wxDC_DrawBitmap, 634). --define(wxDC_DrawCheckMark, 635). --define(wxDC_DrawCircle, 636). --define(wxDC_DrawEllipse_2, 638). --define(wxDC_DrawEllipse_1, 639). --define(wxDC_DrawEllipticArc, 640). --define(wxDC_DrawIcon, 641). --define(wxDC_DrawLabel, 642). --define(wxDC_DrawLine, 643). --define(wxDC_DrawLines, 644). --define(wxDC_DrawPolygon, 646). --define(wxDC_DrawPoint, 648). --define(wxDC_DrawRectangle_2, 650). --define(wxDC_DrawRectangle_1, 651). --define(wxDC_DrawRotatedText, 652). --define(wxDC_DrawRoundedRectangle_3, 654). --define(wxDC_DrawRoundedRectangle_2, 655). --define(wxDC_DrawText, 656). --define(wxDC_EndDoc, 657). --define(wxDC_EndPage, 658). --define(wxDC_FloodFill, 659). --define(wxDC_GetBackground, 660). --define(wxDC_GetBackgroundMode, 661). --define(wxDC_GetBrush, 662). --define(wxDC_GetCharHeight, 663). --define(wxDC_GetCharWidth, 664). --define(wxDC_GetClippingBox, 665). --define(wxDC_GetFont, 667). --define(wxDC_GetLayoutDirection, 668). --define(wxDC_GetLogicalFunction, 669). --define(wxDC_GetMapMode, 670). --define(wxDC_GetMultiLineTextExtent_4, 671). --define(wxDC_GetMultiLineTextExtent_1, 672). --define(wxDC_GetPartialTextExtents, 673). --define(wxDC_GetPen, 674). --define(wxDC_GetPixel, 675). --define(wxDC_GetPPI, 676). --define(wxDC_GetSize, 678). --define(wxDC_GetSizeMM, 680). --define(wxDC_GetTextBackground, 681). --define(wxDC_GetTextExtent_4, 682). --define(wxDC_GetTextExtent_1, 683). --define(wxDC_GetTextForeground, 685). --define(wxDC_GetUserScale, 686). --define(wxDC_GradientFillConcentric_3, 687). --define(wxDC_GradientFillConcentric_4, 688). --define(wxDC_GradientFillLinear, 689). --define(wxDC_LogicalToDeviceX, 690). --define(wxDC_LogicalToDeviceXRel, 691). --define(wxDC_LogicalToDeviceY, 692). --define(wxDC_LogicalToDeviceYRel, 693). --define(wxDC_MaxX, 694). --define(wxDC_MaxY, 695). --define(wxDC_MinX, 696). --define(wxDC_MinY, 697). --define(wxDC_IsOk, 698). --define(wxDC_ResetBoundingBox, 699). --define(wxDC_SetAxisOrientation, 700). --define(wxDC_SetBackground, 701). --define(wxDC_SetBackgroundMode, 702). --define(wxDC_SetBrush, 703). --define(wxDC_SetClippingRegion_2, 705). --define(wxDC_SetClippingRegion_1_1, 706). --define(wxDC_SetClippingRegion_1_0, 707). --define(wxDC_SetDeviceOrigin, 708). --define(wxDC_SetFont, 709). --define(wxDC_SetLayoutDirection, 710). --define(wxDC_SetLogicalFunction, 711). --define(wxDC_SetMapMode, 712). --define(wxDC_SetPalette, 713). --define(wxDC_SetPen, 714). --define(wxDC_SetTextBackground, 715). --define(wxDC_SetTextForeground, 716). --define(wxDC_SetUserScale, 717). --define(wxDC_StartDoc, 718). --define(wxDC_StartPage, 719). --define(wxMirrorDC_new, 720). --define(wxMirrorDC_destroy, 721). --define(wxScreenDC_new, 722). --define(wxScreenDC_destruct, 723). --define(wxPostScriptDC_new_0, 724). --define(wxPostScriptDC_new_1, 725). --define(wxPostScriptDC_destruct, 726). --define(wxPostScriptDC_SetResolution, 727). --define(wxPostScriptDC_GetResolution, 728). --define(wxWindowDC_new_0, 729). --define(wxWindowDC_new_1, 730). --define(wxWindowDC_destruct, 731). --define(wxClientDC_new_0, 732). --define(wxClientDC_new_1, 733). --define(wxClientDC_destroy, 734). --define(wxPaintDC_new_0, 735). --define(wxPaintDC_new_1, 736). --define(wxPaintDC_destroy, 737). --define(wxMemoryDC_new_1_0, 739). --define(wxMemoryDC_new_1_1, 740). --define(wxMemoryDC_new_0, 741). --define(wxMemoryDC_destruct, 743). --define(wxMemoryDC_SelectObject, 744). --define(wxMemoryDC_SelectObjectAsSource, 745). --define(wxBufferedDC_new_0, 746). --define(wxBufferedDC_new_2, 747). --define(wxBufferedDC_new_3, 748). --define(wxBufferedDC_destruct, 749). --define(wxBufferedDC_Init_2, 750). --define(wxBufferedDC_Init_3, 751). --define(wxBufferedPaintDC_new_3, 752). --define(wxBufferedPaintDC_new_2, 753). --define(wxBufferedPaintDC_destruct, 754). --define(wxGraphicsObject_destruct, 755). --define(wxGraphicsObject_GetRenderer, 756). --define(wxGraphicsObject_IsNull, 757). --define(wxGraphicsContext_destruct, 758). --define(wxGraphicsContext_Create_1_1, 759). --define(wxGraphicsContext_Create_1_0, 760). --define(wxGraphicsContext_Create_0, 761). --define(wxGraphicsContext_CreatePen, 762). --define(wxGraphicsContext_CreateBrush, 763). --define(wxGraphicsContext_CreateRadialGradientBrush, 764). --define(wxGraphicsContext_CreateLinearGradientBrush, 765). --define(wxGraphicsContext_CreateFont, 766). --define(wxGraphicsContext_CreateMatrix, 767). --define(wxGraphicsContext_CreatePath, 768). --define(wxGraphicsContext_Clip_1, 769). --define(wxGraphicsContext_Clip_4, 770). --define(wxGraphicsContext_ResetClip, 771). --define(wxGraphicsContext_DrawBitmap, 772). --define(wxGraphicsContext_DrawEllipse, 773). --define(wxGraphicsContext_DrawIcon, 774). --define(wxGraphicsContext_DrawLines, 775). --define(wxGraphicsContext_DrawPath, 776). --define(wxGraphicsContext_DrawRectangle, 777). --define(wxGraphicsContext_DrawRoundedRectangle, 778). --define(wxGraphicsContext_DrawText_3, 779). --define(wxGraphicsContext_DrawText_4_0, 780). --define(wxGraphicsContext_DrawText_4_1, 781). --define(wxGraphicsContext_DrawText_5, 782). --define(wxGraphicsContext_FillPath, 783). --define(wxGraphicsContext_StrokePath, 784). --define(wxGraphicsContext_GetPartialTextExtents, 785). --define(wxGraphicsContext_GetTextExtent, 786). --define(wxGraphicsContext_Rotate, 787). --define(wxGraphicsContext_Scale, 788). --define(wxGraphicsContext_Translate, 789). --define(wxGraphicsContext_GetTransform, 790). --define(wxGraphicsContext_SetTransform, 791). --define(wxGraphicsContext_ConcatTransform, 792). --define(wxGraphicsContext_SetBrush_1_1, 793). --define(wxGraphicsContext_SetBrush_1_0, 794). --define(wxGraphicsContext_SetFont_1, 795). --define(wxGraphicsContext_SetFont_2, 796). --define(wxGraphicsContext_SetPen_1_0, 797). --define(wxGraphicsContext_SetPen_1_1, 798). --define(wxGraphicsContext_StrokeLine, 799). --define(wxGraphicsContext_StrokeLines, 800). --define(wxGraphicsMatrix_Concat, 802). --define(wxGraphicsMatrix_Get, 804). --define(wxGraphicsMatrix_Invert, 805). --define(wxGraphicsMatrix_IsEqual, 806). --define(wxGraphicsMatrix_IsIdentity, 808). --define(wxGraphicsMatrix_Rotate, 809). --define(wxGraphicsMatrix_Scale, 810). --define(wxGraphicsMatrix_Translate, 811). --define(wxGraphicsMatrix_Set, 812). --define(wxGraphicsMatrix_TransformPoint, 813). --define(wxGraphicsMatrix_TransformDistance, 814). --define(wxGraphicsPath_MoveToPoint_2, 815). --define(wxGraphicsPath_MoveToPoint_1, 816). --define(wxGraphicsPath_AddArc_6, 817). --define(wxGraphicsPath_AddArc_5, 818). --define(wxGraphicsPath_AddArcToPoint, 819). --define(wxGraphicsPath_AddCircle, 820). --define(wxGraphicsPath_AddCurveToPoint_6, 821). --define(wxGraphicsPath_AddCurveToPoint_3, 822). --define(wxGraphicsPath_AddEllipse, 823). --define(wxGraphicsPath_AddLineToPoint_2, 824). --define(wxGraphicsPath_AddLineToPoint_1, 825). --define(wxGraphicsPath_AddPath, 826). --define(wxGraphicsPath_AddQuadCurveToPoint, 827). --define(wxGraphicsPath_AddRectangle, 828). --define(wxGraphicsPath_AddRoundedRectangle, 829). --define(wxGraphicsPath_CloseSubpath, 830). --define(wxGraphicsPath_Contains_3, 831). --define(wxGraphicsPath_Contains_2, 832). --define(wxGraphicsPath_GetBox, 834). --define(wxGraphicsPath_GetCurrentPoint, 836). --define(wxGraphicsPath_Transform, 837). --define(wxGraphicsRenderer_GetDefaultRenderer, 838). --define(wxGraphicsRenderer_CreateContext_1_1, 839). --define(wxGraphicsRenderer_CreateContext_1_0, 840). --define(wxGraphicsRenderer_CreatePen, 841). --define(wxGraphicsRenderer_CreateBrush, 842). --define(wxGraphicsRenderer_CreateLinearGradientBrush, 843). --define(wxGraphicsRenderer_CreateRadialGradientBrush, 844). --define(wxGraphicsRenderer_CreateFont, 845). --define(wxGraphicsRenderer_CreateMatrix, 846). --define(wxGraphicsRenderer_CreatePath, 847). --define(wxMenuBar_new_1, 849). --define(wxMenuBar_new_0, 851). --define(wxMenuBar_destruct, 853). --define(wxMenuBar_Append, 854). --define(wxMenuBar_Check, 855). --define(wxMenuBar_Enable_2, 856). --define(wxMenuBar_Enable_1, 857). --define(wxMenuBar_EnableTop, 858). --define(wxMenuBar_FindMenu, 859). --define(wxMenuBar_FindMenuItem, 860). --define(wxMenuBar_FindItem, 861). --define(wxMenuBar_GetHelpString, 862). --define(wxMenuBar_GetLabel_1, 863). --define(wxMenuBar_GetLabel_0, 864). --define(wxMenuBar_GetLabelTop, 865). --define(wxMenuBar_GetMenu, 866). --define(wxMenuBar_GetMenuCount, 867). --define(wxMenuBar_Insert, 868). --define(wxMenuBar_IsChecked, 869). --define(wxMenuBar_IsEnabled_1, 870). --define(wxMenuBar_IsEnabled_0, 871). --define(wxMenuBar_Remove, 872). --define(wxMenuBar_Replace, 873). --define(wxMenuBar_SetHelpString, 874). --define(wxMenuBar_SetLabel_2, 875). --define(wxMenuBar_SetLabel_1, 876). --define(wxMenuBar_SetLabelTop, 877). --define(wxControl_GetLabel, 878). --define(wxControl_SetLabel, 879). --define(wxControlWithItems_Append_1, 880). --define(wxControlWithItems_Append_2, 881). --define(wxControlWithItems_appendStrings_1, 882). --define(wxControlWithItems_Clear, 883). --define(wxControlWithItems_Delete, 884). --define(wxControlWithItems_FindString, 885). --define(wxControlWithItems_getClientData, 886). --define(wxControlWithItems_setClientData, 887). --define(wxControlWithItems_GetCount, 888). --define(wxControlWithItems_GetSelection, 889). --define(wxControlWithItems_GetString, 890). --define(wxControlWithItems_GetStringSelection, 891). --define(wxControlWithItems_Insert_2, 892). --define(wxControlWithItems_Insert_3, 893). --define(wxControlWithItems_IsEmpty, 894). --define(wxControlWithItems_Select, 895). --define(wxControlWithItems_SetSelection, 896). --define(wxControlWithItems_SetString, 897). --define(wxControlWithItems_SetStringSelection, 898). --define(wxMenu_new_2, 901). --define(wxMenu_new_1, 902). --define(wxMenu_destruct, 904). --define(wxMenu_Append_3, 905). --define(wxMenu_Append_1, 906). --define(wxMenu_Append_4_0, 907). --define(wxMenu_Append_4_1, 908). --define(wxMenu_AppendCheckItem, 909). --define(wxMenu_AppendRadioItem, 910). --define(wxMenu_AppendSeparator, 911). --define(wxMenu_Break, 912). --define(wxMenu_Check, 913). --define(wxMenu_Delete_1_0, 914). --define(wxMenu_Delete_1_1, 915). --define(wxMenu_Destroy_1_0, 916). --define(wxMenu_Destroy_1_1, 917). --define(wxMenu_Enable, 918). --define(wxMenu_FindItem_1, 919). --define(wxMenu_FindItem_2, 920). --define(wxMenu_FindItemByPosition, 921). --define(wxMenu_GetHelpString, 922). --define(wxMenu_GetLabel, 923). --define(wxMenu_GetMenuItemCount, 924). --define(wxMenu_GetMenuItems, 925). --define(wxMenu_GetTitle, 927). --define(wxMenu_Insert_2, 928). --define(wxMenu_Insert_3, 929). --define(wxMenu_Insert_5_1, 930). --define(wxMenu_Insert_5_0, 931). --define(wxMenu_InsertCheckItem, 932). --define(wxMenu_InsertRadioItem, 933). --define(wxMenu_InsertSeparator, 934). --define(wxMenu_IsChecked, 935). --define(wxMenu_IsEnabled, 936). --define(wxMenu_Prepend_1, 937). --define(wxMenu_Prepend_2, 938). --define(wxMenu_Prepend_4_1, 939). --define(wxMenu_Prepend_4_0, 940). --define(wxMenu_PrependCheckItem, 941). --define(wxMenu_PrependRadioItem, 942). --define(wxMenu_PrependSeparator, 943). --define(wxMenu_Remove_1_0, 944). --define(wxMenu_Remove_1_1, 945). --define(wxMenu_SetHelpString, 946). --define(wxMenu_SetLabel, 947). --define(wxMenu_SetTitle, 948). --define(wxMenuItem_new, 949). --define(wxMenuItem_destruct, 951). --define(wxMenuItem_Check, 952). --define(wxMenuItem_Enable, 953). --define(wxMenuItem_GetBitmap, 954). --define(wxMenuItem_GetHelp, 955). --define(wxMenuItem_GetId, 956). --define(wxMenuItem_GetKind, 957). --define(wxMenuItem_GetLabel, 958). --define(wxMenuItem_GetLabelFromText, 959). --define(wxMenuItem_GetMenu, 960). --define(wxMenuItem_GetText, 961). --define(wxMenuItem_GetSubMenu, 962). --define(wxMenuItem_IsCheckable, 963). --define(wxMenuItem_IsChecked, 964). --define(wxMenuItem_IsEnabled, 965). --define(wxMenuItem_IsSeparator, 966). --define(wxMenuItem_IsSubMenu, 967). --define(wxMenuItem_SetBitmap, 968). --define(wxMenuItem_SetHelp, 969). --define(wxMenuItem_SetMenu, 970). --define(wxMenuItem_SetSubMenu, 971). --define(wxMenuItem_SetText, 972). --define(wxToolBar_AddControl, 973). --define(wxToolBar_AddSeparator, 974). --define(wxToolBar_AddTool_5, 975). --define(wxToolBar_AddTool_4_0, 976). --define(wxToolBar_AddTool_1, 977). --define(wxToolBar_AddTool_4_1, 978). --define(wxToolBar_AddTool_3, 979). --define(wxToolBar_AddTool_6, 980). --define(wxToolBar_AddCheckTool, 981). --define(wxToolBar_AddRadioTool, 982). --define(wxToolBar_DeleteTool, 983). --define(wxToolBar_DeleteToolByPos, 984). --define(wxToolBar_EnableTool, 985). --define(wxToolBar_FindById, 986). --define(wxToolBar_FindControl, 987). --define(wxToolBar_FindToolForPosition, 988). --define(wxToolBar_GetToolSize, 989). --define(wxToolBar_GetToolBitmapSize, 990). --define(wxToolBar_GetMargins, 991). --define(wxToolBar_GetToolEnabled, 992). --define(wxToolBar_GetToolLongHelp, 993). --define(wxToolBar_GetToolPacking, 994). --define(wxToolBar_GetToolPos, 995). --define(wxToolBar_GetToolSeparation, 996). --define(wxToolBar_GetToolShortHelp, 997). --define(wxToolBar_GetToolState, 998). --define(wxToolBar_InsertControl, 999). --define(wxToolBar_InsertSeparator, 1000). --define(wxToolBar_InsertTool_5, 1001). --define(wxToolBar_InsertTool_2, 1002). --define(wxToolBar_InsertTool_4, 1003). --define(wxToolBar_Realize, 1004). --define(wxToolBar_RemoveTool, 1005). --define(wxToolBar_SetMargins, 1006). --define(wxToolBar_SetToolBitmapSize, 1007). --define(wxToolBar_SetToolLongHelp, 1008). --define(wxToolBar_SetToolPacking, 1009). --define(wxToolBar_SetToolShortHelp, 1010). --define(wxToolBar_SetToolSeparation, 1011). --define(wxToolBar_ToggleTool, 1012). --define(wxStatusBar_new_0, 1014). --define(wxStatusBar_new_2, 1015). --define(wxStatusBar_destruct, 1017). --define(wxStatusBar_Create, 1018). --define(wxStatusBar_GetFieldRect, 1019). --define(wxStatusBar_GetFieldsCount, 1020). --define(wxStatusBar_GetStatusText, 1021). --define(wxStatusBar_PopStatusText, 1022). --define(wxStatusBar_PushStatusText, 1023). --define(wxStatusBar_SetFieldsCount, 1024). --define(wxStatusBar_SetMinHeight, 1025). --define(wxStatusBar_SetStatusText, 1026). --define(wxStatusBar_SetStatusWidths, 1027). --define(wxStatusBar_SetStatusStyles, 1028). --define(wxBitmap_new_0, 1029). --define(wxBitmap_new_3, 1030). --define(wxBitmap_new_4, 1031). --define(wxBitmap_new_2_0, 1032). --define(wxBitmap_new_2_1, 1033). --define(wxBitmap_destruct, 1034). --define(wxBitmap_ConvertToImage, 1035). --define(wxBitmap_CopyFromIcon, 1036). --define(wxBitmap_Create, 1037). --define(wxBitmap_GetDepth, 1038). --define(wxBitmap_GetHeight, 1039). --define(wxBitmap_GetPalette, 1040). --define(wxBitmap_GetMask, 1041). --define(wxBitmap_GetWidth, 1042). --define(wxBitmap_GetSubBitmap, 1043). --define(wxBitmap_LoadFile, 1044). --define(wxBitmap_Ok, 1045). --define(wxBitmap_SaveFile, 1046). --define(wxBitmap_SetDepth, 1047). --define(wxBitmap_SetHeight, 1048). --define(wxBitmap_SetMask, 1049). --define(wxBitmap_SetPalette, 1050). --define(wxBitmap_SetWidth, 1051). --define(wxIcon_new_0, 1052). --define(wxIcon_new_2, 1053). --define(wxIcon_new_1, 1054). --define(wxIcon_CopyFromBitmap, 1055). --define(wxIcon_destroy, 1056). --define(wxIconBundle_new_0, 1057). --define(wxIconBundle_new_2, 1058). --define(wxIconBundle_new_1_0, 1059). --define(wxIconBundle_new_1_1, 1060). --define(wxIconBundle_destruct, 1061). --define(wxIconBundle_AddIcon_2, 1062). --define(wxIconBundle_AddIcon_1, 1063). --define(wxIconBundle_GetIcon_1_1, 1064). --define(wxIconBundle_GetIcon_1_0, 1065). --define(wxCursor_new_0, 1066). --define(wxCursor_new_1_0, 1067). --define(wxCursor_new_1_1, 1068). --define(wxCursor_new_4, 1069). --define(wxCursor_destruct, 1070). --define(wxCursor_Ok, 1071). --define(wxMask_new_0, 1072). --define(wxMask_new_2_1, 1073). --define(wxMask_new_2_0, 1074). --define(wxMask_new_1, 1075). --define(wxMask_destruct, 1076). --define(wxMask_Create_2_1, 1077). --define(wxMask_Create_2_0, 1078). --define(wxMask_Create_1, 1079). --define(wxImage_new_0, 1080). --define(wxImage_new_3_0, 1081). --define(wxImage_new_4, 1082). --define(wxImage_new_5, 1083). --define(wxImage_new_2, 1084). --define(wxImage_new_3_1, 1085). --define(wxImage_Blur, 1086). --define(wxImage_BlurHorizontal, 1087). --define(wxImage_BlurVertical, 1088). --define(wxImage_ConvertAlphaToMask, 1089). --define(wxImage_ConvertToGreyscale, 1090). --define(wxImage_ConvertToMono, 1091). --define(wxImage_Copy, 1092). --define(wxImage_Create_3, 1093). --define(wxImage_Create_4, 1094). --define(wxImage_Create_5, 1095). --define(wxImage_Destroy, 1096). --define(wxImage_FindFirstUnusedColour, 1097). --define(wxImage_GetImageExtWildcard, 1098). --define(wxImage_GetAlpha_2, 1099). --define(wxImage_GetAlpha_0, 1100). --define(wxImage_GetBlue, 1101). --define(wxImage_GetData, 1102). --define(wxImage_GetGreen, 1103). --define(wxImage_GetImageCount, 1104). --define(wxImage_GetHeight, 1105). --define(wxImage_GetMaskBlue, 1106). --define(wxImage_GetMaskGreen, 1107). --define(wxImage_GetMaskRed, 1108). --define(wxImage_GetOrFindMaskColour, 1109). --define(wxImage_GetPalette, 1110). --define(wxImage_GetRed, 1111). --define(wxImage_GetSubImage, 1112). --define(wxImage_GetWidth, 1113). --define(wxImage_HasAlpha, 1114). --define(wxImage_HasMask, 1115). --define(wxImage_GetOption, 1116). --define(wxImage_GetOptionInt, 1117). --define(wxImage_HasOption, 1118). --define(wxImage_InitAlpha, 1119). --define(wxImage_InitStandardHandlers, 1120). --define(wxImage_IsTransparent, 1121). --define(wxImage_LoadFile_2, 1122). --define(wxImage_LoadFile_3, 1123). --define(wxImage_Ok, 1124). --define(wxImage_RemoveHandler, 1125). --define(wxImage_Mirror, 1126). --define(wxImage_Replace, 1127). --define(wxImage_Rescale, 1128). --define(wxImage_Resize, 1129). --define(wxImage_Rotate, 1130). --define(wxImage_RotateHue, 1131). --define(wxImage_Rotate90, 1132). --define(wxImage_SaveFile_1, 1133). --define(wxImage_SaveFile_2_0, 1134). --define(wxImage_SaveFile_2_1, 1135). --define(wxImage_Scale, 1136). --define(wxImage_Size, 1137). --define(wxImage_SetAlpha_3, 1138). --define(wxImage_SetAlpha_2, 1139). --define(wxImage_SetData_2, 1140). --define(wxImage_SetData_4, 1141). --define(wxImage_SetMask, 1142). --define(wxImage_SetMaskColour, 1143). --define(wxImage_SetMaskFromImage, 1144). --define(wxImage_SetOption_2_1, 1145). --define(wxImage_SetOption_2_0, 1146). --define(wxImage_SetPalette, 1147). --define(wxImage_SetRGB_5, 1148). --define(wxImage_SetRGB_4, 1149). --define(wxImage_destroy, 1150). --define(wxBrush_new_0, 1151). --define(wxBrush_new_2, 1152). --define(wxBrush_new_1, 1153). --define(wxBrush_destruct, 1155). --define(wxBrush_GetColour, 1156). --define(wxBrush_GetStipple, 1157). --define(wxBrush_GetStyle, 1158). --define(wxBrush_IsHatch, 1159). --define(wxBrush_IsOk, 1160). --define(wxBrush_SetColour_1, 1161). --define(wxBrush_SetColour_3, 1162). --define(wxBrush_SetStipple, 1163). --define(wxBrush_SetStyle, 1164). --define(wxPen_new_0, 1165). --define(wxPen_new_2, 1166). --define(wxPen_destruct, 1167). --define(wxPen_GetCap, 1168). --define(wxPen_GetColour, 1169). --define(wxPen_GetJoin, 1170). --define(wxPen_GetStyle, 1171). --define(wxPen_GetWidth, 1172). --define(wxPen_IsOk, 1173). --define(wxPen_SetCap, 1174). --define(wxPen_SetColour_1, 1175). --define(wxPen_SetColour_3, 1176). --define(wxPen_SetJoin, 1177). --define(wxPen_SetStyle, 1178). --define(wxPen_SetWidth, 1179). --define(wxRegion_new_0, 1180). --define(wxRegion_new_4, 1181). --define(wxRegion_new_2, 1182). --define(wxRegion_new_1_1, 1183). --define(wxRegion_new_1_0, 1185). --define(wxRegion_destruct, 1187). --define(wxRegion_Clear, 1188). --define(wxRegion_Contains_2, 1189). --define(wxRegion_Contains_1_0, 1190). --define(wxRegion_Contains_4, 1191). --define(wxRegion_Contains_1_1, 1192). --define(wxRegion_ConvertToBitmap, 1193). --define(wxRegion_GetBox, 1194). --define(wxRegion_Intersect_4, 1195). --define(wxRegion_Intersect_1_1, 1196). --define(wxRegion_Intersect_1_0, 1197). --define(wxRegion_IsEmpty, 1198). --define(wxRegion_Subtract_4, 1199). --define(wxRegion_Subtract_1_1, 1200). --define(wxRegion_Subtract_1_0, 1201). --define(wxRegion_Offset_2, 1202). --define(wxRegion_Offset_1, 1203). --define(wxRegion_Union_4, 1204). --define(wxRegion_Union_1_2, 1205). --define(wxRegion_Union_1_1, 1206). --define(wxRegion_Union_1_0, 1207). --define(wxRegion_Union_3, 1208). --define(wxRegion_Xor_4, 1209). --define(wxRegion_Xor_1_1, 1210). --define(wxRegion_Xor_1_0, 1211). --define(wxAcceleratorTable_new_0, 1212). --define(wxAcceleratorTable_new_2, 1213). --define(wxAcceleratorTable_destruct, 1214). --define(wxAcceleratorTable_Ok, 1215). --define(wxAcceleratorEntry_new_1_0, 1216). --define(wxAcceleratorEntry_new_1_1, 1217). --define(wxAcceleratorEntry_GetCommand, 1218). --define(wxAcceleratorEntry_GetFlags, 1219). --define(wxAcceleratorEntry_GetKeyCode, 1220). --define(wxAcceleratorEntry_Set, 1221). --define(wxAcceleratorEntry_destroy, 1222). --define(wxCaret_new_3, 1227). --define(wxCaret_new_2, 1228). --define(wxCaret_destruct, 1230). --define(wxCaret_Create_3, 1231). --define(wxCaret_Create_2, 1232). --define(wxCaret_GetBlinkTime, 1233). --define(wxCaret_GetPosition, 1235). --define(wxCaret_GetSize, 1237). --define(wxCaret_GetWindow, 1238). --define(wxCaret_Hide, 1239). --define(wxCaret_IsOk, 1240). --define(wxCaret_IsVisible, 1241). --define(wxCaret_Move_2, 1242). --define(wxCaret_Move_1, 1243). --define(wxCaret_SetBlinkTime, 1244). --define(wxCaret_SetSize_2, 1245). --define(wxCaret_SetSize_1, 1246). --define(wxCaret_Show, 1247). --define(wxSizer_Add_2_1, 1248). --define(wxSizer_Add_2_0, 1249). --define(wxSizer_Add_3, 1250). --define(wxSizer_Add_2_3, 1251). --define(wxSizer_Add_2_2, 1252). --define(wxSizer_AddSpacer, 1253). --define(wxSizer_AddStretchSpacer, 1254). --define(wxSizer_CalcMin, 1255). --define(wxSizer_Clear, 1256). --define(wxSizer_Detach_1_2, 1257). --define(wxSizer_Detach_1_1, 1258). --define(wxSizer_Detach_1_0, 1259). --define(wxSizer_Fit, 1260). --define(wxSizer_FitInside, 1261). --define(wxSizer_GetChildren, 1262). --define(wxSizer_GetItem_2_1, 1263). --define(wxSizer_GetItem_2_0, 1264). --define(wxSizer_GetItem_1, 1265). --define(wxSizer_GetSize, 1266). --define(wxSizer_GetPosition, 1267). --define(wxSizer_GetMinSize, 1268). --define(wxSizer_Hide_2_0, 1269). --define(wxSizer_Hide_2_1, 1270). --define(wxSizer_Hide_1, 1271). --define(wxSizer_Insert_3_1, 1272). --define(wxSizer_Insert_3_0, 1273). --define(wxSizer_Insert_4, 1274). --define(wxSizer_Insert_3_3, 1275). --define(wxSizer_Insert_3_2, 1276). --define(wxSizer_Insert_2, 1277). --define(wxSizer_InsertSpacer, 1278). --define(wxSizer_InsertStretchSpacer, 1279). --define(wxSizer_IsShown_1_2, 1280). --define(wxSizer_IsShown_1_1, 1281). --define(wxSizer_IsShown_1_0, 1282). --define(wxSizer_Layout, 1283). --define(wxSizer_Prepend_2_1, 1284). --define(wxSizer_Prepend_2_0, 1285). --define(wxSizer_Prepend_3, 1286). --define(wxSizer_Prepend_2_3, 1287). --define(wxSizer_Prepend_2_2, 1288). --define(wxSizer_Prepend_1, 1289). --define(wxSizer_PrependSpacer, 1290). --define(wxSizer_PrependStretchSpacer, 1291). --define(wxSizer_RecalcSizes, 1292). --define(wxSizer_Remove_1_1, 1293). --define(wxSizer_Remove_1_0, 1294). --define(wxSizer_Replace_3_1, 1295). --define(wxSizer_Replace_3_0, 1296). --define(wxSizer_Replace_2, 1297). --define(wxSizer_SetDimension, 1298). --define(wxSizer_SetMinSize_2, 1299). --define(wxSizer_SetMinSize_1, 1300). --define(wxSizer_SetItemMinSize_3_2, 1301). --define(wxSizer_SetItemMinSize_2_2, 1302). --define(wxSizer_SetItemMinSize_3_1, 1303). --define(wxSizer_SetItemMinSize_2_1, 1304). --define(wxSizer_SetItemMinSize_3_0, 1305). --define(wxSizer_SetItemMinSize_2_0, 1306). --define(wxSizer_SetSizeHints, 1307). --define(wxSizer_SetVirtualSizeHints, 1308). --define(wxSizer_Show_2_2, 1309). --define(wxSizer_Show_2_1, 1310). --define(wxSizer_Show_2_0, 1311). --define(wxSizer_Show_1, 1312). --define(wxSizerFlags_new, 1313). --define(wxSizerFlags_Align, 1314). --define(wxSizerFlags_Border_2, 1315). --define(wxSizerFlags_Border_1, 1316). --define(wxSizerFlags_Center, 1317). --define(wxSizerFlags_Centre, 1318). --define(wxSizerFlags_Expand, 1319). --define(wxSizerFlags_Left, 1320). --define(wxSizerFlags_Proportion, 1321). --define(wxSizerFlags_Right, 1322). --define(wxSizerFlags_destroy, 1323). --define(wxSizerItem_new_5_1, 1324). --define(wxSizerItem_new_2_1, 1325). --define(wxSizerItem_new_5_0, 1326). --define(wxSizerItem_new_2_0, 1327). --define(wxSizerItem_new_6, 1328). --define(wxSizerItem_new_3, 1329). --define(wxSizerItem_new_0, 1330). --define(wxSizerItem_destruct, 1331). --define(wxSizerItem_CalcMin, 1332). --define(wxSizerItem_DeleteWindows, 1333). --define(wxSizerItem_DetachSizer, 1334). --define(wxSizerItem_GetBorder, 1335). --define(wxSizerItem_GetFlag, 1336). --define(wxSizerItem_GetMinSize, 1337). --define(wxSizerItem_GetPosition, 1338). --define(wxSizerItem_GetProportion, 1339). --define(wxSizerItem_GetRatio, 1340). --define(wxSizerItem_GetRect, 1341). --define(wxSizerItem_GetSize, 1342). --define(wxSizerItem_GetSizer, 1343). --define(wxSizerItem_GetSpacer, 1344). --define(wxSizerItem_GetUserData, 1345). --define(wxSizerItem_GetWindow, 1346). --define(wxSizerItem_IsSizer, 1347). --define(wxSizerItem_IsShown, 1348). --define(wxSizerItem_IsSpacer, 1349). --define(wxSizerItem_IsWindow, 1350). --define(wxSizerItem_SetBorder, 1351). --define(wxSizerItem_SetDimension, 1352). --define(wxSizerItem_SetFlag, 1353). --define(wxSizerItem_SetInitSize, 1354). --define(wxSizerItem_SetMinSize_1, 1355). --define(wxSizerItem_SetMinSize_2, 1356). --define(wxSizerItem_SetProportion, 1357). --define(wxSizerItem_SetRatio_2, 1358). --define(wxSizerItem_SetRatio_1_1, 1359). --define(wxSizerItem_SetRatio_1_0, 1360). --define(wxSizerItem_SetSizer, 1361). --define(wxSizerItem_SetSpacer_1, 1362). --define(wxSizerItem_SetSpacer_2, 1363). --define(wxSizerItem_SetWindow, 1364). --define(wxSizerItem_Show, 1365). --define(wxBoxSizer_new, 1366). --define(wxBoxSizer_GetOrientation, 1367). --define(wxBoxSizer_destroy, 1368). --define(wxStaticBoxSizer_new_2, 1369). --define(wxStaticBoxSizer_new_3, 1370). --define(wxStaticBoxSizer_GetStaticBox, 1371). --define(wxStaticBoxSizer_destroy, 1372). --define(wxGridSizer_new_4, 1373). --define(wxGridSizer_new_2, 1374). --define(wxGridSizer_GetCols, 1375). --define(wxGridSizer_GetHGap, 1376). --define(wxGridSizer_GetRows, 1377). --define(wxGridSizer_GetVGap, 1378). --define(wxGridSizer_SetCols, 1379). --define(wxGridSizer_SetHGap, 1380). --define(wxGridSizer_SetRows, 1381). --define(wxGridSizer_SetVGap, 1382). --define(wxGridSizer_destroy, 1383). --define(wxFlexGridSizer_new_4, 1384). --define(wxFlexGridSizer_new_2, 1385). --define(wxFlexGridSizer_AddGrowableCol, 1386). --define(wxFlexGridSizer_AddGrowableRow, 1387). --define(wxFlexGridSizer_GetFlexibleDirection, 1388). --define(wxFlexGridSizer_GetNonFlexibleGrowMode, 1389). --define(wxFlexGridSizer_RemoveGrowableCol, 1390). --define(wxFlexGridSizer_RemoveGrowableRow, 1391). --define(wxFlexGridSizer_SetFlexibleDirection, 1392). --define(wxFlexGridSizer_SetNonFlexibleGrowMode, 1393). --define(wxFlexGridSizer_destroy, 1394). --define(wxGridBagSizer_new, 1395). --define(wxGridBagSizer_Add_3_2, 1396). --define(wxGridBagSizer_Add_3_1, 1397). --define(wxGridBagSizer_Add_4, 1398). --define(wxGridBagSizer_Add_1_0, 1399). --define(wxGridBagSizer_Add_2_1, 1400). --define(wxGridBagSizer_Add_2_0, 1401). --define(wxGridBagSizer_Add_3_0, 1402). --define(wxGridBagSizer_Add_1_1, 1403). --define(wxGridBagSizer_CalcMin, 1404). --define(wxGridBagSizer_CheckForIntersection_2, 1405). --define(wxGridBagSizer_CheckForIntersection_3, 1406). --define(wxGridBagSizer_FindItem_1_1, 1407). --define(wxGridBagSizer_FindItem_1_0, 1408). --define(wxGridBagSizer_FindItemAtPoint, 1409). --define(wxGridBagSizer_FindItemAtPosition, 1410). --define(wxGridBagSizer_FindItemWithData, 1411). --define(wxGridBagSizer_GetCellSize, 1412). --define(wxGridBagSizer_GetEmptyCellSize, 1413). --define(wxGridBagSizer_GetItemPosition_1_2, 1414). --define(wxGridBagSizer_GetItemPosition_1_1, 1415). --define(wxGridBagSizer_GetItemPosition_1_0, 1416). --define(wxGridBagSizer_GetItemSpan_1_2, 1417). --define(wxGridBagSizer_GetItemSpan_1_1, 1418). --define(wxGridBagSizer_GetItemSpan_1_0, 1419). --define(wxGridBagSizer_SetEmptyCellSize, 1420). --define(wxGridBagSizer_SetItemPosition_2_2, 1421). --define(wxGridBagSizer_SetItemPosition_2_1, 1422). --define(wxGridBagSizer_SetItemPosition_2_0, 1423). --define(wxGridBagSizer_SetItemSpan_2_2, 1424). --define(wxGridBagSizer_SetItemSpan_2_1, 1425). --define(wxGridBagSizer_SetItemSpan_2_0, 1426). --define(wxGridBagSizer_destroy, 1427). --define(wxStdDialogButtonSizer_new, 1428). --define(wxStdDialogButtonSizer_AddButton, 1429). --define(wxStdDialogButtonSizer_Realize, 1430). --define(wxStdDialogButtonSizer_SetAffirmativeButton, 1431). --define(wxStdDialogButtonSizer_SetCancelButton, 1432). --define(wxStdDialogButtonSizer_SetNegativeButton, 1433). --define(wxStdDialogButtonSizer_destroy, 1434). --define(wxFont_new_0, 1435). --define(wxFont_new_1, 1436). --define(wxFont_new_5, 1437). --define(wxFont_destruct, 1439). --define(wxFont_IsFixedWidth, 1440). --define(wxFont_GetDefaultEncoding, 1441). --define(wxFont_GetFaceName, 1442). --define(wxFont_GetFamily, 1443). --define(wxFont_GetNativeFontInfoDesc, 1444). --define(wxFont_GetNativeFontInfoUserDesc, 1445). --define(wxFont_GetPointSize, 1446). --define(wxFont_GetStyle, 1447). --define(wxFont_GetUnderlined, 1448). --define(wxFont_GetWeight, 1449). --define(wxFont_Ok, 1450). --define(wxFont_SetDefaultEncoding, 1451). --define(wxFont_SetFaceName, 1452). --define(wxFont_SetFamily, 1453). --define(wxFont_SetPointSize, 1454). --define(wxFont_SetStyle, 1455). --define(wxFont_SetUnderlined, 1456). --define(wxFont_SetWeight, 1457). --define(wxToolTip_Enable, 1458). --define(wxToolTip_SetDelay, 1459). --define(wxToolTip_new, 1460). --define(wxToolTip_SetTip, 1461). --define(wxToolTip_GetTip, 1462). --define(wxToolTip_GetWindow, 1463). --define(wxToolTip_destroy, 1464). --define(wxButton_new_3, 1466). --define(wxButton_new_0, 1467). --define(wxButton_destruct, 1468). --define(wxButton_Create, 1469). --define(wxButton_GetDefaultSize, 1470). --define(wxButton_SetDefault, 1471). --define(wxButton_SetLabel, 1472). --define(wxBitmapButton_new_4, 1474). --define(wxBitmapButton_new_0, 1475). --define(wxBitmapButton_Create, 1476). --define(wxBitmapButton_GetBitmapDisabled, 1477). --define(wxBitmapButton_GetBitmapFocus, 1479). --define(wxBitmapButton_GetBitmapLabel, 1481). --define(wxBitmapButton_GetBitmapSelected, 1483). --define(wxBitmapButton_SetBitmapDisabled, 1485). --define(wxBitmapButton_SetBitmapFocus, 1486). --define(wxBitmapButton_SetBitmapLabel, 1487). --define(wxBitmapButton_SetBitmapSelected, 1488). --define(wxBitmapButton_destroy, 1489). --define(wxToggleButton_new_0, 1490). --define(wxToggleButton_new_4, 1491). --define(wxToggleButton_Create, 1492). --define(wxToggleButton_GetValue, 1493). --define(wxToggleButton_SetValue, 1494). --define(wxToggleButton_destroy, 1495). --define(wxCalendarCtrl_new_0, 1496). --define(wxCalendarCtrl_new_3, 1497). --define(wxCalendarCtrl_Create, 1498). --define(wxCalendarCtrl_destruct, 1499). --define(wxCalendarCtrl_SetDate, 1500). --define(wxCalendarCtrl_GetDate, 1501). --define(wxCalendarCtrl_EnableYearChange, 1502). --define(wxCalendarCtrl_EnableMonthChange, 1503). --define(wxCalendarCtrl_EnableHolidayDisplay, 1504). --define(wxCalendarCtrl_SetHeaderColours, 1505). --define(wxCalendarCtrl_GetHeaderColourFg, 1506). --define(wxCalendarCtrl_GetHeaderColourBg, 1507). --define(wxCalendarCtrl_SetHighlightColours, 1508). --define(wxCalendarCtrl_GetHighlightColourFg, 1509). --define(wxCalendarCtrl_GetHighlightColourBg, 1510). --define(wxCalendarCtrl_SetHolidayColours, 1511). --define(wxCalendarCtrl_GetHolidayColourFg, 1512). --define(wxCalendarCtrl_GetHolidayColourBg, 1513). --define(wxCalendarCtrl_GetAttr, 1514). --define(wxCalendarCtrl_SetAttr, 1515). --define(wxCalendarCtrl_SetHoliday, 1516). --define(wxCalendarCtrl_ResetAttr, 1517). --define(wxCalendarCtrl_HitTest, 1518). --define(wxCalendarDateAttr_new_0, 1519). --define(wxCalendarDateAttr_new_2_1, 1520). --define(wxCalendarDateAttr_new_2_0, 1521). --define(wxCalendarDateAttr_SetTextColour, 1522). --define(wxCalendarDateAttr_SetBackgroundColour, 1523). --define(wxCalendarDateAttr_SetBorderColour, 1524). --define(wxCalendarDateAttr_SetFont, 1525). --define(wxCalendarDateAttr_SetBorder, 1526). --define(wxCalendarDateAttr_SetHoliday, 1527). --define(wxCalendarDateAttr_HasTextColour, 1528). --define(wxCalendarDateAttr_HasBackgroundColour, 1529). --define(wxCalendarDateAttr_HasBorderColour, 1530). --define(wxCalendarDateAttr_HasFont, 1531). --define(wxCalendarDateAttr_HasBorder, 1532). --define(wxCalendarDateAttr_IsHoliday, 1533). --define(wxCalendarDateAttr_GetTextColour, 1534). --define(wxCalendarDateAttr_GetBackgroundColour, 1535). --define(wxCalendarDateAttr_GetBorderColour, 1536). --define(wxCalendarDateAttr_GetFont, 1537). --define(wxCalendarDateAttr_GetBorder, 1538). --define(wxCalendarDateAttr_destroy, 1539). --define(wxCheckBox_new_4, 1541). --define(wxCheckBox_new_0, 1542). --define(wxCheckBox_Create, 1543). --define(wxCheckBox_GetValue, 1544). --define(wxCheckBox_Get3StateValue, 1545). --define(wxCheckBox_Is3rdStateAllowedForUser, 1546). --define(wxCheckBox_Is3State, 1547). --define(wxCheckBox_IsChecked, 1548). --define(wxCheckBox_SetValue, 1549). --define(wxCheckBox_Set3StateValue, 1550). --define(wxCheckBox_destroy, 1551). --define(wxCheckListBox_new_0, 1552). --define(wxCheckListBox_new_3, 1554). --define(wxCheckListBox_Check, 1555). --define(wxCheckListBox_IsChecked, 1556). --define(wxCheckListBox_destroy, 1557). --define(wxChoice_new_3, 1560). --define(wxChoice_new_0, 1561). --define(wxChoice_destruct, 1563). --define(wxChoice_Create, 1565). --define(wxChoice_Delete, 1566). --define(wxChoice_GetColumns, 1567). --define(wxChoice_SetColumns, 1568). --define(wxComboBox_new_0, 1569). --define(wxComboBox_new_3, 1571). --define(wxComboBox_destruct, 1572). --define(wxComboBox_Create, 1574). --define(wxComboBox_CanCopy, 1575). --define(wxComboBox_CanCut, 1576). --define(wxComboBox_CanPaste, 1577). --define(wxComboBox_CanRedo, 1578). --define(wxComboBox_CanUndo, 1579). --define(wxComboBox_Copy, 1580). --define(wxComboBox_Cut, 1581). --define(wxComboBox_GetInsertionPoint, 1582). --define(wxComboBox_GetLastPosition, 1583). --define(wxComboBox_GetValue, 1584). --define(wxComboBox_Paste, 1585). --define(wxComboBox_Redo, 1586). --define(wxComboBox_Replace, 1587). --define(wxComboBox_Remove, 1588). --define(wxComboBox_SetInsertionPoint, 1589). --define(wxComboBox_SetInsertionPointEnd, 1590). --define(wxComboBox_SetSelection_1, 1591). --define(wxComboBox_SetSelection_2, 1592). --define(wxComboBox_SetValue, 1593). --define(wxComboBox_Undo, 1594). --define(wxGauge_new_0, 1595). --define(wxGauge_new_4, 1596). --define(wxGauge_Create, 1597). --define(wxGauge_GetBezelFace, 1598). --define(wxGauge_GetRange, 1599). --define(wxGauge_GetShadowWidth, 1600). --define(wxGauge_GetValue, 1601). --define(wxGauge_IsVertical, 1602). --define(wxGauge_SetBezelFace, 1603). --define(wxGauge_SetRange, 1604). --define(wxGauge_SetShadowWidth, 1605). --define(wxGauge_SetValue, 1606). --define(wxGauge_Pulse, 1607). --define(wxGauge_destroy, 1608). --define(wxGenericDirCtrl_new_0, 1609). --define(wxGenericDirCtrl_new_2, 1610). --define(wxGenericDirCtrl_destruct, 1611). --define(wxGenericDirCtrl_Create, 1612). --define(wxGenericDirCtrl_Init, 1613). --define(wxGenericDirCtrl_CollapseTree, 1614). --define(wxGenericDirCtrl_ExpandPath, 1615). --define(wxGenericDirCtrl_GetDefaultPath, 1616). --define(wxGenericDirCtrl_GetPath, 1617). --define(wxGenericDirCtrl_GetFilePath, 1618). --define(wxGenericDirCtrl_GetFilter, 1619). --define(wxGenericDirCtrl_GetFilterIndex, 1620). --define(wxGenericDirCtrl_GetRootId, 1621). --define(wxGenericDirCtrl_GetTreeCtrl, 1622). --define(wxGenericDirCtrl_ReCreateTree, 1623). --define(wxGenericDirCtrl_SetDefaultPath, 1624). --define(wxGenericDirCtrl_SetFilter, 1625). --define(wxGenericDirCtrl_SetFilterIndex, 1626). --define(wxGenericDirCtrl_SetPath, 1627). --define(wxStaticBox_new_4, 1629). --define(wxStaticBox_new_0, 1630). --define(wxStaticBox_Create, 1631). --define(wxStaticBox_destroy, 1632). --define(wxStaticLine_new_2, 1634). --define(wxStaticLine_new_0, 1635). --define(wxStaticLine_Create, 1636). --define(wxStaticLine_IsVertical, 1637). --define(wxStaticLine_GetDefaultSize, 1638). --define(wxStaticLine_destroy, 1639). --define(wxListBox_new_3, 1642). --define(wxListBox_new_0, 1643). --define(wxListBox_destruct, 1645). --define(wxListBox_Create, 1647). --define(wxListBox_Deselect, 1648). --define(wxListBox_GetSelections, 1649). --define(wxListBox_InsertItems, 1650). --define(wxListBox_IsSelected, 1651). --define(wxListBox_Set, 1653). --define(wxListBox_HitTest, 1654). --define(wxListBox_SetFirstItem_1_0, 1655). --define(wxListBox_SetFirstItem_1_1, 1656). --define(wxListCtrl_new_0, 1657). --define(wxListCtrl_new_2, 1658). --define(wxListCtrl_Arrange, 1659). --define(wxListCtrl_AssignImageList, 1660). --define(wxListCtrl_ClearAll, 1661). --define(wxListCtrl_Create, 1662). --define(wxListCtrl_DeleteAllItems, 1663). --define(wxListCtrl_DeleteColumn, 1664). --define(wxListCtrl_DeleteItem, 1665). --define(wxListCtrl_EditLabel, 1666). --define(wxListCtrl_EnsureVisible, 1667). --define(wxListCtrl_FindItem_3_0, 1668). --define(wxListCtrl_FindItem_3_1, 1669). --define(wxListCtrl_GetColumn, 1670). --define(wxListCtrl_GetColumnCount, 1671). --define(wxListCtrl_GetColumnWidth, 1672). --define(wxListCtrl_GetCountPerPage, 1673). --define(wxListCtrl_GetEditControl, 1674). --define(wxListCtrl_GetImageList, 1675). --define(wxListCtrl_GetItem, 1676). --define(wxListCtrl_GetItemBackgroundColour, 1677). --define(wxListCtrl_GetItemCount, 1678). --define(wxListCtrl_GetItemData, 1679). --define(wxListCtrl_GetItemFont, 1680). --define(wxListCtrl_GetItemPosition, 1681). --define(wxListCtrl_GetItemRect, 1682). --define(wxListCtrl_GetItemSpacing, 1683). --define(wxListCtrl_GetItemState, 1684). --define(wxListCtrl_GetItemText, 1685). --define(wxListCtrl_GetItemTextColour, 1686). --define(wxListCtrl_GetNextItem, 1687). --define(wxListCtrl_GetSelectedItemCount, 1688). --define(wxListCtrl_GetTextColour, 1689). --define(wxListCtrl_GetTopItem, 1690). --define(wxListCtrl_GetViewRect, 1691). --define(wxListCtrl_HitTest, 1692). --define(wxListCtrl_InsertColumn_2, 1693). --define(wxListCtrl_InsertColumn_3, 1694). --define(wxListCtrl_InsertItem_1, 1695). --define(wxListCtrl_InsertItem_2_1, 1696). --define(wxListCtrl_InsertItem_2_0, 1697). --define(wxListCtrl_InsertItem_3, 1698). --define(wxListCtrl_RefreshItem, 1699). --define(wxListCtrl_RefreshItems, 1700). --define(wxListCtrl_ScrollList, 1701). --define(wxListCtrl_SetBackgroundColour, 1702). --define(wxListCtrl_SetColumn, 1703). --define(wxListCtrl_SetColumnWidth, 1704). --define(wxListCtrl_SetImageList, 1705). --define(wxListCtrl_SetItem_1, 1706). --define(wxListCtrl_SetItem_4, 1707). --define(wxListCtrl_SetItemBackgroundColour, 1708). --define(wxListCtrl_SetItemCount, 1709). --define(wxListCtrl_SetItemData, 1710). --define(wxListCtrl_SetItemFont, 1711). --define(wxListCtrl_SetItemImage, 1712). --define(wxListCtrl_SetItemColumnImage, 1713). --define(wxListCtrl_SetItemPosition, 1714). --define(wxListCtrl_SetItemState, 1715). --define(wxListCtrl_SetItemText, 1716). --define(wxListCtrl_SetItemTextColour, 1717). --define(wxListCtrl_SetSingleStyle, 1718). --define(wxListCtrl_SetTextColour, 1719). --define(wxListCtrl_SetWindowStyleFlag, 1720). --define(wxListCtrl_SortItems, 1721). --define(wxListCtrl_destroy, 1722). --define(wxListView_ClearColumnImage, 1723). --define(wxListView_Focus, 1724). --define(wxListView_GetFirstSelected, 1725). --define(wxListView_GetFocusedItem, 1726). --define(wxListView_GetNextSelected, 1727). --define(wxListView_IsSelected, 1728). --define(wxListView_Select, 1729). --define(wxListView_SetColumnImage, 1730). --define(wxListItem_new_0, 1731). --define(wxListItem_new_1, 1732). --define(wxListItem_destruct, 1733). --define(wxListItem_Clear, 1734). --define(wxListItem_GetAlign, 1735). --define(wxListItem_GetBackgroundColour, 1736). --define(wxListItem_GetColumn, 1737). --define(wxListItem_GetFont, 1738). --define(wxListItem_GetId, 1739). --define(wxListItem_GetImage, 1740). --define(wxListItem_GetMask, 1741). --define(wxListItem_GetState, 1742). --define(wxListItem_GetText, 1743). --define(wxListItem_GetTextColour, 1744). --define(wxListItem_GetWidth, 1745). --define(wxListItem_SetAlign, 1746). --define(wxListItem_SetBackgroundColour, 1747). --define(wxListItem_SetColumn, 1748). --define(wxListItem_SetFont, 1749). --define(wxListItem_SetId, 1750). --define(wxListItem_SetImage, 1751). --define(wxListItem_SetMask, 1752). --define(wxListItem_SetState, 1753). --define(wxListItem_SetStateMask, 1754). --define(wxListItem_SetText, 1755). --define(wxListItem_SetTextColour, 1756). --define(wxListItem_SetWidth, 1757). --define(wxListItemAttr_new_0, 1758). --define(wxListItemAttr_new_3, 1759). --define(wxListItemAttr_GetBackgroundColour, 1760). --define(wxListItemAttr_GetFont, 1761). --define(wxListItemAttr_GetTextColour, 1762). --define(wxListItemAttr_HasBackgroundColour, 1763). --define(wxListItemAttr_HasFont, 1764). --define(wxListItemAttr_HasTextColour, 1765). --define(wxListItemAttr_SetBackgroundColour, 1766). --define(wxListItemAttr_SetFont, 1767). --define(wxListItemAttr_SetTextColour, 1768). --define(wxListItemAttr_destroy, 1769). --define(wxImageList_new_0, 1770). --define(wxImageList_new_3, 1771). --define(wxImageList_Add_1, 1772). --define(wxImageList_Add_2_0, 1773). --define(wxImageList_Add_2_1, 1774). --define(wxImageList_Create, 1775). --define(wxImageList_Draw, 1777). --define(wxImageList_GetBitmap, 1778). --define(wxImageList_GetIcon, 1779). --define(wxImageList_GetImageCount, 1780). --define(wxImageList_GetSize, 1781). --define(wxImageList_Remove, 1782). --define(wxImageList_RemoveAll, 1783). --define(wxImageList_Replace_2, 1784). --define(wxImageList_Replace_3, 1785). --define(wxImageList_destroy, 1786). --define(wxTextAttr_new_0, 1787). --define(wxTextAttr_new_2, 1788). --define(wxTextAttr_GetAlignment, 1789). --define(wxTextAttr_GetBackgroundColour, 1790). --define(wxTextAttr_GetFont, 1791). --define(wxTextAttr_GetLeftIndent, 1792). --define(wxTextAttr_GetLeftSubIndent, 1793). --define(wxTextAttr_GetRightIndent, 1794). --define(wxTextAttr_GetTabs, 1795). --define(wxTextAttr_GetTextColour, 1796). --define(wxTextAttr_HasBackgroundColour, 1797). --define(wxTextAttr_HasFont, 1798). --define(wxTextAttr_HasTextColour, 1799). --define(wxTextAttr_GetFlags, 1800). --define(wxTextAttr_IsDefault, 1801). --define(wxTextAttr_SetAlignment, 1802). --define(wxTextAttr_SetBackgroundColour, 1803). --define(wxTextAttr_SetFlags, 1804). --define(wxTextAttr_SetFont, 1805). --define(wxTextAttr_SetLeftIndent, 1806). --define(wxTextAttr_SetRightIndent, 1807). --define(wxTextAttr_SetTabs, 1808). --define(wxTextAttr_SetTextColour, 1809). --define(wxTextAttr_destroy, 1810). --define(wxTextCtrl_new_3, 1812). --define(wxTextCtrl_new_0, 1813). --define(wxTextCtrl_destruct, 1815). --define(wxTextCtrl_AppendText, 1816). --define(wxTextCtrl_CanCopy, 1817). --define(wxTextCtrl_CanCut, 1818). --define(wxTextCtrl_CanPaste, 1819). --define(wxTextCtrl_CanRedo, 1820). --define(wxTextCtrl_CanUndo, 1821). --define(wxTextCtrl_Clear, 1822). --define(wxTextCtrl_Copy, 1823). --define(wxTextCtrl_Create, 1824). --define(wxTextCtrl_Cut, 1825). --define(wxTextCtrl_DiscardEdits, 1826). --define(wxTextCtrl_EmulateKeyPress, 1827). --define(wxTextCtrl_GetDefaultStyle, 1828). --define(wxTextCtrl_GetInsertionPoint, 1829). --define(wxTextCtrl_GetLastPosition, 1830). --define(wxTextCtrl_GetLineLength, 1831). --define(wxTextCtrl_GetLineText, 1832). --define(wxTextCtrl_GetNumberOfLines, 1833). --define(wxTextCtrl_GetRange, 1834). --define(wxTextCtrl_GetSelection, 1835). --define(wxTextCtrl_GetStringSelection, 1836). --define(wxTextCtrl_GetStyle, 1837). --define(wxTextCtrl_GetValue, 1838). --define(wxTextCtrl_IsEditable, 1839). --define(wxTextCtrl_IsModified, 1840). --define(wxTextCtrl_IsMultiLine, 1841). --define(wxTextCtrl_IsSingleLine, 1842). --define(wxTextCtrl_LoadFile, 1843). --define(wxTextCtrl_MarkDirty, 1844). --define(wxTextCtrl_Paste, 1845). --define(wxTextCtrl_PositionToXY, 1846). --define(wxTextCtrl_Redo, 1847). --define(wxTextCtrl_Remove, 1848). --define(wxTextCtrl_Replace, 1849). --define(wxTextCtrl_SaveFile, 1850). --define(wxTextCtrl_SetDefaultStyle, 1851). --define(wxTextCtrl_SetEditable, 1852). --define(wxTextCtrl_SetInsertionPoint, 1853). --define(wxTextCtrl_SetInsertionPointEnd, 1854). --define(wxTextCtrl_SetMaxLength, 1856). --define(wxTextCtrl_SetSelection, 1857). --define(wxTextCtrl_SetStyle, 1858). --define(wxTextCtrl_SetValue, 1859). --define(wxTextCtrl_ShowPosition, 1860). --define(wxTextCtrl_Undo, 1861). --define(wxTextCtrl_WriteText, 1862). --define(wxTextCtrl_XYToPosition, 1863). --define(wxNotebook_new_0, 1866). --define(wxNotebook_new_3, 1867). --define(wxNotebook_destruct, 1868). --define(wxNotebook_AddPage, 1869). --define(wxNotebook_AdvanceSelection, 1870). --define(wxNotebook_AssignImageList, 1871). --define(wxNotebook_Create, 1872). --define(wxNotebook_DeleteAllPages, 1873). --define(wxNotebook_DeletePage, 1874). --define(wxNotebook_RemovePage, 1875). --define(wxNotebook_GetCurrentPage, 1876). --define(wxNotebook_GetImageList, 1877). --define(wxNotebook_GetPage, 1879). --define(wxNotebook_GetPageCount, 1880). --define(wxNotebook_GetPageImage, 1881). --define(wxNotebook_GetPageText, 1882). --define(wxNotebook_GetRowCount, 1883). --define(wxNotebook_GetSelection, 1884). --define(wxNotebook_GetThemeBackgroundColour, 1885). --define(wxNotebook_HitTest, 1887). --define(wxNotebook_InsertPage, 1889). --define(wxNotebook_SetImageList, 1890). --define(wxNotebook_SetPadding, 1891). --define(wxNotebook_SetPageSize, 1892). --define(wxNotebook_SetPageImage, 1893). --define(wxNotebook_SetPageText, 1894). --define(wxNotebook_SetSelection, 1895). --define(wxNotebook_ChangeSelection, 1896). --define(wxChoicebook_new_0, 1897). --define(wxChoicebook_new_3, 1898). --define(wxChoicebook_AddPage, 1899). --define(wxChoicebook_AdvanceSelection, 1900). --define(wxChoicebook_AssignImageList, 1901). --define(wxChoicebook_Create, 1902). --define(wxChoicebook_DeleteAllPages, 1903). --define(wxChoicebook_DeletePage, 1904). --define(wxChoicebook_RemovePage, 1905). --define(wxChoicebook_GetCurrentPage, 1906). --define(wxChoicebook_GetImageList, 1907). --define(wxChoicebook_GetPage, 1909). --define(wxChoicebook_GetPageCount, 1910). --define(wxChoicebook_GetPageImage, 1911). --define(wxChoicebook_GetPageText, 1912). --define(wxChoicebook_GetSelection, 1913). --define(wxChoicebook_HitTest, 1914). --define(wxChoicebook_InsertPage, 1915). --define(wxChoicebook_SetImageList, 1916). --define(wxChoicebook_SetPageSize, 1917). --define(wxChoicebook_SetPageImage, 1918). --define(wxChoicebook_SetPageText, 1919). --define(wxChoicebook_SetSelection, 1920). --define(wxChoicebook_ChangeSelection, 1921). --define(wxChoicebook_destroy, 1922). --define(wxToolbook_new_0, 1923). --define(wxToolbook_new_3, 1924). --define(wxToolbook_AddPage, 1925). --define(wxToolbook_AdvanceSelection, 1926). --define(wxToolbook_AssignImageList, 1927). --define(wxToolbook_Create, 1928). --define(wxToolbook_DeleteAllPages, 1929). --define(wxToolbook_DeletePage, 1930). --define(wxToolbook_RemovePage, 1931). --define(wxToolbook_GetCurrentPage, 1932). --define(wxToolbook_GetImageList, 1933). --define(wxToolbook_GetPage, 1935). --define(wxToolbook_GetPageCount, 1936). --define(wxToolbook_GetPageImage, 1937). --define(wxToolbook_GetPageText, 1938). --define(wxToolbook_GetSelection, 1939). --define(wxToolbook_HitTest, 1941). --define(wxToolbook_InsertPage, 1942). --define(wxToolbook_SetImageList, 1943). --define(wxToolbook_SetPageSize, 1944). --define(wxToolbook_SetPageImage, 1945). --define(wxToolbook_SetPageText, 1946). --define(wxToolbook_SetSelection, 1947). --define(wxToolbook_ChangeSelection, 1948). --define(wxToolbook_destroy, 1949). --define(wxListbook_new_0, 1950). --define(wxListbook_new_3, 1951). --define(wxListbook_AddPage, 1952). --define(wxListbook_AdvanceSelection, 1953). --define(wxListbook_AssignImageList, 1954). --define(wxListbook_Create, 1955). --define(wxListbook_DeleteAllPages, 1956). --define(wxListbook_DeletePage, 1957). --define(wxListbook_RemovePage, 1958). --define(wxListbook_GetCurrentPage, 1959). --define(wxListbook_GetImageList, 1960). --define(wxListbook_GetPage, 1962). --define(wxListbook_GetPageCount, 1963). --define(wxListbook_GetPageImage, 1964). --define(wxListbook_GetPageText, 1965). --define(wxListbook_GetSelection, 1966). --define(wxListbook_HitTest, 1968). --define(wxListbook_InsertPage, 1969). --define(wxListbook_SetImageList, 1970). --define(wxListbook_SetPageSize, 1971). --define(wxListbook_SetPageImage, 1972). --define(wxListbook_SetPageText, 1973). --define(wxListbook_SetSelection, 1974). --define(wxListbook_ChangeSelection, 1975). --define(wxListbook_destroy, 1976). --define(wxTreebook_new_0, 1977). --define(wxTreebook_new_3, 1978). --define(wxTreebook_AddPage, 1979). --define(wxTreebook_AdvanceSelection, 1980). --define(wxTreebook_AssignImageList, 1981). --define(wxTreebook_Create, 1982). --define(wxTreebook_DeleteAllPages, 1983). --define(wxTreebook_DeletePage, 1984). --define(wxTreebook_RemovePage, 1985). --define(wxTreebook_GetCurrentPage, 1986). --define(wxTreebook_GetImageList, 1987). --define(wxTreebook_GetPage, 1989). --define(wxTreebook_GetPageCount, 1990). --define(wxTreebook_GetPageImage, 1991). --define(wxTreebook_GetPageText, 1992). --define(wxTreebook_GetSelection, 1993). --define(wxTreebook_ExpandNode, 1994). --define(wxTreebook_IsNodeExpanded, 1995). --define(wxTreebook_HitTest, 1997). --define(wxTreebook_InsertPage, 1998). --define(wxTreebook_InsertSubPage, 1999). --define(wxTreebook_SetImageList, 2000). --define(wxTreebook_SetPageSize, 2001). --define(wxTreebook_SetPageImage, 2002). --define(wxTreebook_SetPageText, 2003). --define(wxTreebook_SetSelection, 2004). --define(wxTreebook_ChangeSelection, 2005). --define(wxTreebook_destroy, 2006). --define(wxTreeCtrl_new_2, 2009). --define(wxTreeCtrl_new_0, 2010). --define(wxTreeCtrl_destruct, 2012). --define(wxTreeCtrl_AddRoot, 2013). --define(wxTreeCtrl_AppendItem, 2014). --define(wxTreeCtrl_AssignImageList, 2015). --define(wxTreeCtrl_AssignStateImageList, 2016). --define(wxTreeCtrl_Collapse, 2017). --define(wxTreeCtrl_CollapseAndReset, 2018). --define(wxTreeCtrl_Create, 2019). --define(wxTreeCtrl_Delete, 2020). --define(wxTreeCtrl_DeleteAllItems, 2021). --define(wxTreeCtrl_DeleteChildren, 2022). --define(wxTreeCtrl_EditLabel, 2023). --define(wxTreeCtrl_EnsureVisible, 2024). --define(wxTreeCtrl_Expand, 2025). --define(wxTreeCtrl_GetBoundingRect, 2026). --define(wxTreeCtrl_GetChildrenCount, 2028). --define(wxTreeCtrl_GetCount, 2029). --define(wxTreeCtrl_GetEditControl, 2030). --define(wxTreeCtrl_GetFirstChild, 2031). --define(wxTreeCtrl_GetNextChild, 2032). --define(wxTreeCtrl_GetFirstVisibleItem, 2033). --define(wxTreeCtrl_GetImageList, 2034). --define(wxTreeCtrl_GetIndent, 2035). --define(wxTreeCtrl_GetItemBackgroundColour, 2036). --define(wxTreeCtrl_GetItemData, 2037). --define(wxTreeCtrl_GetItemFont, 2038). --define(wxTreeCtrl_GetItemImage_1, 2039). --define(wxTreeCtrl_GetItemImage_2, 2040). --define(wxTreeCtrl_GetItemText, 2041). --define(wxTreeCtrl_GetItemTextColour, 2042). --define(wxTreeCtrl_GetLastChild, 2043). --define(wxTreeCtrl_GetNextSibling, 2044). --define(wxTreeCtrl_GetNextVisible, 2045). --define(wxTreeCtrl_GetItemParent, 2046). --define(wxTreeCtrl_GetPrevSibling, 2047). --define(wxTreeCtrl_GetPrevVisible, 2048). --define(wxTreeCtrl_GetRootItem, 2049). --define(wxTreeCtrl_GetSelection, 2050). --define(wxTreeCtrl_GetSelections, 2051). --define(wxTreeCtrl_GetStateImageList, 2052). --define(wxTreeCtrl_HitTest, 2053). --define(wxTreeCtrl_InsertItem, 2055). --define(wxTreeCtrl_IsBold, 2056). --define(wxTreeCtrl_IsExpanded, 2057). --define(wxTreeCtrl_IsSelected, 2058). --define(wxTreeCtrl_IsVisible, 2059). --define(wxTreeCtrl_ItemHasChildren, 2060). --define(wxTreeCtrl_IsTreeItemIdOk, 2061). --define(wxTreeCtrl_PrependItem, 2062). --define(wxTreeCtrl_ScrollTo, 2063). --define(wxTreeCtrl_SelectItem_1, 2064). --define(wxTreeCtrl_SelectItem_2, 2065). --define(wxTreeCtrl_SetIndent, 2066). --define(wxTreeCtrl_SetImageList, 2067). --define(wxTreeCtrl_SetItemBackgroundColour, 2068). --define(wxTreeCtrl_SetItemBold, 2069). --define(wxTreeCtrl_SetItemData, 2070). --define(wxTreeCtrl_SetItemDropHighlight, 2071). --define(wxTreeCtrl_SetItemFont, 2072). --define(wxTreeCtrl_SetItemHasChildren, 2073). --define(wxTreeCtrl_SetItemImage_2, 2074). --define(wxTreeCtrl_SetItemImage_3, 2075). --define(wxTreeCtrl_SetItemText, 2076). --define(wxTreeCtrl_SetItemTextColour, 2077). --define(wxTreeCtrl_SetStateImageList, 2078). --define(wxTreeCtrl_SetWindowStyle, 2079). --define(wxTreeCtrl_SortChildren, 2080). --define(wxTreeCtrl_Toggle, 2081). --define(wxTreeCtrl_ToggleItemSelection, 2082). --define(wxTreeCtrl_Unselect, 2083). --define(wxTreeCtrl_UnselectAll, 2084). --define(wxTreeCtrl_UnselectItem, 2085). --define(wxScrollBar_new_0, 2086). --define(wxScrollBar_new_3, 2087). --define(wxScrollBar_destruct, 2088). --define(wxScrollBar_Create, 2089). --define(wxScrollBar_GetRange, 2090). --define(wxScrollBar_GetPageSize, 2091). --define(wxScrollBar_GetThumbPosition, 2092). --define(wxScrollBar_GetThumbSize, 2093). --define(wxScrollBar_SetThumbPosition, 2094). --define(wxScrollBar_SetScrollbar, 2095). --define(wxSpinButton_new_2, 2097). --define(wxSpinButton_new_0, 2098). --define(wxSpinButton_Create, 2099). --define(wxSpinButton_GetMax, 2100). --define(wxSpinButton_GetMin, 2101). --define(wxSpinButton_GetValue, 2102). --define(wxSpinButton_SetRange, 2103). --define(wxSpinButton_SetValue, 2104). --define(wxSpinButton_destroy, 2105). --define(wxSpinCtrl_new_0, 2106). --define(wxSpinCtrl_new_2, 2107). --define(wxSpinCtrl_Create, 2109). --define(wxSpinCtrl_SetValue_1_1, 2112). --define(wxSpinCtrl_SetValue_1_0, 2113). --define(wxSpinCtrl_GetValue, 2115). --define(wxSpinCtrl_SetRange, 2117). --define(wxSpinCtrl_SetSelection, 2118). --define(wxSpinCtrl_GetMin, 2120). --define(wxSpinCtrl_GetMax, 2122). --define(wxSpinCtrl_destroy, 2123). --define(wxStaticText_new_0, 2124). --define(wxStaticText_new_4, 2125). --define(wxStaticText_Create, 2126). --define(wxStaticText_GetLabel, 2127). --define(wxStaticText_SetLabel, 2128). --define(wxStaticText_Wrap, 2129). --define(wxStaticText_destroy, 2130). --define(wxStaticBitmap_new_0, 2131). --define(wxStaticBitmap_new_4, 2132). --define(wxStaticBitmap_Create, 2133). --define(wxStaticBitmap_GetBitmap, 2134). --define(wxStaticBitmap_SetBitmap, 2135). --define(wxStaticBitmap_destroy, 2136). --define(wxRadioBox_new, 2137). --define(wxRadioBox_destruct, 2139). --define(wxRadioBox_Create, 2140). --define(wxRadioBox_Enable_2, 2141). --define(wxRadioBox_Enable_1, 2142). --define(wxRadioBox_GetSelection, 2143). --define(wxRadioBox_GetString, 2144). --define(wxRadioBox_SetSelection, 2145). --define(wxRadioBox_Show_2, 2146). --define(wxRadioBox_Show_1, 2147). --define(wxRadioBox_GetColumnCount, 2148). --define(wxRadioBox_GetItemHelpText, 2149). --define(wxRadioBox_GetItemToolTip, 2150). --define(wxRadioBox_GetItemFromPoint, 2152). --define(wxRadioBox_GetRowCount, 2153). --define(wxRadioBox_IsItemEnabled, 2154). --define(wxRadioBox_IsItemShown, 2155). --define(wxRadioBox_SetItemHelpText, 2156). --define(wxRadioBox_SetItemToolTip, 2157). --define(wxRadioButton_new_0, 2158). --define(wxRadioButton_new_4, 2159). --define(wxRadioButton_Create, 2160). --define(wxRadioButton_GetValue, 2161). --define(wxRadioButton_SetValue, 2162). --define(wxRadioButton_destroy, 2163). --define(wxSlider_new_6, 2165). --define(wxSlider_new_0, 2166). --define(wxSlider_Create, 2167). --define(wxSlider_GetLineSize, 2168). --define(wxSlider_GetMax, 2169). --define(wxSlider_GetMin, 2170). --define(wxSlider_GetPageSize, 2171). --define(wxSlider_GetThumbLength, 2172). --define(wxSlider_GetValue, 2173). --define(wxSlider_SetLineSize, 2174). --define(wxSlider_SetPageSize, 2175). --define(wxSlider_SetRange, 2176). --define(wxSlider_SetThumbLength, 2177). --define(wxSlider_SetValue, 2178). --define(wxSlider_destroy, 2179). --define(wxDialog_new_4, 2181). --define(wxDialog_new_0, 2182). --define(wxDialog_destruct, 2184). --define(wxDialog_Create, 2185). --define(wxDialog_CreateButtonSizer, 2186). --define(wxDialog_CreateStdDialogButtonSizer, 2187). --define(wxDialog_EndModal, 2188). --define(wxDialog_GetAffirmativeId, 2189). --define(wxDialog_GetReturnCode, 2190). --define(wxDialog_IsModal, 2191). --define(wxDialog_SetAffirmativeId, 2192). --define(wxDialog_SetReturnCode, 2193). --define(wxDialog_Show, 2194). --define(wxDialog_ShowModal, 2195). --define(wxColourDialog_new_0, 2196). --define(wxColourDialog_new_2, 2197). --define(wxColourDialog_destruct, 2198). --define(wxColourDialog_Create, 2199). --define(wxColourDialog_GetColourData, 2200). --define(wxColourData_new_0, 2201). --define(wxColourData_new_1, 2202). --define(wxColourData_destruct, 2203). --define(wxColourData_GetChooseFull, 2204). --define(wxColourData_GetColour, 2205). --define(wxColourData_GetCustomColour, 2207). --define(wxColourData_SetChooseFull, 2208). --define(wxColourData_SetColour, 2209). --define(wxColourData_SetCustomColour, 2210). --define(wxPalette_new_0, 2211). --define(wxPalette_new_4, 2212). --define(wxPalette_destruct, 2214). --define(wxPalette_Create, 2215). --define(wxPalette_GetColoursCount, 2216). --define(wxPalette_GetPixel, 2217). --define(wxPalette_GetRGB, 2218). --define(wxPalette_IsOk, 2219). --define(wxDirDialog_new, 2223). --define(wxDirDialog_destruct, 2224). --define(wxDirDialog_GetPath, 2225). --define(wxDirDialog_GetMessage, 2226). --define(wxDirDialog_SetMessage, 2227). --define(wxDirDialog_SetPath, 2228). --define(wxFileDialog_new, 2232). --define(wxFileDialog_destruct, 2233). --define(wxFileDialog_GetDirectory, 2234). --define(wxFileDialog_GetFilename, 2235). --define(wxFileDialog_GetFilenames, 2236). --define(wxFileDialog_GetFilterIndex, 2237). --define(wxFileDialog_GetMessage, 2238). --define(wxFileDialog_GetPath, 2239). --define(wxFileDialog_GetPaths, 2240). --define(wxFileDialog_GetWildcard, 2241). --define(wxFileDialog_SetDirectory, 2242). --define(wxFileDialog_SetFilename, 2243). --define(wxFileDialog_SetFilterIndex, 2244). --define(wxFileDialog_SetMessage, 2245). --define(wxFileDialog_SetPath, 2246). --define(wxFileDialog_SetWildcard, 2247). --define(wxPickerBase_SetInternalMargin, 2248). --define(wxPickerBase_GetInternalMargin, 2249). --define(wxPickerBase_SetTextCtrlProportion, 2250). --define(wxPickerBase_SetPickerCtrlProportion, 2251). --define(wxPickerBase_GetTextCtrlProportion, 2252). --define(wxPickerBase_GetPickerCtrlProportion, 2253). --define(wxPickerBase_HasTextCtrl, 2254). --define(wxPickerBase_GetTextCtrl, 2255). --define(wxPickerBase_IsTextCtrlGrowable, 2256). --define(wxPickerBase_SetPickerCtrlGrowable, 2257). --define(wxPickerBase_SetTextCtrlGrowable, 2258). --define(wxPickerBase_IsPickerCtrlGrowable, 2259). --define(wxFilePickerCtrl_new_0, 2260). --define(wxFilePickerCtrl_new_3, 2261). --define(wxFilePickerCtrl_Create, 2262). --define(wxFilePickerCtrl_GetPath, 2263). --define(wxFilePickerCtrl_SetPath, 2264). --define(wxFilePickerCtrl_destroy, 2265). --define(wxDirPickerCtrl_new_0, 2266). --define(wxDirPickerCtrl_new_3, 2267). --define(wxDirPickerCtrl_Create, 2268). --define(wxDirPickerCtrl_GetPath, 2269). --define(wxDirPickerCtrl_SetPath, 2270). --define(wxDirPickerCtrl_destroy, 2271). --define(wxColourPickerCtrl_new_0, 2272). --define(wxColourPickerCtrl_new_3, 2273). --define(wxColourPickerCtrl_Create, 2274). --define(wxColourPickerCtrl_GetColour, 2275). --define(wxColourPickerCtrl_SetColour_1_1, 2276). --define(wxColourPickerCtrl_SetColour_1_0, 2277). --define(wxColourPickerCtrl_destroy, 2278). --define(wxDatePickerCtrl_new_0, 2279). --define(wxDatePickerCtrl_new_3, 2280). --define(wxDatePickerCtrl_GetRange, 2281). --define(wxDatePickerCtrl_GetValue, 2282). --define(wxDatePickerCtrl_SetRange, 2283). --define(wxDatePickerCtrl_SetValue, 2284). --define(wxDatePickerCtrl_destroy, 2285). --define(wxFontPickerCtrl_new_0, 2286). --define(wxFontPickerCtrl_new_3, 2287). --define(wxFontPickerCtrl_Create, 2288). --define(wxFontPickerCtrl_GetSelectedFont, 2289). --define(wxFontPickerCtrl_SetSelectedFont, 2290). --define(wxFontPickerCtrl_GetMaxPointSize, 2291). --define(wxFontPickerCtrl_SetMaxPointSize, 2292). --define(wxFontPickerCtrl_destroy, 2293). --define(wxFindReplaceDialog_new_0, 2296). --define(wxFindReplaceDialog_new_4, 2297). --define(wxFindReplaceDialog_destruct, 2298). --define(wxFindReplaceDialog_Create, 2299). --define(wxFindReplaceDialog_GetData, 2300). --define(wxFindReplaceData_new_0, 2301). --define(wxFindReplaceData_new_1, 2302). --define(wxFindReplaceData_GetFindString, 2303). --define(wxFindReplaceData_GetReplaceString, 2304). --define(wxFindReplaceData_GetFlags, 2305). --define(wxFindReplaceData_SetFlags, 2306). --define(wxFindReplaceData_SetFindString, 2307). --define(wxFindReplaceData_SetReplaceString, 2308). --define(wxFindReplaceData_destroy, 2309). --define(wxMultiChoiceDialog_new_0, 2310). --define(wxMultiChoiceDialog_new_5, 2312). --define(wxMultiChoiceDialog_GetSelections, 2313). --define(wxMultiChoiceDialog_SetSelections, 2314). --define(wxMultiChoiceDialog_destroy, 2315). --define(wxSingleChoiceDialog_new_0, 2316). --define(wxSingleChoiceDialog_new_5, 2318). --define(wxSingleChoiceDialog_GetSelection, 2319). --define(wxSingleChoiceDialog_GetStringSelection, 2320). --define(wxSingleChoiceDialog_SetSelection, 2321). --define(wxSingleChoiceDialog_destroy, 2322). --define(wxTextEntryDialog_new, 2323). --define(wxTextEntryDialog_GetValue, 2324). --define(wxTextEntryDialog_SetValue, 2325). --define(wxTextEntryDialog_destroy, 2326). --define(wxPasswordEntryDialog_new, 2327). --define(wxPasswordEntryDialog_destroy, 2328). --define(wxFontData_new_0, 2329). --define(wxFontData_new_1, 2330). --define(wxFontData_destruct, 2331). --define(wxFontData_EnableEffects, 2332). --define(wxFontData_GetAllowSymbols, 2333). --define(wxFontData_GetColour, 2334). --define(wxFontData_GetChosenFont, 2335). --define(wxFontData_GetEnableEffects, 2336). --define(wxFontData_GetInitialFont, 2337). --define(wxFontData_GetShowHelp, 2338). --define(wxFontData_SetAllowSymbols, 2339). --define(wxFontData_SetChosenFont, 2340). --define(wxFontData_SetColour, 2341). --define(wxFontData_SetInitialFont, 2342). --define(wxFontData_SetRange, 2343). --define(wxFontData_SetShowHelp, 2344). --define(wxFontDialog_new_0, 2348). --define(wxFontDialog_new_2, 2350). --define(wxFontDialog_Create, 2352). --define(wxFontDialog_GetFontData, 2353). --define(wxFontDialog_destroy, 2355). --define(wxProgressDialog_new, 2356). --define(wxProgressDialog_destruct, 2357). --define(wxProgressDialog_Resume, 2358). --define(wxProgressDialog_Update_2, 2359). --define(wxProgressDialog_Update_0, 2360). --define(wxMessageDialog_new, 2361). --define(wxMessageDialog_destruct, 2362). --define(wxPageSetupDialog_new, 2363). --define(wxPageSetupDialog_destruct, 2364). --define(wxPageSetupDialog_GetPageSetupData, 2365). --define(wxPageSetupDialog_ShowModal, 2366). --define(wxPageSetupDialogData_new_0, 2367). --define(wxPageSetupDialogData_new_1_0, 2368). --define(wxPageSetupDialogData_new_1_1, 2369). --define(wxPageSetupDialogData_destruct, 2370). --define(wxPageSetupDialogData_EnableHelp, 2371). --define(wxPageSetupDialogData_EnableMargins, 2372). --define(wxPageSetupDialogData_EnableOrientation, 2373). --define(wxPageSetupDialogData_EnablePaper, 2374). --define(wxPageSetupDialogData_EnablePrinter, 2375). --define(wxPageSetupDialogData_GetDefaultMinMargins, 2376). --define(wxPageSetupDialogData_GetEnableMargins, 2377). --define(wxPageSetupDialogData_GetEnableOrientation, 2378). --define(wxPageSetupDialogData_GetEnablePaper, 2379). --define(wxPageSetupDialogData_GetEnablePrinter, 2380). --define(wxPageSetupDialogData_GetEnableHelp, 2381). --define(wxPageSetupDialogData_GetDefaultInfo, 2382). --define(wxPageSetupDialogData_GetMarginTopLeft, 2383). --define(wxPageSetupDialogData_GetMarginBottomRight, 2384). --define(wxPageSetupDialogData_GetMinMarginTopLeft, 2385). --define(wxPageSetupDialogData_GetMinMarginBottomRight, 2386). --define(wxPageSetupDialogData_GetPaperId, 2387). --define(wxPageSetupDialogData_GetPaperSize, 2388). --define(wxPageSetupDialogData_GetPrintData, 2390). --define(wxPageSetupDialogData_IsOk, 2391). --define(wxPageSetupDialogData_SetDefaultInfo, 2392). --define(wxPageSetupDialogData_SetDefaultMinMargins, 2393). --define(wxPageSetupDialogData_SetMarginTopLeft, 2394). --define(wxPageSetupDialogData_SetMarginBottomRight, 2395). --define(wxPageSetupDialogData_SetMinMarginTopLeft, 2396). --define(wxPageSetupDialogData_SetMinMarginBottomRight, 2397). --define(wxPageSetupDialogData_SetPaperId, 2398). --define(wxPageSetupDialogData_SetPaperSize_1_1, 2399). --define(wxPageSetupDialogData_SetPaperSize_1_0, 2400). --define(wxPageSetupDialogData_SetPrintData, 2401). --define(wxPrintDialog_new_2_0, 2402). --define(wxPrintDialog_new_2_1, 2403). --define(wxPrintDialog_destruct, 2404). --define(wxPrintDialog_GetPrintDialogData, 2405). --define(wxPrintDialog_GetPrintDC, 2406). --define(wxPrintDialogData_new_0, 2407). --define(wxPrintDialogData_new_1_1, 2408). --define(wxPrintDialogData_new_1_0, 2409). --define(wxPrintDialogData_destruct, 2410). --define(wxPrintDialogData_EnableHelp, 2411). --define(wxPrintDialogData_EnablePageNumbers, 2412). --define(wxPrintDialogData_EnablePrintToFile, 2413). --define(wxPrintDialogData_EnableSelection, 2414). --define(wxPrintDialogData_GetAllPages, 2415). --define(wxPrintDialogData_GetCollate, 2416). --define(wxPrintDialogData_GetFromPage, 2417). --define(wxPrintDialogData_GetMaxPage, 2418). --define(wxPrintDialogData_GetMinPage, 2419). --define(wxPrintDialogData_GetNoCopies, 2420). --define(wxPrintDialogData_GetPrintData, 2421). --define(wxPrintDialogData_GetPrintToFile, 2422). --define(wxPrintDialogData_GetSelection, 2423). --define(wxPrintDialogData_GetToPage, 2424). --define(wxPrintDialogData_IsOk, 2425). --define(wxPrintDialogData_SetCollate, 2426). --define(wxPrintDialogData_SetFromPage, 2427). --define(wxPrintDialogData_SetMaxPage, 2428). --define(wxPrintDialogData_SetMinPage, 2429). --define(wxPrintDialogData_SetNoCopies, 2430). --define(wxPrintDialogData_SetPrintData, 2431). --define(wxPrintDialogData_SetPrintToFile, 2432). --define(wxPrintDialogData_SetSelection, 2433). --define(wxPrintDialogData_SetToPage, 2434). --define(wxPrintData_new_0, 2435). --define(wxPrintData_new_1, 2436). --define(wxPrintData_destruct, 2437). --define(wxPrintData_GetCollate, 2438). --define(wxPrintData_GetBin, 2439). --define(wxPrintData_GetColour, 2440). --define(wxPrintData_GetDuplex, 2441). --define(wxPrintData_GetNoCopies, 2442). --define(wxPrintData_GetOrientation, 2443). --define(wxPrintData_GetPaperId, 2444). --define(wxPrintData_GetPrinterName, 2445). --define(wxPrintData_GetQuality, 2446). --define(wxPrintData_IsOk, 2447). --define(wxPrintData_SetBin, 2448). --define(wxPrintData_SetCollate, 2449). --define(wxPrintData_SetColour, 2450). --define(wxPrintData_SetDuplex, 2451). --define(wxPrintData_SetNoCopies, 2452). --define(wxPrintData_SetOrientation, 2453). --define(wxPrintData_SetPaperId, 2454). --define(wxPrintData_SetPrinterName, 2455). --define(wxPrintData_SetQuality, 2456). --define(wxPrintPreview_new_2, 2459). --define(wxPrintPreview_new_3, 2460). --define(wxPrintPreview_destruct, 2462). --define(wxPrintPreview_GetCanvas, 2463). --define(wxPrintPreview_GetCurrentPage, 2464). --define(wxPrintPreview_GetFrame, 2465). --define(wxPrintPreview_GetMaxPage, 2466). --define(wxPrintPreview_GetMinPage, 2467). --define(wxPrintPreview_GetPrintout, 2468). --define(wxPrintPreview_GetPrintoutForPrinting, 2469). --define(wxPrintPreview_IsOk, 2470). --define(wxPrintPreview_PaintPage, 2471). --define(wxPrintPreview_Print, 2472). --define(wxPrintPreview_RenderPage, 2473). --define(wxPrintPreview_SetCanvas, 2474). --define(wxPrintPreview_SetCurrentPage, 2475). --define(wxPrintPreview_SetFrame, 2476). --define(wxPrintPreview_SetPrintout, 2477). --define(wxPrintPreview_SetZoom, 2478). --define(wxPreviewFrame_new, 2479). --define(wxPreviewFrame_destruct, 2480). --define(wxPreviewFrame_CreateControlBar, 2481). --define(wxPreviewFrame_CreateCanvas, 2482). --define(wxPreviewFrame_Initialize, 2483). --define(wxPreviewFrame_OnCloseWindow, 2484). --define(wxPreviewControlBar_new, 2485). --define(wxPreviewControlBar_destruct, 2486). --define(wxPreviewControlBar_CreateButtons, 2487). --define(wxPreviewControlBar_GetPrintPreview, 2488). --define(wxPreviewControlBar_GetZoomControl, 2489). --define(wxPreviewControlBar_SetZoomControl, 2490). --define(wxPrinter_new, 2492). --define(wxPrinter_CreateAbortWindow, 2493). --define(wxPrinter_GetAbort, 2494). --define(wxPrinter_GetLastError, 2495). --define(wxPrinter_GetPrintDialogData, 2496). --define(wxPrinter_Print, 2497). --define(wxPrinter_PrintDialog, 2498). --define(wxPrinter_ReportError, 2499). --define(wxPrinter_Setup, 2500). --define(wxPrinter_destroy, 2501). --define(wxXmlResource_new_1, 2502). --define(wxXmlResource_new_2, 2503). --define(wxXmlResource_destruct, 2504). --define(wxXmlResource_AttachUnknownControl, 2505). --define(wxXmlResource_ClearHandlers, 2506). --define(wxXmlResource_CompareVersion, 2507). --define(wxXmlResource_Get, 2508). --define(wxXmlResource_GetFlags, 2509). --define(wxXmlResource_GetVersion, 2510). --define(wxXmlResource_GetXRCID, 2511). --define(wxXmlResource_InitAllHandlers, 2512). --define(wxXmlResource_Load, 2513). --define(wxXmlResource_LoadBitmap, 2514). --define(wxXmlResource_LoadDialog_2, 2515). --define(wxXmlResource_LoadDialog_3, 2516). --define(wxXmlResource_LoadFrame_2, 2517). --define(wxXmlResource_LoadFrame_3, 2518). --define(wxXmlResource_LoadIcon, 2519). --define(wxXmlResource_LoadMenu, 2520). --define(wxXmlResource_LoadMenuBar_2, 2521). --define(wxXmlResource_LoadMenuBar_1, 2522). --define(wxXmlResource_LoadPanel_2, 2523). --define(wxXmlResource_LoadPanel_3, 2524). --define(wxXmlResource_LoadToolBar, 2525). --define(wxXmlResource_Set, 2526). --define(wxXmlResource_SetFlags, 2527). --define(wxXmlResource_Unload, 2528). --define(wxXmlResource_xrcctrl, 2529). --define(wxHtmlEasyPrinting_new, 2530). --define(wxHtmlEasyPrinting_destruct, 2531). --define(wxHtmlEasyPrinting_GetPrintData, 2532). --define(wxHtmlEasyPrinting_GetPageSetupData, 2533). --define(wxHtmlEasyPrinting_PreviewFile, 2534). --define(wxHtmlEasyPrinting_PreviewText, 2535). --define(wxHtmlEasyPrinting_PrintFile, 2536). --define(wxHtmlEasyPrinting_PrintText, 2537). --define(wxHtmlEasyPrinting_PageSetup, 2538). --define(wxHtmlEasyPrinting_SetFonts, 2539). --define(wxHtmlEasyPrinting_SetHeader, 2540). --define(wxHtmlEasyPrinting_SetFooter, 2541). --define(wxGLCanvas_new_2, 2543). --define(wxGLCanvas_new_3_1, 2544). --define(wxGLCanvas_new_3_0, 2545). --define(wxGLCanvas_GetContext, 2546). --define(wxGLCanvas_SetCurrent, 2548). --define(wxGLCanvas_SwapBuffers, 2549). --define(wxGLCanvas_destroy, 2550). --define(wxAuiManager_new, 2551). --define(wxAuiManager_destruct, 2552). --define(wxAuiManager_AddPane_2_1, 2553). --define(wxAuiManager_AddPane_3, 2554). --define(wxAuiManager_AddPane_2_0, 2555). --define(wxAuiManager_DetachPane, 2556). --define(wxAuiManager_GetAllPanes, 2557). --define(wxAuiManager_GetArtProvider, 2558). --define(wxAuiManager_GetDockSizeConstraint, 2559). --define(wxAuiManager_GetFlags, 2560). --define(wxAuiManager_GetManagedWindow, 2561). --define(wxAuiManager_GetManager, 2562). --define(wxAuiManager_GetPane_1_1, 2563). --define(wxAuiManager_GetPane_1_0, 2564). --define(wxAuiManager_HideHint, 2565). --define(wxAuiManager_InsertPane, 2566). --define(wxAuiManager_LoadPaneInfo, 2567). --define(wxAuiManager_LoadPerspective, 2568). --define(wxAuiManager_SavePaneInfo, 2569). --define(wxAuiManager_SavePerspective, 2570). --define(wxAuiManager_SetArtProvider, 2571). --define(wxAuiManager_SetDockSizeConstraint, 2572). --define(wxAuiManager_SetFlags, 2573). --define(wxAuiManager_SetManagedWindow, 2574). --define(wxAuiManager_ShowHint, 2575). --define(wxAuiManager_UnInit, 2576). --define(wxAuiManager_Update, 2577). --define(wxAuiPaneInfo_new_0, 2578). --define(wxAuiPaneInfo_new_1, 2579). --define(wxAuiPaneInfo_destruct, 2580). --define(wxAuiPaneInfo_BestSize_1, 2581). --define(wxAuiPaneInfo_BestSize_2, 2582). --define(wxAuiPaneInfo_Bottom, 2583). --define(wxAuiPaneInfo_BottomDockable, 2584). --define(wxAuiPaneInfo_Caption, 2585). --define(wxAuiPaneInfo_CaptionVisible, 2586). --define(wxAuiPaneInfo_Centre, 2587). --define(wxAuiPaneInfo_CentrePane, 2588). --define(wxAuiPaneInfo_CloseButton, 2589). --define(wxAuiPaneInfo_DefaultPane, 2590). --define(wxAuiPaneInfo_DestroyOnClose, 2591). --define(wxAuiPaneInfo_Direction, 2592). --define(wxAuiPaneInfo_Dock, 2593). --define(wxAuiPaneInfo_Dockable, 2594). --define(wxAuiPaneInfo_Fixed, 2595). --define(wxAuiPaneInfo_Float, 2596). --define(wxAuiPaneInfo_Floatable, 2597). --define(wxAuiPaneInfo_FloatingPosition_1, 2598). --define(wxAuiPaneInfo_FloatingPosition_2, 2599). --define(wxAuiPaneInfo_FloatingSize_1, 2600). --define(wxAuiPaneInfo_FloatingSize_2, 2601). --define(wxAuiPaneInfo_Gripper, 2602). --define(wxAuiPaneInfo_GripperTop, 2603). --define(wxAuiPaneInfo_HasBorder, 2604). --define(wxAuiPaneInfo_HasCaption, 2605). --define(wxAuiPaneInfo_HasCloseButton, 2606). --define(wxAuiPaneInfo_HasFlag, 2607). --define(wxAuiPaneInfo_HasGripper, 2608). --define(wxAuiPaneInfo_HasGripperTop, 2609). --define(wxAuiPaneInfo_HasMaximizeButton, 2610). --define(wxAuiPaneInfo_HasMinimizeButton, 2611). --define(wxAuiPaneInfo_HasPinButton, 2612). --define(wxAuiPaneInfo_Hide, 2613). --define(wxAuiPaneInfo_IsBottomDockable, 2614). --define(wxAuiPaneInfo_IsDocked, 2615). --define(wxAuiPaneInfo_IsFixed, 2616). --define(wxAuiPaneInfo_IsFloatable, 2617). --define(wxAuiPaneInfo_IsFloating, 2618). --define(wxAuiPaneInfo_IsLeftDockable, 2619). --define(wxAuiPaneInfo_IsMovable, 2620). --define(wxAuiPaneInfo_IsOk, 2621). --define(wxAuiPaneInfo_IsResizable, 2622). --define(wxAuiPaneInfo_IsRightDockable, 2623). --define(wxAuiPaneInfo_IsShown, 2624). --define(wxAuiPaneInfo_IsToolbar, 2625). --define(wxAuiPaneInfo_IsTopDockable, 2626). --define(wxAuiPaneInfo_Layer, 2627). --define(wxAuiPaneInfo_Left, 2628). --define(wxAuiPaneInfo_LeftDockable, 2629). --define(wxAuiPaneInfo_MaxSize_1, 2630). --define(wxAuiPaneInfo_MaxSize_2, 2631). --define(wxAuiPaneInfo_MaximizeButton, 2632). --define(wxAuiPaneInfo_MinSize_1, 2633). --define(wxAuiPaneInfo_MinSize_2, 2634). --define(wxAuiPaneInfo_MinimizeButton, 2635). --define(wxAuiPaneInfo_Movable, 2636). --define(wxAuiPaneInfo_Name, 2637). --define(wxAuiPaneInfo_PaneBorder, 2638). --define(wxAuiPaneInfo_PinButton, 2639). --define(wxAuiPaneInfo_Position, 2640). --define(wxAuiPaneInfo_Resizable, 2641). --define(wxAuiPaneInfo_Right, 2642). --define(wxAuiPaneInfo_RightDockable, 2643). --define(wxAuiPaneInfo_Row, 2644). --define(wxAuiPaneInfo_SafeSet, 2645). --define(wxAuiPaneInfo_SetFlag, 2646). --define(wxAuiPaneInfo_Show, 2647). --define(wxAuiPaneInfo_ToolbarPane, 2648). --define(wxAuiPaneInfo_Top, 2649). --define(wxAuiPaneInfo_TopDockable, 2650). --define(wxAuiPaneInfo_Window, 2651). --define(wxAuiNotebook_new_0, 2652). --define(wxAuiNotebook_new_2, 2653). --define(wxAuiNotebook_AddPage, 2654). --define(wxAuiNotebook_Create, 2655). --define(wxAuiNotebook_DeletePage, 2656). --define(wxAuiNotebook_GetArtProvider, 2657). --define(wxAuiNotebook_GetPage, 2658). --define(wxAuiNotebook_GetPageBitmap, 2659). --define(wxAuiNotebook_GetPageCount, 2660). --define(wxAuiNotebook_GetPageIndex, 2661). --define(wxAuiNotebook_GetPageText, 2662). --define(wxAuiNotebook_GetSelection, 2663). --define(wxAuiNotebook_InsertPage, 2664). --define(wxAuiNotebook_RemovePage, 2665). --define(wxAuiNotebook_SetArtProvider, 2666). --define(wxAuiNotebook_SetFont, 2667). --define(wxAuiNotebook_SetPageBitmap, 2668). --define(wxAuiNotebook_SetPageText, 2669). --define(wxAuiNotebook_SetSelection, 2670). --define(wxAuiNotebook_SetTabCtrlHeight, 2671). --define(wxAuiNotebook_SetUniformBitmapSize, 2672). --define(wxAuiNotebook_destroy, 2673). --define(wxMDIParentFrame_new_0, 2674). --define(wxMDIParentFrame_new_4, 2675). --define(wxMDIParentFrame_destruct, 2676). --define(wxMDIParentFrame_ActivateNext, 2677). --define(wxMDIParentFrame_ActivatePrevious, 2678). --define(wxMDIParentFrame_ArrangeIcons, 2679). --define(wxMDIParentFrame_Cascade, 2680). --define(wxMDIParentFrame_Create, 2681). --define(wxMDIParentFrame_GetActiveChild, 2682). --define(wxMDIParentFrame_GetClientWindow, 2683). --define(wxMDIParentFrame_Tile, 2684). --define(wxMDIChildFrame_new_0, 2685). --define(wxMDIChildFrame_new_4, 2686). --define(wxMDIChildFrame_destruct, 2687). --define(wxMDIChildFrame_Activate, 2688). --define(wxMDIChildFrame_Create, 2689). --define(wxMDIChildFrame_Maximize, 2690). --define(wxMDIChildFrame_Restore, 2691). --define(wxMDIClientWindow_new_0, 2692). --define(wxMDIClientWindow_new_2, 2693). --define(wxMDIClientWindow_destruct, 2694). --define(wxMDIClientWindow_CreateClient, 2695). --define(wxLayoutAlgorithm_new, 2696). --define(wxLayoutAlgorithm_LayoutFrame, 2697). --define(wxLayoutAlgorithm_LayoutMDIFrame, 2698). --define(wxLayoutAlgorithm_LayoutWindow, 2699). --define(wxLayoutAlgorithm_destroy, 2700). --define(wxEvent_GetId, 2701). --define(wxEvent_GetSkipped, 2702). --define(wxEvent_GetTimestamp, 2703). --define(wxEvent_IsCommandEvent, 2704). --define(wxEvent_ResumePropagation, 2705). --define(wxEvent_ShouldPropagate, 2706). --define(wxEvent_Skip, 2707). --define(wxEvent_StopPropagation, 2708). --define(wxCommandEvent_getClientData, 2709). --define(wxCommandEvent_GetExtraLong, 2710). --define(wxCommandEvent_GetInt, 2711). --define(wxCommandEvent_GetSelection, 2712). --define(wxCommandEvent_GetString, 2713). --define(wxCommandEvent_IsChecked, 2714). --define(wxCommandEvent_IsSelection, 2715). --define(wxCommandEvent_SetInt, 2716). --define(wxCommandEvent_SetString, 2717). --define(wxScrollEvent_GetOrientation, 2718). --define(wxScrollEvent_GetPosition, 2719). --define(wxScrollWinEvent_GetOrientation, 2720). --define(wxScrollWinEvent_GetPosition, 2721). --define(wxMouseEvent_AltDown, 2722). --define(wxMouseEvent_Button, 2723). --define(wxMouseEvent_ButtonDClick, 2724). --define(wxMouseEvent_ButtonDown, 2725). --define(wxMouseEvent_ButtonUp, 2726). --define(wxMouseEvent_CmdDown, 2727). --define(wxMouseEvent_ControlDown, 2728). --define(wxMouseEvent_Dragging, 2729). --define(wxMouseEvent_Entering, 2730). --define(wxMouseEvent_GetButton, 2731). --define(wxMouseEvent_GetPosition, 2734). --define(wxMouseEvent_GetLogicalPosition, 2735). --define(wxMouseEvent_GetLinesPerAction, 2736). --define(wxMouseEvent_GetWheelRotation, 2737). --define(wxMouseEvent_GetWheelDelta, 2738). --define(wxMouseEvent_GetX, 2739). --define(wxMouseEvent_GetY, 2740). --define(wxMouseEvent_IsButton, 2741). --define(wxMouseEvent_IsPageScroll, 2742). --define(wxMouseEvent_Leaving, 2743). --define(wxMouseEvent_LeftDClick, 2744). --define(wxMouseEvent_LeftDown, 2745). --define(wxMouseEvent_LeftIsDown, 2746). --define(wxMouseEvent_LeftUp, 2747). --define(wxMouseEvent_MetaDown, 2748). --define(wxMouseEvent_MiddleDClick, 2749). --define(wxMouseEvent_MiddleDown, 2750). --define(wxMouseEvent_MiddleIsDown, 2751). --define(wxMouseEvent_MiddleUp, 2752). --define(wxMouseEvent_Moving, 2753). --define(wxMouseEvent_RightDClick, 2754). --define(wxMouseEvent_RightDown, 2755). --define(wxMouseEvent_RightIsDown, 2756). --define(wxMouseEvent_RightUp, 2757). --define(wxMouseEvent_ShiftDown, 2758). --define(wxSetCursorEvent_GetCursor, 2759). --define(wxSetCursorEvent_GetX, 2760). --define(wxSetCursorEvent_GetY, 2761). --define(wxSetCursorEvent_HasCursor, 2762). --define(wxSetCursorEvent_SetCursor, 2763). --define(wxKeyEvent_AltDown, 2764). --define(wxKeyEvent_CmdDown, 2765). --define(wxKeyEvent_ControlDown, 2766). --define(wxKeyEvent_GetKeyCode, 2767). --define(wxKeyEvent_GetModifiers, 2768). --define(wxKeyEvent_GetPosition, 2771). --define(wxKeyEvent_GetRawKeyCode, 2772). --define(wxKeyEvent_GetRawKeyFlags, 2773). --define(wxKeyEvent_GetUnicodeKey, 2774). --define(wxKeyEvent_GetX, 2775). --define(wxKeyEvent_GetY, 2776). --define(wxKeyEvent_HasModifiers, 2777). --define(wxKeyEvent_MetaDown, 2778). --define(wxKeyEvent_ShiftDown, 2779). --define(wxSizeEvent_GetSize, 2780). --define(wxMoveEvent_GetPosition, 2781). --define(wxEraseEvent_GetDC, 2782). --define(wxFocusEvent_GetWindow, 2783). --define(wxChildFocusEvent_GetWindow, 2784). --define(wxMenuEvent_GetMenu, 2785). --define(wxMenuEvent_GetMenuId, 2786). --define(wxMenuEvent_IsPopup, 2787). --define(wxCloseEvent_CanVeto, 2788). --define(wxCloseEvent_GetLoggingOff, 2789). --define(wxCloseEvent_SetCanVeto, 2790). --define(wxCloseEvent_SetLoggingOff, 2791). --define(wxCloseEvent_Veto, 2792). --define(wxShowEvent_SetShow, 2793). --define(wxShowEvent_GetShow, 2794). --define(wxIconizeEvent_Iconized, 2795). --define(wxJoystickEvent_ButtonDown, 2796). --define(wxJoystickEvent_ButtonIsDown, 2797). --define(wxJoystickEvent_ButtonUp, 2798). --define(wxJoystickEvent_GetButtonChange, 2799). --define(wxJoystickEvent_GetButtonState, 2800). --define(wxJoystickEvent_GetJoystick, 2801). --define(wxJoystickEvent_GetPosition, 2802). --define(wxJoystickEvent_GetZPosition, 2803). --define(wxJoystickEvent_IsButton, 2804). --define(wxJoystickEvent_IsMove, 2805). --define(wxJoystickEvent_IsZMove, 2806). --define(wxUpdateUIEvent_CanUpdate, 2807). --define(wxUpdateUIEvent_Check, 2808). --define(wxUpdateUIEvent_Enable, 2809). --define(wxUpdateUIEvent_Show, 2810). --define(wxUpdateUIEvent_GetChecked, 2811). --define(wxUpdateUIEvent_GetEnabled, 2812). --define(wxUpdateUIEvent_GetShown, 2813). --define(wxUpdateUIEvent_GetSetChecked, 2814). --define(wxUpdateUIEvent_GetSetEnabled, 2815). --define(wxUpdateUIEvent_GetSetShown, 2816). --define(wxUpdateUIEvent_GetSetText, 2817). --define(wxUpdateUIEvent_GetText, 2818). --define(wxUpdateUIEvent_GetMode, 2819). --define(wxUpdateUIEvent_GetUpdateInterval, 2820). --define(wxUpdateUIEvent_ResetUpdateTime, 2821). --define(wxUpdateUIEvent_SetMode, 2822). --define(wxUpdateUIEvent_SetText, 2823). --define(wxUpdateUIEvent_SetUpdateInterval, 2824). --define(wxMouseCaptureChangedEvent_GetCapturedWindow, 2825). --define(wxPaletteChangedEvent_SetChangedWindow, 2826). --define(wxPaletteChangedEvent_GetChangedWindow, 2827). --define(wxQueryNewPaletteEvent_SetPaletteRealized, 2828). --define(wxQueryNewPaletteEvent_GetPaletteRealized, 2829). --define(wxNavigationKeyEvent_GetDirection, 2830). --define(wxNavigationKeyEvent_SetDirection, 2831). --define(wxNavigationKeyEvent_IsWindowChange, 2832). --define(wxNavigationKeyEvent_SetWindowChange, 2833). --define(wxNavigationKeyEvent_IsFromTab, 2834). --define(wxNavigationKeyEvent_SetFromTab, 2835). --define(wxNavigationKeyEvent_GetCurrentFocus, 2836). --define(wxNavigationKeyEvent_SetCurrentFocus, 2837). --define(wxHelpEvent_GetOrigin, 2838). --define(wxHelpEvent_GetPosition, 2839). --define(wxHelpEvent_SetOrigin, 2840). --define(wxHelpEvent_SetPosition, 2841). --define(wxContextMenuEvent_GetPosition, 2842). --define(wxContextMenuEvent_SetPosition, 2843). --define(wxIdleEvent_CanSend, 2844). --define(wxIdleEvent_GetMode, 2845). --define(wxIdleEvent_RequestMore, 2846). --define(wxIdleEvent_MoreRequested, 2847). --define(wxIdleEvent_SetMode, 2848). --define(wxGridEvent_AltDown, 2849). --define(wxGridEvent_ControlDown, 2850). --define(wxGridEvent_GetCol, 2851). --define(wxGridEvent_GetPosition, 2852). --define(wxGridEvent_GetRow, 2853). --define(wxGridEvent_MetaDown, 2854). --define(wxGridEvent_Selecting, 2855). --define(wxGridEvent_ShiftDown, 2856). --define(wxNotifyEvent_Allow, 2857). --define(wxNotifyEvent_IsAllowed, 2858). --define(wxNotifyEvent_Veto, 2859). --define(wxSashEvent_GetEdge, 2860). --define(wxSashEvent_GetDragRect, 2861). --define(wxSashEvent_GetDragStatus, 2862). --define(wxListEvent_GetCacheFrom, 2863). --define(wxListEvent_GetCacheTo, 2864). --define(wxListEvent_GetKeyCode, 2865). --define(wxListEvent_GetIndex, 2866). --define(wxListEvent_GetColumn, 2867). --define(wxListEvent_GetPoint, 2868). --define(wxListEvent_GetLabel, 2869). --define(wxListEvent_GetText, 2870). --define(wxListEvent_GetImage, 2871). --define(wxListEvent_GetData, 2872). --define(wxListEvent_GetMask, 2873). --define(wxListEvent_GetItem, 2874). --define(wxListEvent_IsEditCancelled, 2875). --define(wxDateEvent_GetDate, 2876). --define(wxCalendarEvent_GetWeekDay, 2877). --define(wxFileDirPickerEvent_GetPath, 2878). --define(wxColourPickerEvent_GetColour, 2879). --define(wxFontPickerEvent_GetFont, 2880). --define(wxStyledTextEvent_GetPosition, 2881). --define(wxStyledTextEvent_GetKey, 2882). --define(wxStyledTextEvent_GetModifiers, 2883). --define(wxStyledTextEvent_GetModificationType, 2884). --define(wxStyledTextEvent_GetText, 2885). --define(wxStyledTextEvent_GetLength, 2886). --define(wxStyledTextEvent_GetLinesAdded, 2887). --define(wxStyledTextEvent_GetLine, 2888). --define(wxStyledTextEvent_GetFoldLevelNow, 2889). --define(wxStyledTextEvent_GetFoldLevelPrev, 2890). --define(wxStyledTextEvent_GetMargin, 2891). --define(wxStyledTextEvent_GetMessage, 2892). --define(wxStyledTextEvent_GetWParam, 2893). --define(wxStyledTextEvent_GetLParam, 2894). --define(wxStyledTextEvent_GetListType, 2895). --define(wxStyledTextEvent_GetX, 2896). --define(wxStyledTextEvent_GetY, 2897). --define(wxStyledTextEvent_GetDragText, 2898). --define(wxStyledTextEvent_GetDragAllowMove, 2899). --define(wxStyledTextEvent_GetDragResult, 2900). --define(wxStyledTextEvent_GetShift, 2901). --define(wxStyledTextEvent_GetControl, 2902). --define(wxStyledTextEvent_GetAlt, 2903). --define(utils_wxGetKeyState, 2904). --define(utils_wxGetMousePosition, 2905). --define(utils_wxGetMouseState, 2906). --define(utils_wxSetDetectableAutoRepeat, 2907). --define(utils_wxBell, 2908). --define(utils_wxFindMenuItemId, 2909). --define(utils_wxGenericFindWindowAtPoint, 2910). --define(utils_wxFindWindowAtPoint, 2911). --define(utils_wxBeginBusyCursor, 2912). --define(utils_wxEndBusyCursor, 2913). --define(utils_wxIsBusy, 2914). --define(utils_wxShutdown, 2915). --define(utils_wxShell, 2916). --define(utils_wxLaunchDefaultBrowser, 2917). --define(utils_wxGetEmailAddress, 2918). --define(utils_wxGetUserId, 2919). --define(utils_wxGetHomeDir, 2920). --define(utils_wxNewId, 2921). --define(utils_wxRegisterId, 2922). --define(utils_wxGetCurrentId, 2923). --define(utils_wxGetOsDescription, 2924). --define(utils_wxIsPlatformLittleEndian, 2925). --define(utils_wxIsPlatform64Bit, 2926). --define(wxPrintout_new, 2927). --define(wxPrintout_destruct, 2928). --define(wxPrintout_GetDC, 2929). --define(wxPrintout_GetPageSizeMM, 2930). --define(wxPrintout_GetPageSizePixels, 2931). --define(wxPrintout_GetPaperRectPixels, 2932). --define(wxPrintout_GetPPIPrinter, 2933). --define(wxPrintout_GetPPIScreen, 2934). --define(wxPrintout_GetTitle, 2935). --define(wxPrintout_IsPreview, 2936). --define(wxPrintout_FitThisSizeToPaper, 2937). --define(wxPrintout_FitThisSizeToPage, 2938). --define(wxPrintout_FitThisSizeToPageMargins, 2939). --define(wxPrintout_MapScreenSizeToPaper, 2940). --define(wxPrintout_MapScreenSizeToPage, 2941). --define(wxPrintout_MapScreenSizeToPageMargins, 2942). --define(wxPrintout_MapScreenSizeToDevice, 2943). --define(wxPrintout_GetLogicalPaperRect, 2944). --define(wxPrintout_GetLogicalPageRect, 2945). --define(wxPrintout_GetLogicalPageMarginsRect, 2946). --define(wxPrintout_SetLogicalOrigin, 2947). --define(wxPrintout_OffsetLogicalOrigin, 2948). --define(wxStyledTextCtrl_new_2, 2949). --define(wxStyledTextCtrl_new_0, 2950). --define(wxStyledTextCtrl_destruct, 2951). --define(wxStyledTextCtrl_Create, 2952). --define(wxStyledTextCtrl_AddText, 2953). --define(wxStyledTextCtrl_AddStyledText, 2954). --define(wxStyledTextCtrl_InsertText, 2955). --define(wxStyledTextCtrl_ClearAll, 2956). --define(wxStyledTextCtrl_ClearDocumentStyle, 2957). --define(wxStyledTextCtrl_GetLength, 2958). --define(wxStyledTextCtrl_GetCharAt, 2959). --define(wxStyledTextCtrl_GetCurrentPos, 2960). --define(wxStyledTextCtrl_GetAnchor, 2961). --define(wxStyledTextCtrl_GetStyleAt, 2962). --define(wxStyledTextCtrl_Redo, 2963). --define(wxStyledTextCtrl_SetUndoCollection, 2964). --define(wxStyledTextCtrl_SelectAll, 2965). --define(wxStyledTextCtrl_SetSavePoint, 2966). --define(wxStyledTextCtrl_GetStyledText, 2967). --define(wxStyledTextCtrl_CanRedo, 2968). --define(wxStyledTextCtrl_MarkerLineFromHandle, 2969). --define(wxStyledTextCtrl_MarkerDeleteHandle, 2970). --define(wxStyledTextCtrl_GetUndoCollection, 2971). --define(wxStyledTextCtrl_GetViewWhiteSpace, 2972). --define(wxStyledTextCtrl_SetViewWhiteSpace, 2973). --define(wxStyledTextCtrl_PositionFromPoint, 2974). --define(wxStyledTextCtrl_PositionFromPointClose, 2975). --define(wxStyledTextCtrl_GotoLine, 2976). --define(wxStyledTextCtrl_GotoPos, 2977). --define(wxStyledTextCtrl_SetAnchor, 2978). --define(wxStyledTextCtrl_GetCurLine, 2979). --define(wxStyledTextCtrl_GetEndStyled, 2980). --define(wxStyledTextCtrl_ConvertEOLs, 2981). --define(wxStyledTextCtrl_GetEOLMode, 2982). --define(wxStyledTextCtrl_SetEOLMode, 2983). --define(wxStyledTextCtrl_StartStyling, 2984). --define(wxStyledTextCtrl_SetStyling, 2985). --define(wxStyledTextCtrl_GetBufferedDraw, 2986). --define(wxStyledTextCtrl_SetBufferedDraw, 2987). --define(wxStyledTextCtrl_SetTabWidth, 2988). --define(wxStyledTextCtrl_GetTabWidth, 2989). --define(wxStyledTextCtrl_SetCodePage, 2990). --define(wxStyledTextCtrl_MarkerDefine, 2991). --define(wxStyledTextCtrl_MarkerSetForeground, 2992). --define(wxStyledTextCtrl_MarkerSetBackground, 2993). --define(wxStyledTextCtrl_MarkerAdd, 2994). --define(wxStyledTextCtrl_MarkerDelete, 2995). --define(wxStyledTextCtrl_MarkerDeleteAll, 2996). --define(wxStyledTextCtrl_MarkerGet, 2997). --define(wxStyledTextCtrl_MarkerNext, 2998). --define(wxStyledTextCtrl_MarkerPrevious, 2999). --define(wxStyledTextCtrl_MarkerDefineBitmap, 3000). --define(wxStyledTextCtrl_MarkerAddSet, 3001). --define(wxStyledTextCtrl_MarkerSetAlpha, 3002). --define(wxStyledTextCtrl_SetMarginType, 3003). --define(wxStyledTextCtrl_GetMarginType, 3004). --define(wxStyledTextCtrl_SetMarginWidth, 3005). --define(wxStyledTextCtrl_GetMarginWidth, 3006). --define(wxStyledTextCtrl_SetMarginMask, 3007). --define(wxStyledTextCtrl_GetMarginMask, 3008). --define(wxStyledTextCtrl_SetMarginSensitive, 3009). --define(wxStyledTextCtrl_GetMarginSensitive, 3010). --define(wxStyledTextCtrl_StyleClearAll, 3011). --define(wxStyledTextCtrl_StyleSetForeground, 3012). --define(wxStyledTextCtrl_StyleSetBackground, 3013). --define(wxStyledTextCtrl_StyleSetBold, 3014). --define(wxStyledTextCtrl_StyleSetItalic, 3015). --define(wxStyledTextCtrl_StyleSetSize, 3016). --define(wxStyledTextCtrl_StyleSetFaceName, 3017). --define(wxStyledTextCtrl_StyleSetEOLFilled, 3018). --define(wxStyledTextCtrl_StyleResetDefault, 3019). --define(wxStyledTextCtrl_StyleSetUnderline, 3020). --define(wxStyledTextCtrl_StyleSetCase, 3021). --define(wxStyledTextCtrl_StyleSetHotSpot, 3022). --define(wxStyledTextCtrl_SetSelForeground, 3023). --define(wxStyledTextCtrl_SetSelBackground, 3024). --define(wxStyledTextCtrl_GetSelAlpha, 3025). --define(wxStyledTextCtrl_SetSelAlpha, 3026). --define(wxStyledTextCtrl_SetCaretForeground, 3027). --define(wxStyledTextCtrl_CmdKeyAssign, 3028). --define(wxStyledTextCtrl_CmdKeyClear, 3029). --define(wxStyledTextCtrl_CmdKeyClearAll, 3030). --define(wxStyledTextCtrl_SetStyleBytes, 3031). --define(wxStyledTextCtrl_StyleSetVisible, 3032). --define(wxStyledTextCtrl_GetCaretPeriod, 3033). --define(wxStyledTextCtrl_SetCaretPeriod, 3034). --define(wxStyledTextCtrl_SetWordChars, 3035). --define(wxStyledTextCtrl_BeginUndoAction, 3036). --define(wxStyledTextCtrl_EndUndoAction, 3037). --define(wxStyledTextCtrl_IndicatorSetStyle, 3038). --define(wxStyledTextCtrl_IndicatorGetStyle, 3039). --define(wxStyledTextCtrl_IndicatorSetForeground, 3040). --define(wxStyledTextCtrl_IndicatorGetForeground, 3041). --define(wxStyledTextCtrl_SetWhitespaceForeground, 3042). --define(wxStyledTextCtrl_SetWhitespaceBackground, 3043). --define(wxStyledTextCtrl_GetStyleBits, 3044). --define(wxStyledTextCtrl_SetLineState, 3045). --define(wxStyledTextCtrl_GetLineState, 3046). --define(wxStyledTextCtrl_GetMaxLineState, 3047). --define(wxStyledTextCtrl_GetCaretLineVisible, 3048). --define(wxStyledTextCtrl_SetCaretLineVisible, 3049). --define(wxStyledTextCtrl_GetCaretLineBackground, 3050). --define(wxStyledTextCtrl_SetCaretLineBackground, 3051). --define(wxStyledTextCtrl_AutoCompShow, 3052). --define(wxStyledTextCtrl_AutoCompCancel, 3053). --define(wxStyledTextCtrl_AutoCompActive, 3054). --define(wxStyledTextCtrl_AutoCompPosStart, 3055). --define(wxStyledTextCtrl_AutoCompComplete, 3056). --define(wxStyledTextCtrl_AutoCompStops, 3057). --define(wxStyledTextCtrl_AutoCompSetSeparator, 3058). --define(wxStyledTextCtrl_AutoCompGetSeparator, 3059). --define(wxStyledTextCtrl_AutoCompSelect, 3060). --define(wxStyledTextCtrl_AutoCompSetCancelAtStart, 3061). --define(wxStyledTextCtrl_AutoCompGetCancelAtStart, 3062). --define(wxStyledTextCtrl_AutoCompSetFillUps, 3063). --define(wxStyledTextCtrl_AutoCompSetChooseSingle, 3064). --define(wxStyledTextCtrl_AutoCompGetChooseSingle, 3065). --define(wxStyledTextCtrl_AutoCompSetIgnoreCase, 3066). --define(wxStyledTextCtrl_AutoCompGetIgnoreCase, 3067). --define(wxStyledTextCtrl_UserListShow, 3068). --define(wxStyledTextCtrl_AutoCompSetAutoHide, 3069). --define(wxStyledTextCtrl_AutoCompGetAutoHide, 3070). --define(wxStyledTextCtrl_AutoCompSetDropRestOfWord, 3071). --define(wxStyledTextCtrl_AutoCompGetDropRestOfWord, 3072). --define(wxStyledTextCtrl_RegisterImage, 3073). --define(wxStyledTextCtrl_ClearRegisteredImages, 3074). --define(wxStyledTextCtrl_AutoCompGetTypeSeparator, 3075). --define(wxStyledTextCtrl_AutoCompSetTypeSeparator, 3076). --define(wxStyledTextCtrl_AutoCompSetMaxWidth, 3077). --define(wxStyledTextCtrl_AutoCompGetMaxWidth, 3078). --define(wxStyledTextCtrl_AutoCompSetMaxHeight, 3079). --define(wxStyledTextCtrl_AutoCompGetMaxHeight, 3080). --define(wxStyledTextCtrl_SetIndent, 3081). --define(wxStyledTextCtrl_GetIndent, 3082). --define(wxStyledTextCtrl_SetUseTabs, 3083). --define(wxStyledTextCtrl_GetUseTabs, 3084). --define(wxStyledTextCtrl_SetLineIndentation, 3085). --define(wxStyledTextCtrl_GetLineIndentation, 3086). --define(wxStyledTextCtrl_GetLineIndentPosition, 3087). --define(wxStyledTextCtrl_GetColumn, 3088). --define(wxStyledTextCtrl_SetUseHorizontalScrollBar, 3089). --define(wxStyledTextCtrl_GetUseHorizontalScrollBar, 3090). --define(wxStyledTextCtrl_SetIndentationGuides, 3091). --define(wxStyledTextCtrl_GetIndentationGuides, 3092). --define(wxStyledTextCtrl_SetHighlightGuide, 3093). --define(wxStyledTextCtrl_GetHighlightGuide, 3094). --define(wxStyledTextCtrl_GetLineEndPosition, 3095). --define(wxStyledTextCtrl_GetCodePage, 3096). --define(wxStyledTextCtrl_GetCaretForeground, 3097). --define(wxStyledTextCtrl_GetReadOnly, 3098). --define(wxStyledTextCtrl_SetCurrentPos, 3099). --define(wxStyledTextCtrl_SetSelectionStart, 3100). --define(wxStyledTextCtrl_GetSelectionStart, 3101). --define(wxStyledTextCtrl_SetSelectionEnd, 3102). --define(wxStyledTextCtrl_GetSelectionEnd, 3103). --define(wxStyledTextCtrl_SetPrintMagnification, 3104). --define(wxStyledTextCtrl_GetPrintMagnification, 3105). --define(wxStyledTextCtrl_SetPrintColourMode, 3106). --define(wxStyledTextCtrl_GetPrintColourMode, 3107). --define(wxStyledTextCtrl_FindText, 3108). --define(wxStyledTextCtrl_FormatRange, 3109). --define(wxStyledTextCtrl_GetFirstVisibleLine, 3110). --define(wxStyledTextCtrl_GetLine, 3111). --define(wxStyledTextCtrl_GetLineCount, 3112). --define(wxStyledTextCtrl_SetMarginLeft, 3113). --define(wxStyledTextCtrl_GetMarginLeft, 3114). --define(wxStyledTextCtrl_SetMarginRight, 3115). --define(wxStyledTextCtrl_GetMarginRight, 3116). --define(wxStyledTextCtrl_GetModify, 3117). --define(wxStyledTextCtrl_SetSelection, 3118). --define(wxStyledTextCtrl_GetSelectedText, 3119). --define(wxStyledTextCtrl_GetTextRange, 3120). --define(wxStyledTextCtrl_HideSelection, 3121). --define(wxStyledTextCtrl_LineFromPosition, 3122). --define(wxStyledTextCtrl_PositionFromLine, 3123). --define(wxStyledTextCtrl_LineScroll, 3124). --define(wxStyledTextCtrl_EnsureCaretVisible, 3125). --define(wxStyledTextCtrl_ReplaceSelection, 3126). --define(wxStyledTextCtrl_SetReadOnly, 3127). --define(wxStyledTextCtrl_CanPaste, 3128). --define(wxStyledTextCtrl_CanUndo, 3129). --define(wxStyledTextCtrl_EmptyUndoBuffer, 3130). --define(wxStyledTextCtrl_Undo, 3131). --define(wxStyledTextCtrl_Cut, 3132). --define(wxStyledTextCtrl_Copy, 3133). --define(wxStyledTextCtrl_Paste, 3134). --define(wxStyledTextCtrl_Clear, 3135). --define(wxStyledTextCtrl_SetText, 3136). --define(wxStyledTextCtrl_GetText, 3137). --define(wxStyledTextCtrl_GetTextLength, 3138). --define(wxStyledTextCtrl_GetOvertype, 3139). --define(wxStyledTextCtrl_SetCaretWidth, 3140). --define(wxStyledTextCtrl_GetCaretWidth, 3141). --define(wxStyledTextCtrl_SetTargetStart, 3142). --define(wxStyledTextCtrl_GetTargetStart, 3143). --define(wxStyledTextCtrl_SetTargetEnd, 3144). --define(wxStyledTextCtrl_GetTargetEnd, 3145). --define(wxStyledTextCtrl_ReplaceTarget, 3146). --define(wxStyledTextCtrl_SearchInTarget, 3147). --define(wxStyledTextCtrl_SetSearchFlags, 3148). --define(wxStyledTextCtrl_GetSearchFlags, 3149). --define(wxStyledTextCtrl_CallTipShow, 3150). --define(wxStyledTextCtrl_CallTipCancel, 3151). --define(wxStyledTextCtrl_CallTipActive, 3152). --define(wxStyledTextCtrl_CallTipPosAtStart, 3153). --define(wxStyledTextCtrl_CallTipSetHighlight, 3154). --define(wxStyledTextCtrl_CallTipSetBackground, 3155). --define(wxStyledTextCtrl_CallTipSetForeground, 3156). --define(wxStyledTextCtrl_CallTipSetForegroundHighlight, 3157). --define(wxStyledTextCtrl_CallTipUseStyle, 3158). --define(wxStyledTextCtrl_VisibleFromDocLine, 3159). --define(wxStyledTextCtrl_DocLineFromVisible, 3160). --define(wxStyledTextCtrl_WrapCount, 3161). --define(wxStyledTextCtrl_SetFoldLevel, 3162). --define(wxStyledTextCtrl_GetFoldLevel, 3163). --define(wxStyledTextCtrl_GetLastChild, 3164). --define(wxStyledTextCtrl_GetFoldParent, 3165). --define(wxStyledTextCtrl_ShowLines, 3166). --define(wxStyledTextCtrl_HideLines, 3167). --define(wxStyledTextCtrl_GetLineVisible, 3168). --define(wxStyledTextCtrl_SetFoldExpanded, 3169). --define(wxStyledTextCtrl_GetFoldExpanded, 3170). --define(wxStyledTextCtrl_ToggleFold, 3171). --define(wxStyledTextCtrl_EnsureVisible, 3172). --define(wxStyledTextCtrl_SetFoldFlags, 3173). --define(wxStyledTextCtrl_EnsureVisibleEnforcePolicy, 3174). --define(wxStyledTextCtrl_SetTabIndents, 3175). --define(wxStyledTextCtrl_GetTabIndents, 3176). --define(wxStyledTextCtrl_SetBackSpaceUnIndents, 3177). --define(wxStyledTextCtrl_GetBackSpaceUnIndents, 3178). --define(wxStyledTextCtrl_SetMouseDwellTime, 3179). --define(wxStyledTextCtrl_GetMouseDwellTime, 3180). --define(wxStyledTextCtrl_WordStartPosition, 3181). --define(wxStyledTextCtrl_WordEndPosition, 3182). --define(wxStyledTextCtrl_SetWrapMode, 3183). --define(wxStyledTextCtrl_GetWrapMode, 3184). --define(wxStyledTextCtrl_SetWrapVisualFlags, 3185). --define(wxStyledTextCtrl_GetWrapVisualFlags, 3186). --define(wxStyledTextCtrl_SetWrapVisualFlagsLocation, 3187). --define(wxStyledTextCtrl_GetWrapVisualFlagsLocation, 3188). --define(wxStyledTextCtrl_SetWrapStartIndent, 3189). --define(wxStyledTextCtrl_GetWrapStartIndent, 3190). --define(wxStyledTextCtrl_SetLayoutCache, 3191). --define(wxStyledTextCtrl_GetLayoutCache, 3192). --define(wxStyledTextCtrl_SetScrollWidth, 3193). --define(wxStyledTextCtrl_GetScrollWidth, 3194). --define(wxStyledTextCtrl_TextWidth, 3195). --define(wxStyledTextCtrl_GetEndAtLastLine, 3196). --define(wxStyledTextCtrl_TextHeight, 3197). --define(wxStyledTextCtrl_SetUseVerticalScrollBar, 3198). --define(wxStyledTextCtrl_GetUseVerticalScrollBar, 3199). --define(wxStyledTextCtrl_AppendText, 3200). --define(wxStyledTextCtrl_GetTwoPhaseDraw, 3201). --define(wxStyledTextCtrl_SetTwoPhaseDraw, 3202). --define(wxStyledTextCtrl_TargetFromSelection, 3203). --define(wxStyledTextCtrl_LinesJoin, 3204). --define(wxStyledTextCtrl_LinesSplit, 3205). --define(wxStyledTextCtrl_SetFoldMarginColour, 3206). --define(wxStyledTextCtrl_SetFoldMarginHiColour, 3207). --define(wxStyledTextCtrl_LineDown, 3208). --define(wxStyledTextCtrl_LineDownExtend, 3209). --define(wxStyledTextCtrl_LineUp, 3210). --define(wxStyledTextCtrl_LineUpExtend, 3211). --define(wxStyledTextCtrl_CharLeft, 3212). --define(wxStyledTextCtrl_CharLeftExtend, 3213). --define(wxStyledTextCtrl_CharRight, 3214). --define(wxStyledTextCtrl_CharRightExtend, 3215). --define(wxStyledTextCtrl_WordLeft, 3216). --define(wxStyledTextCtrl_WordLeftExtend, 3217). --define(wxStyledTextCtrl_WordRight, 3218). --define(wxStyledTextCtrl_WordRightExtend, 3219). --define(wxStyledTextCtrl_Home, 3220). --define(wxStyledTextCtrl_HomeExtend, 3221). --define(wxStyledTextCtrl_LineEnd, 3222). --define(wxStyledTextCtrl_LineEndExtend, 3223). --define(wxStyledTextCtrl_DocumentStart, 3224). --define(wxStyledTextCtrl_DocumentStartExtend, 3225). --define(wxStyledTextCtrl_DocumentEnd, 3226). --define(wxStyledTextCtrl_DocumentEndExtend, 3227). --define(wxStyledTextCtrl_PageUp, 3228). --define(wxStyledTextCtrl_PageUpExtend, 3229). --define(wxStyledTextCtrl_PageDown, 3230). --define(wxStyledTextCtrl_PageDownExtend, 3231). --define(wxStyledTextCtrl_EditToggleOvertype, 3232). --define(wxStyledTextCtrl_Cancel, 3233). --define(wxStyledTextCtrl_DeleteBack, 3234). --define(wxStyledTextCtrl_Tab, 3235). --define(wxStyledTextCtrl_BackTab, 3236). --define(wxStyledTextCtrl_NewLine, 3237). --define(wxStyledTextCtrl_FormFeed, 3238). --define(wxStyledTextCtrl_VCHome, 3239). --define(wxStyledTextCtrl_VCHomeExtend, 3240). --define(wxStyledTextCtrl_ZoomIn, 3241). --define(wxStyledTextCtrl_ZoomOut, 3242). --define(wxStyledTextCtrl_DelWordLeft, 3243). --define(wxStyledTextCtrl_DelWordRight, 3244). --define(wxStyledTextCtrl_LineCut, 3245). --define(wxStyledTextCtrl_LineDelete, 3246). --define(wxStyledTextCtrl_LineTranspose, 3247). --define(wxStyledTextCtrl_LineDuplicate, 3248). --define(wxStyledTextCtrl_LowerCase, 3249). --define(wxStyledTextCtrl_UpperCase, 3250). --define(wxStyledTextCtrl_LineScrollDown, 3251). --define(wxStyledTextCtrl_LineScrollUp, 3252). --define(wxStyledTextCtrl_DeleteBackNotLine, 3253). --define(wxStyledTextCtrl_HomeDisplay, 3254). --define(wxStyledTextCtrl_HomeDisplayExtend, 3255). --define(wxStyledTextCtrl_LineEndDisplay, 3256). --define(wxStyledTextCtrl_LineEndDisplayExtend, 3257). --define(wxStyledTextCtrl_HomeWrapExtend, 3258). --define(wxStyledTextCtrl_LineEndWrap, 3259). --define(wxStyledTextCtrl_LineEndWrapExtend, 3260). --define(wxStyledTextCtrl_VCHomeWrap, 3261). --define(wxStyledTextCtrl_VCHomeWrapExtend, 3262). --define(wxStyledTextCtrl_LineCopy, 3263). --define(wxStyledTextCtrl_MoveCaretInsideView, 3264). --define(wxStyledTextCtrl_LineLength, 3265). --define(wxStyledTextCtrl_BraceHighlight, 3266). --define(wxStyledTextCtrl_BraceBadLight, 3267). --define(wxStyledTextCtrl_BraceMatch, 3268). --define(wxStyledTextCtrl_GetViewEOL, 3269). --define(wxStyledTextCtrl_SetViewEOL, 3270). --define(wxStyledTextCtrl_SetModEventMask, 3271). --define(wxStyledTextCtrl_GetEdgeColumn, 3272). --define(wxStyledTextCtrl_SetEdgeColumn, 3273). --define(wxStyledTextCtrl_SetEdgeMode, 3274). --define(wxStyledTextCtrl_GetEdgeMode, 3275). --define(wxStyledTextCtrl_GetEdgeColour, 3276). --define(wxStyledTextCtrl_SetEdgeColour, 3277). --define(wxStyledTextCtrl_SearchAnchor, 3278). --define(wxStyledTextCtrl_SearchNext, 3279). --define(wxStyledTextCtrl_SearchPrev, 3280). --define(wxStyledTextCtrl_LinesOnScreen, 3281). --define(wxStyledTextCtrl_UsePopUp, 3282). --define(wxStyledTextCtrl_SelectionIsRectangle, 3283). --define(wxStyledTextCtrl_SetZoom, 3284). --define(wxStyledTextCtrl_GetZoom, 3285). --define(wxStyledTextCtrl_GetModEventMask, 3286). --define(wxStyledTextCtrl_SetSTCFocus, 3287). --define(wxStyledTextCtrl_GetSTCFocus, 3288). --define(wxStyledTextCtrl_SetStatus, 3289). --define(wxStyledTextCtrl_GetStatus, 3290). --define(wxStyledTextCtrl_SetMouseDownCaptures, 3291). --define(wxStyledTextCtrl_GetMouseDownCaptures, 3292). --define(wxStyledTextCtrl_SetSTCCursor, 3293). --define(wxStyledTextCtrl_GetSTCCursor, 3294). --define(wxStyledTextCtrl_SetControlCharSymbol, 3295). --define(wxStyledTextCtrl_GetControlCharSymbol, 3296). --define(wxStyledTextCtrl_WordPartLeft, 3297). --define(wxStyledTextCtrl_WordPartLeftExtend, 3298). --define(wxStyledTextCtrl_WordPartRight, 3299). --define(wxStyledTextCtrl_WordPartRightExtend, 3300). --define(wxStyledTextCtrl_SetVisiblePolicy, 3301). --define(wxStyledTextCtrl_DelLineLeft, 3302). --define(wxStyledTextCtrl_DelLineRight, 3303). --define(wxStyledTextCtrl_GetXOffset, 3304). --define(wxStyledTextCtrl_ChooseCaretX, 3305). --define(wxStyledTextCtrl_SetXCaretPolicy, 3306). --define(wxStyledTextCtrl_SetYCaretPolicy, 3307). --define(wxStyledTextCtrl_GetPrintWrapMode, 3308). --define(wxStyledTextCtrl_SetHotspotActiveForeground, 3309). --define(wxStyledTextCtrl_SetHotspotActiveBackground, 3310). --define(wxStyledTextCtrl_SetHotspotActiveUnderline, 3311). --define(wxStyledTextCtrl_SetHotspotSingleLine, 3312). --define(wxStyledTextCtrl_ParaDownExtend, 3313). --define(wxStyledTextCtrl_ParaUp, 3314). --define(wxStyledTextCtrl_ParaUpExtend, 3315). --define(wxStyledTextCtrl_PositionBefore, 3316). --define(wxStyledTextCtrl_PositionAfter, 3317). --define(wxStyledTextCtrl_CopyRange, 3318). --define(wxStyledTextCtrl_CopyText, 3319). --define(wxStyledTextCtrl_SetSelectionMode, 3320). --define(wxStyledTextCtrl_GetSelectionMode, 3321). --define(wxStyledTextCtrl_LineDownRectExtend, 3322). --define(wxStyledTextCtrl_LineUpRectExtend, 3323). --define(wxStyledTextCtrl_CharLeftRectExtend, 3324). --define(wxStyledTextCtrl_CharRightRectExtend, 3325). --define(wxStyledTextCtrl_HomeRectExtend, 3326). --define(wxStyledTextCtrl_VCHomeRectExtend, 3327). --define(wxStyledTextCtrl_LineEndRectExtend, 3328). --define(wxStyledTextCtrl_PageUpRectExtend, 3329). --define(wxStyledTextCtrl_PageDownRectExtend, 3330). --define(wxStyledTextCtrl_StutteredPageUp, 3331). --define(wxStyledTextCtrl_StutteredPageUpExtend, 3332). --define(wxStyledTextCtrl_StutteredPageDown, 3333). --define(wxStyledTextCtrl_StutteredPageDownExtend, 3334). --define(wxStyledTextCtrl_WordLeftEnd, 3335). --define(wxStyledTextCtrl_WordLeftEndExtend, 3336). --define(wxStyledTextCtrl_WordRightEnd, 3337). --define(wxStyledTextCtrl_WordRightEndExtend, 3338). --define(wxStyledTextCtrl_SetWhitespaceChars, 3339). --define(wxStyledTextCtrl_SetCharsDefault, 3340). --define(wxStyledTextCtrl_AutoCompGetCurrent, 3341). --define(wxStyledTextCtrl_Allocate, 3342). --define(wxStyledTextCtrl_FindColumn, 3343). --define(wxStyledTextCtrl_GetCaretSticky, 3344). --define(wxStyledTextCtrl_SetCaretSticky, 3345). --define(wxStyledTextCtrl_ToggleCaretSticky, 3346). --define(wxStyledTextCtrl_SetPasteConvertEndings, 3347). --define(wxStyledTextCtrl_GetPasteConvertEndings, 3348). --define(wxStyledTextCtrl_SelectionDuplicate, 3349). --define(wxStyledTextCtrl_SetCaretLineBackAlpha, 3350). --define(wxStyledTextCtrl_GetCaretLineBackAlpha, 3351). --define(wxStyledTextCtrl_StartRecord, 3352). --define(wxStyledTextCtrl_StopRecord, 3353). --define(wxStyledTextCtrl_SetLexer, 3354). --define(wxStyledTextCtrl_GetLexer, 3355). --define(wxStyledTextCtrl_Colourise, 3356). --define(wxStyledTextCtrl_SetProperty, 3357). --define(wxStyledTextCtrl_SetKeyWords, 3358). --define(wxStyledTextCtrl_SetLexerLanguage, 3359). --define(wxStyledTextCtrl_GetProperty, 3360). --define(wxStyledTextCtrl_GetStyleBitsNeeded, 3361). --define(wxStyledTextCtrl_GetCurrentLine, 3362). --define(wxStyledTextCtrl_StyleSetSpec, 3363). --define(wxStyledTextCtrl_StyleSetFont, 3364). --define(wxStyledTextCtrl_StyleSetFontAttr, 3365). --define(wxStyledTextCtrl_StyleSetCharacterSet, 3366). --define(wxStyledTextCtrl_StyleSetFontEncoding, 3367). --define(wxStyledTextCtrl_CmdKeyExecute, 3368). --define(wxStyledTextCtrl_SetMargins, 3369). --define(wxStyledTextCtrl_GetSelection, 3370). --define(wxStyledTextCtrl_PointFromPosition, 3371). --define(wxStyledTextCtrl_ScrollToLine, 3372). --define(wxStyledTextCtrl_ScrollToColumn, 3373). --define(wxStyledTextCtrl_SetVScrollBar, 3374). --define(wxStyledTextCtrl_SetHScrollBar, 3375). --define(wxStyledTextCtrl_GetLastKeydownProcessed, 3376). --define(wxStyledTextCtrl_SetLastKeydownProcessed, 3377). --define(wxStyledTextCtrl_SaveFile, 3378). --define(wxStyledTextCtrl_LoadFile, 3379). --define(wxStyledTextCtrl_DoDragOver, 3380). --define(wxStyledTextCtrl_DoDropText, 3381). --define(wxStyledTextCtrl_GetUseAntiAliasing, 3382). --define(wxStyledTextCtrl_AddTextRaw, 3383). --define(wxStyledTextCtrl_InsertTextRaw, 3384). --define(wxStyledTextCtrl_GetCurLineRaw, 3385). --define(wxStyledTextCtrl_GetLineRaw, 3386). --define(wxStyledTextCtrl_GetSelectedTextRaw, 3387). --define(wxStyledTextCtrl_GetTextRangeRaw, 3388). --define(wxStyledTextCtrl_SetTextRaw, 3389). --define(wxStyledTextCtrl_GetTextRaw, 3390). --define(wxStyledTextCtrl_AppendTextRaw, 3391). --define(wxArtProvider_GetBitmap, 3392). --define(wxArtProvider_GetIcon, 3393). --define(wxTreeEvent_GetKeyCode, 3394). --define(wxTreeEvent_GetItem, 3395). --define(wxTreeEvent_GetKeyEvent, 3396). --define(wxTreeEvent_GetLabel, 3397). --define(wxTreeEvent_GetOldItem, 3398). --define(wxTreeEvent_GetPoint, 3399). --define(wxTreeEvent_IsEditCancelled, 3400). --define(wxTreeEvent_SetToolTip, 3401). --define(wxNotebookEvent_GetOldSelection, 3402). --define(wxNotebookEvent_GetSelection, 3403). --define(wxNotebookEvent_SetOldSelection, 3404). --define(wxNotebookEvent_SetSelection, 3405). --define(wxFileDataObject_new, 3406). --define(wxFileDataObject_AddFile, 3407). --define(wxFileDataObject_GetFilenames, 3408). --define(wxFileDataObject_destroy, 3409). --define(wxTextDataObject_new, 3410). --define(wxTextDataObject_GetTextLength, 3411). --define(wxTextDataObject_GetText, 3412). --define(wxTextDataObject_SetText, 3413). --define(wxTextDataObject_destroy, 3414). --define(wxBitmapDataObject_new_1_1, 3415). --define(wxBitmapDataObject_new_1_0, 3416). --define(wxBitmapDataObject_GetBitmap, 3417). --define(wxBitmapDataObject_SetBitmap, 3418). --define(wxBitmapDataObject_destroy, 3419). --define(wxClipboard_new, 3421). --define(wxClipboard_destruct, 3422). --define(wxClipboard_AddData, 3423). --define(wxClipboard_Clear, 3424). --define(wxClipboard_Close, 3425). --define(wxClipboard_Flush, 3426). --define(wxClipboard_GetData, 3427). --define(wxClipboard_IsOpened, 3428). --define(wxClipboard_Open, 3429). --define(wxClipboard_SetData, 3430). --define(wxClipboard_UsePrimarySelection, 3432). --define(wxClipboard_IsSupported, 3433). --define(wxClipboard_Get, 3434). --define(wxSpinEvent_GetPosition, 3435). --define(wxSpinEvent_SetPosition, 3436). --define(wxSplitterWindow_new_0, 3437). --define(wxSplitterWindow_new_2, 3438). --define(wxSplitterWindow_destruct, 3439). --define(wxSplitterWindow_Create, 3440). --define(wxSplitterWindow_GetMinimumPaneSize, 3441). --define(wxSplitterWindow_GetSashGravity, 3442). --define(wxSplitterWindow_GetSashPosition, 3443). --define(wxSplitterWindow_GetSplitMode, 3444). --define(wxSplitterWindow_GetWindow1, 3445). --define(wxSplitterWindow_GetWindow2, 3446). --define(wxSplitterWindow_Initialize, 3447). --define(wxSplitterWindow_IsSplit, 3448). --define(wxSplitterWindow_ReplaceWindow, 3449). --define(wxSplitterWindow_SetSashGravity, 3450). --define(wxSplitterWindow_SetSashPosition, 3451). --define(wxSplitterWindow_SetSashSize, 3452). --define(wxSplitterWindow_SetMinimumPaneSize, 3453). --define(wxSplitterWindow_SetSplitMode, 3454). --define(wxSplitterWindow_SplitHorizontally, 3455). --define(wxSplitterWindow_SplitVertically, 3456). --define(wxSplitterWindow_Unsplit, 3457). --define(wxSplitterWindow_UpdateSize, 3458). --define(wxSplitterEvent_GetSashPosition, 3459). --define(wxSplitterEvent_GetX, 3460). --define(wxSplitterEvent_GetY, 3461). --define(wxSplitterEvent_GetWindowBeingRemoved, 3462). --define(wxSplitterEvent_SetSashPosition, 3463). --define(wxHtmlWindow_new_0, 3464). --define(wxHtmlWindow_new_2, 3465). --define(wxHtmlWindow_AppendToPage, 3466). --define(wxHtmlWindow_GetOpenedAnchor, 3467). --define(wxHtmlWindow_GetOpenedPage, 3468). --define(wxHtmlWindow_GetOpenedPageTitle, 3469). --define(wxHtmlWindow_GetRelatedFrame, 3470). --define(wxHtmlWindow_HistoryBack, 3471). --define(wxHtmlWindow_HistoryCanBack, 3472). --define(wxHtmlWindow_HistoryCanForward, 3473). --define(wxHtmlWindow_HistoryClear, 3474). --define(wxHtmlWindow_HistoryForward, 3475). --define(wxHtmlWindow_LoadFile, 3476). --define(wxHtmlWindow_LoadPage, 3477). --define(wxHtmlWindow_SelectAll, 3478). --define(wxHtmlWindow_SelectionToText, 3479). --define(wxHtmlWindow_SelectLine, 3480). --define(wxHtmlWindow_SelectWord, 3481). --define(wxHtmlWindow_SetBorders, 3482). --define(wxHtmlWindow_SetFonts, 3483). --define(wxHtmlWindow_SetPage, 3484). --define(wxHtmlWindow_SetRelatedFrame, 3485). --define(wxHtmlWindow_SetRelatedStatusBar, 3486). --define(wxHtmlWindow_ToText, 3487). --define(wxHtmlWindow_destroy, 3488). --define(wxHtmlLinkEvent_GetLinkInfo, 3489). --define(wxSystemSettings_GetColour, 3490). --define(wxSystemSettings_GetFont, 3491). --define(wxSystemSettings_GetMetric, 3492). --define(wxSystemSettings_GetScreenType, 3493). --define(wxSystemOptions_GetOption, 3494). --define(wxSystemOptions_GetOptionInt, 3495). --define(wxSystemOptions_HasOption, 3496). --define(wxSystemOptions_IsFalse, 3497). --define(wxSystemOptions_SetOption_2_1, 3498). --define(wxSystemOptions_SetOption_2_0, 3499). --define(wxAuiNotebookEvent_SetSelection, 3500). --define(wxAuiNotebookEvent_GetSelection, 3501). --define(wxAuiNotebookEvent_SetOldSelection, 3502). --define(wxAuiNotebookEvent_GetOldSelection, 3503). --define(wxAuiNotebookEvent_SetDragSource, 3504). --define(wxAuiNotebookEvent_GetDragSource, 3505). --define(wxAuiManagerEvent_SetManager, 3506). --define(wxAuiManagerEvent_GetManager, 3507). --define(wxAuiManagerEvent_SetPane, 3508). --define(wxAuiManagerEvent_GetPane, 3509). --define(wxAuiManagerEvent_SetButton, 3510). --define(wxAuiManagerEvent_GetButton, 3511). --define(wxAuiManagerEvent_SetDC, 3512). --define(wxAuiManagerEvent_GetDC, 3513). --define(wxAuiManagerEvent_Veto, 3514). --define(wxAuiManagerEvent_GetVeto, 3515). --define(wxAuiManagerEvent_SetCanVeto, 3516). --define(wxAuiManagerEvent_CanVeto, 3517). --define(wxLogNull_new, 3518). --define(wxLogNull_destroy, 3519). --define(wxTaskBarIcon_new, 3520). --define(wxTaskBarIcon_destruct, 3521). --define(wxTaskBarIcon_PopupMenu, 3522). --define(wxTaskBarIcon_RemoveIcon, 3523). --define(wxTaskBarIcon_SetIcon, 3524). +-define(wxPanel_SetFocusIgnoringChildren, 337). +-define(wxScrolledWindow_new_0, 338). +-define(wxScrolledWindow_new_2, 339). +-define(wxScrolledWindow_destruct, 340). +-define(wxScrolledWindow_CalcScrolledPosition_4, 341). +-define(wxScrolledWindow_CalcScrolledPosition_1, 342). +-define(wxScrolledWindow_CalcUnscrolledPosition_4, 343). +-define(wxScrolledWindow_CalcUnscrolledPosition_1, 344). +-define(wxScrolledWindow_EnableScrolling, 345). +-define(wxScrolledWindow_GetScrollPixelsPerUnit, 346). +-define(wxScrolledWindow_GetViewStart, 347). +-define(wxScrolledWindow_DoPrepareDC, 348). +-define(wxScrolledWindow_PrepareDC, 349). +-define(wxScrolledWindow_Scroll, 350). +-define(wxScrolledWindow_SetScrollbars, 351). +-define(wxScrolledWindow_SetScrollRate, 352). +-define(wxScrolledWindow_SetTargetWindow, 353). +-define(wxSashWindow_new_0, 354). +-define(wxSashWindow_new_2, 355). +-define(wxSashWindow_destruct, 356). +-define(wxSashWindow_GetSashVisible, 357). +-define(wxSashWindow_GetMaximumSizeX, 358). +-define(wxSashWindow_GetMaximumSizeY, 359). +-define(wxSashWindow_GetMinimumSizeX, 360). +-define(wxSashWindow_GetMinimumSizeY, 361). +-define(wxSashWindow_SetMaximumSizeX, 362). +-define(wxSashWindow_SetMaximumSizeY, 363). +-define(wxSashWindow_SetMinimumSizeX, 364). +-define(wxSashWindow_SetMinimumSizeY, 365). +-define(wxSashWindow_SetSashVisible, 366). +-define(wxSashLayoutWindow_new_0, 367). +-define(wxSashLayoutWindow_new_2, 368). +-define(wxSashLayoutWindow_Create, 369). +-define(wxSashLayoutWindow_GetAlignment, 370). +-define(wxSashLayoutWindow_GetOrientation, 371). +-define(wxSashLayoutWindow_SetAlignment, 372). +-define(wxSashLayoutWindow_SetDefaultSize, 373). +-define(wxSashLayoutWindow_SetOrientation, 374). +-define(wxSashLayoutWindow_destroy, 375). +-define(wxGrid_new_0, 376). +-define(wxGrid_new_3, 377). +-define(wxGrid_new_4, 378). +-define(wxGrid_destruct, 379). +-define(wxGrid_AppendCols, 380). +-define(wxGrid_AppendRows, 381). +-define(wxGrid_AutoSize, 382). +-define(wxGrid_AutoSizeColumn, 383). +-define(wxGrid_AutoSizeColumns, 384). +-define(wxGrid_AutoSizeRow, 385). +-define(wxGrid_AutoSizeRows, 386). +-define(wxGrid_BeginBatch, 387). +-define(wxGrid_BlockToDeviceRect, 388). +-define(wxGrid_CanDragColSize, 389). +-define(wxGrid_CanDragRowSize, 390). +-define(wxGrid_CanDragGridSize, 391). +-define(wxGrid_CanEnableCellControl, 392). +-define(wxGrid_CellToRect_2, 393). +-define(wxGrid_CellToRect_1, 394). +-define(wxGrid_ClearGrid, 395). +-define(wxGrid_ClearSelection, 396). +-define(wxGrid_CreateGrid, 397). +-define(wxGrid_DeleteCols, 398). +-define(wxGrid_DeleteRows, 399). +-define(wxGrid_DisableCellEditControl, 400). +-define(wxGrid_DisableDragColSize, 401). +-define(wxGrid_DisableDragGridSize, 402). +-define(wxGrid_DisableDragRowSize, 403). +-define(wxGrid_EnableCellEditControl, 404). +-define(wxGrid_EnableDragColSize, 405). +-define(wxGrid_EnableDragGridSize, 406). +-define(wxGrid_EnableDragRowSize, 407). +-define(wxGrid_EnableEditing, 408). +-define(wxGrid_EnableGridLines, 409). +-define(wxGrid_EndBatch, 410). +-define(wxGrid_Fit, 411). +-define(wxGrid_ForceRefresh, 412). +-define(wxGrid_GetBatchCount, 413). +-define(wxGrid_GetCellAlignment, 414). +-define(wxGrid_GetCellBackgroundColour, 415). +-define(wxGrid_GetCellEditor, 416). +-define(wxGrid_GetCellFont, 417). +-define(wxGrid_GetCellRenderer, 418). +-define(wxGrid_GetCellTextColour, 419). +-define(wxGrid_GetCellValue_2, 420). +-define(wxGrid_GetCellValue_1, 421). +-define(wxGrid_GetColLabelAlignment, 422). +-define(wxGrid_GetColLabelSize, 423). +-define(wxGrid_GetColLabelValue, 424). +-define(wxGrid_GetColMinimalAcceptableWidth, 425). +-define(wxGrid_GetDefaultCellAlignment, 426). +-define(wxGrid_GetDefaultCellBackgroundColour, 427). +-define(wxGrid_GetDefaultCellFont, 428). +-define(wxGrid_GetDefaultCellTextColour, 429). +-define(wxGrid_GetDefaultColLabelSize, 430). +-define(wxGrid_GetDefaultColSize, 431). +-define(wxGrid_GetDefaultEditor, 432). +-define(wxGrid_GetDefaultEditorForCell_2, 433). +-define(wxGrid_GetDefaultEditorForCell_1, 434). +-define(wxGrid_GetDefaultEditorForType, 435). +-define(wxGrid_GetDefaultRenderer, 436). +-define(wxGrid_GetDefaultRendererForCell, 437). +-define(wxGrid_GetDefaultRendererForType, 438). +-define(wxGrid_GetDefaultRowLabelSize, 439). +-define(wxGrid_GetDefaultRowSize, 440). +-define(wxGrid_GetGridCursorCol, 441). +-define(wxGrid_GetGridCursorRow, 442). +-define(wxGrid_GetGridLineColour, 443). +-define(wxGrid_GridLinesEnabled, 444). +-define(wxGrid_GetLabelBackgroundColour, 445). +-define(wxGrid_GetLabelFont, 446). +-define(wxGrid_GetLabelTextColour, 447). +-define(wxGrid_GetNumberCols, 448). +-define(wxGrid_GetNumberRows, 449). +-define(wxGrid_GetOrCreateCellAttr, 450). +-define(wxGrid_GetRowMinimalAcceptableHeight, 451). +-define(wxGrid_GetRowLabelAlignment, 452). +-define(wxGrid_GetRowLabelSize, 453). +-define(wxGrid_GetRowLabelValue, 454). +-define(wxGrid_GetRowSize, 455). +-define(wxGrid_GetScrollLineX, 456). +-define(wxGrid_GetScrollLineY, 457). +-define(wxGrid_GetSelectedCells, 458). +-define(wxGrid_GetSelectedCols, 459). +-define(wxGrid_GetSelectedRows, 460). +-define(wxGrid_GetSelectionBackground, 461). +-define(wxGrid_GetSelectionBlockTopLeft, 462). +-define(wxGrid_GetSelectionBlockBottomRight, 463). +-define(wxGrid_GetSelectionForeground, 464). +-define(wxGrid_GetViewWidth, 465). +-define(wxGrid_GetGridWindow, 466). +-define(wxGrid_GetGridRowLabelWindow, 467). +-define(wxGrid_GetGridColLabelWindow, 468). +-define(wxGrid_GetGridCornerLabelWindow, 469). +-define(wxGrid_HideCellEditControl, 470). +-define(wxGrid_InsertCols, 471). +-define(wxGrid_InsertRows, 472). +-define(wxGrid_IsCellEditControlEnabled, 473). +-define(wxGrid_IsCurrentCellReadOnly, 474). +-define(wxGrid_IsEditable, 475). +-define(wxGrid_IsInSelection_2, 476). +-define(wxGrid_IsInSelection_1, 477). +-define(wxGrid_IsReadOnly, 478). +-define(wxGrid_IsSelection, 479). +-define(wxGrid_IsVisible_3, 480). +-define(wxGrid_IsVisible_2, 481). +-define(wxGrid_MakeCellVisible_2, 482). +-define(wxGrid_MakeCellVisible_1, 483). +-define(wxGrid_MoveCursorDown, 484). +-define(wxGrid_MoveCursorLeft, 485). +-define(wxGrid_MoveCursorRight, 486). +-define(wxGrid_MoveCursorUp, 487). +-define(wxGrid_MoveCursorDownBlock, 488). +-define(wxGrid_MoveCursorLeftBlock, 489). +-define(wxGrid_MoveCursorRightBlock, 490). +-define(wxGrid_MoveCursorUpBlock, 491). +-define(wxGrid_MovePageDown, 492). +-define(wxGrid_MovePageUp, 493). +-define(wxGrid_RegisterDataType, 494). +-define(wxGrid_SaveEditControlValue, 495). +-define(wxGrid_SelectAll, 496). +-define(wxGrid_SelectBlock_5, 497). +-define(wxGrid_SelectBlock_3, 498). +-define(wxGrid_SelectCol, 499). +-define(wxGrid_SelectRow, 500). +-define(wxGrid_SetCellAlignment_4, 501). +-define(wxGrid_SetCellAlignment_3, 502). +-define(wxGrid_SetCellAlignment_1, 503). +-define(wxGrid_SetCellBackgroundColour_3_0, 504). +-define(wxGrid_SetCellBackgroundColour_1, 505). +-define(wxGrid_SetCellBackgroundColour_3_1, 506). +-define(wxGrid_SetCellEditor, 507). +-define(wxGrid_SetCellFont, 508). +-define(wxGrid_SetCellRenderer, 509). +-define(wxGrid_SetCellTextColour_3_0, 510). +-define(wxGrid_SetCellTextColour_3_1, 511). +-define(wxGrid_SetCellTextColour_1, 512). +-define(wxGrid_SetCellValue_3_0, 513). +-define(wxGrid_SetCellValue_2, 514). +-define(wxGrid_SetCellValue_3_1, 515). +-define(wxGrid_SetColAttr, 516). +-define(wxGrid_SetColFormatBool, 517). +-define(wxGrid_SetColFormatNumber, 518). +-define(wxGrid_SetColFormatFloat, 519). +-define(wxGrid_SetColFormatCustom, 520). +-define(wxGrid_SetColLabelAlignment, 521). +-define(wxGrid_SetColLabelSize, 522). +-define(wxGrid_SetColLabelValue, 523). +-define(wxGrid_SetColMinimalWidth, 524). +-define(wxGrid_SetColMinimalAcceptableWidth, 525). +-define(wxGrid_SetColSize, 526). +-define(wxGrid_SetDefaultCellAlignment, 527). +-define(wxGrid_SetDefaultCellBackgroundColour, 528). +-define(wxGrid_SetDefaultCellFont, 529). +-define(wxGrid_SetDefaultCellTextColour, 530). +-define(wxGrid_SetDefaultEditor, 531). +-define(wxGrid_SetDefaultRenderer, 532). +-define(wxGrid_SetDefaultColSize, 533). +-define(wxGrid_SetDefaultRowSize, 534). +-define(wxGrid_SetGridCursor, 535). +-define(wxGrid_SetGridLineColour, 536). +-define(wxGrid_SetLabelBackgroundColour, 537). +-define(wxGrid_SetLabelFont, 538). +-define(wxGrid_SetLabelTextColour, 539). +-define(wxGrid_SetMargins, 540). +-define(wxGrid_SetReadOnly, 541). +-define(wxGrid_SetRowAttr, 542). +-define(wxGrid_SetRowLabelAlignment, 543). +-define(wxGrid_SetRowLabelSize, 544). +-define(wxGrid_SetRowLabelValue, 545). +-define(wxGrid_SetRowMinimalHeight, 546). +-define(wxGrid_SetRowMinimalAcceptableHeight, 547). +-define(wxGrid_SetRowSize, 548). +-define(wxGrid_SetScrollLineX, 549). +-define(wxGrid_SetScrollLineY, 550). +-define(wxGrid_SetSelectionBackground, 551). +-define(wxGrid_SetSelectionForeground, 552). +-define(wxGrid_SetSelectionMode, 553). +-define(wxGrid_ShowCellEditControl, 554). +-define(wxGrid_XToCol, 555). +-define(wxGrid_XToEdgeOfCol, 556). +-define(wxGrid_YToEdgeOfRow, 557). +-define(wxGrid_YToRow, 558). +-define(wxGridCellRenderer_Draw, 559). +-define(wxGridCellRenderer_GetBestSize, 560). +-define(wxGridCellEditor_Create, 561). +-define(wxGridCellEditor_IsCreated, 562). +-define(wxGridCellEditor_SetSize, 563). +-define(wxGridCellEditor_Show, 564). +-define(wxGridCellEditor_PaintBackground, 565). +-define(wxGridCellEditor_BeginEdit, 566). +-define(wxGridCellEditor_EndEdit, 567). +-define(wxGridCellEditor_Reset, 568). +-define(wxGridCellEditor_StartingKey, 569). +-define(wxGridCellEditor_StartingClick, 570). +-define(wxGridCellEditor_HandleReturn, 571). +-define(wxGridCellBoolRenderer_new, 572). +-define(wxGridCellBoolRenderer_destroy, 573). +-define(wxGridCellBoolEditor_new, 574). +-define(wxGridCellBoolEditor_IsTrueValue, 575). +-define(wxGridCellBoolEditor_UseStringValues, 576). +-define(wxGridCellBoolEditor_destroy, 577). +-define(wxGridCellFloatRenderer_new, 578). +-define(wxGridCellFloatRenderer_GetPrecision, 579). +-define(wxGridCellFloatRenderer_GetWidth, 580). +-define(wxGridCellFloatRenderer_SetParameters, 581). +-define(wxGridCellFloatRenderer_SetPrecision, 582). +-define(wxGridCellFloatRenderer_SetWidth, 583). +-define(wxGridCellFloatRenderer_destroy, 584). +-define(wxGridCellFloatEditor_new, 585). +-define(wxGridCellFloatEditor_SetParameters, 586). +-define(wxGridCellFloatEditor_destroy, 587). +-define(wxGridCellStringRenderer_new, 588). +-define(wxGridCellStringRenderer_destroy, 589). +-define(wxGridCellTextEditor_new, 590). +-define(wxGridCellTextEditor_SetParameters, 591). +-define(wxGridCellTextEditor_destroy, 592). +-define(wxGridCellChoiceEditor_new, 594). +-define(wxGridCellChoiceEditor_SetParameters, 595). +-define(wxGridCellChoiceEditor_destroy, 596). +-define(wxGridCellNumberRenderer_new, 597). +-define(wxGridCellNumberRenderer_destroy, 598). +-define(wxGridCellNumberEditor_new, 599). +-define(wxGridCellNumberEditor_GetValue, 600). +-define(wxGridCellNumberEditor_SetParameters, 601). +-define(wxGridCellNumberEditor_destroy, 602). +-define(wxGridCellAttr_SetTextColour, 603). +-define(wxGridCellAttr_SetBackgroundColour, 604). +-define(wxGridCellAttr_SetFont, 605). +-define(wxGridCellAttr_SetAlignment, 606). +-define(wxGridCellAttr_SetReadOnly, 607). +-define(wxGridCellAttr_SetRenderer, 608). +-define(wxGridCellAttr_SetEditor, 609). +-define(wxGridCellAttr_HasTextColour, 610). +-define(wxGridCellAttr_HasBackgroundColour, 611). +-define(wxGridCellAttr_HasFont, 612). +-define(wxGridCellAttr_HasAlignment, 613). +-define(wxGridCellAttr_HasRenderer, 614). +-define(wxGridCellAttr_HasEditor, 615). +-define(wxGridCellAttr_GetTextColour, 616). +-define(wxGridCellAttr_GetBackgroundColour, 617). +-define(wxGridCellAttr_GetFont, 618). +-define(wxGridCellAttr_GetAlignment, 619). +-define(wxGridCellAttr_GetRenderer, 620). +-define(wxGridCellAttr_GetEditor, 621). +-define(wxGridCellAttr_IsReadOnly, 622). +-define(wxGridCellAttr_SetDefAttr, 623). +-define(wxDC_Blit, 624). +-define(wxDC_CalcBoundingBox, 625). +-define(wxDC_Clear, 626). +-define(wxDC_ComputeScaleAndOrigin, 627). +-define(wxDC_CrossHair, 628). +-define(wxDC_DestroyClippingRegion, 629). +-define(wxDC_DeviceToLogicalX, 630). +-define(wxDC_DeviceToLogicalXRel, 631). +-define(wxDC_DeviceToLogicalY, 632). +-define(wxDC_DeviceToLogicalYRel, 633). +-define(wxDC_DrawArc, 634). +-define(wxDC_DrawBitmap, 635). +-define(wxDC_DrawCheckMark, 636). +-define(wxDC_DrawCircle, 637). +-define(wxDC_DrawEllipse_2, 639). +-define(wxDC_DrawEllipse_1, 640). +-define(wxDC_DrawEllipticArc, 641). +-define(wxDC_DrawIcon, 642). +-define(wxDC_DrawLabel, 643). +-define(wxDC_DrawLine, 644). +-define(wxDC_DrawLines, 645). +-define(wxDC_DrawPolygon, 647). +-define(wxDC_DrawPoint, 649). +-define(wxDC_DrawRectangle_2, 651). +-define(wxDC_DrawRectangle_1, 652). +-define(wxDC_DrawRotatedText, 653). +-define(wxDC_DrawRoundedRectangle_3, 655). +-define(wxDC_DrawRoundedRectangle_2, 656). +-define(wxDC_DrawText, 657). +-define(wxDC_EndDoc, 658). +-define(wxDC_EndPage, 659). +-define(wxDC_FloodFill, 660). +-define(wxDC_GetBackground, 661). +-define(wxDC_GetBackgroundMode, 662). +-define(wxDC_GetBrush, 663). +-define(wxDC_GetCharHeight, 664). +-define(wxDC_GetCharWidth, 665). +-define(wxDC_GetClippingBox, 666). +-define(wxDC_GetFont, 668). +-define(wxDC_GetLayoutDirection, 669). +-define(wxDC_GetLogicalFunction, 670). +-define(wxDC_GetMapMode, 671). +-define(wxDC_GetMultiLineTextExtent_4, 672). +-define(wxDC_GetMultiLineTextExtent_1, 673). +-define(wxDC_GetPartialTextExtents, 674). +-define(wxDC_GetPen, 675). +-define(wxDC_GetPixel, 676). +-define(wxDC_GetPPI, 677). +-define(wxDC_GetSize, 679). +-define(wxDC_GetSizeMM, 681). +-define(wxDC_GetTextBackground, 682). +-define(wxDC_GetTextExtent_4, 683). +-define(wxDC_GetTextExtent_1, 684). +-define(wxDC_GetTextForeground, 686). +-define(wxDC_GetUserScale, 687). +-define(wxDC_GradientFillConcentric_3, 688). +-define(wxDC_GradientFillConcentric_4, 689). +-define(wxDC_GradientFillLinear, 690). +-define(wxDC_LogicalToDeviceX, 691). +-define(wxDC_LogicalToDeviceXRel, 692). +-define(wxDC_LogicalToDeviceY, 693). +-define(wxDC_LogicalToDeviceYRel, 694). +-define(wxDC_MaxX, 695). +-define(wxDC_MaxY, 696). +-define(wxDC_MinX, 697). +-define(wxDC_MinY, 698). +-define(wxDC_IsOk, 699). +-define(wxDC_ResetBoundingBox, 700). +-define(wxDC_SetAxisOrientation, 701). +-define(wxDC_SetBackground, 702). +-define(wxDC_SetBackgroundMode, 703). +-define(wxDC_SetBrush, 704). +-define(wxDC_SetClippingRegion_2, 706). +-define(wxDC_SetClippingRegion_1_1, 707). +-define(wxDC_SetClippingRegion_1_0, 708). +-define(wxDC_SetDeviceOrigin, 709). +-define(wxDC_SetFont, 710). +-define(wxDC_SetLayoutDirection, 711). +-define(wxDC_SetLogicalFunction, 712). +-define(wxDC_SetMapMode, 713). +-define(wxDC_SetPalette, 714). +-define(wxDC_SetPen, 715). +-define(wxDC_SetTextBackground, 716). +-define(wxDC_SetTextForeground, 717). +-define(wxDC_SetUserScale, 718). +-define(wxDC_StartDoc, 719). +-define(wxDC_StartPage, 720). +-define(wxMirrorDC_new, 721). +-define(wxMirrorDC_destroy, 722). +-define(wxScreenDC_new, 723). +-define(wxScreenDC_destruct, 724). +-define(wxPostScriptDC_new_0, 725). +-define(wxPostScriptDC_new_1, 726). +-define(wxPostScriptDC_destruct, 727). +-define(wxPostScriptDC_SetResolution, 728). +-define(wxPostScriptDC_GetResolution, 729). +-define(wxWindowDC_new_0, 730). +-define(wxWindowDC_new_1, 731). +-define(wxWindowDC_destruct, 732). +-define(wxClientDC_new_0, 733). +-define(wxClientDC_new_1, 734). +-define(wxClientDC_destroy, 735). +-define(wxPaintDC_new_0, 736). +-define(wxPaintDC_new_1, 737). +-define(wxPaintDC_destroy, 738). +-define(wxMemoryDC_new_1_0, 740). +-define(wxMemoryDC_new_1_1, 741). +-define(wxMemoryDC_new_0, 742). +-define(wxMemoryDC_destruct, 744). +-define(wxMemoryDC_SelectObject, 745). +-define(wxMemoryDC_SelectObjectAsSource, 746). +-define(wxBufferedDC_new_0, 747). +-define(wxBufferedDC_new_2, 748). +-define(wxBufferedDC_new_3, 749). +-define(wxBufferedDC_destruct, 750). +-define(wxBufferedDC_Init_2, 751). +-define(wxBufferedDC_Init_3, 752). +-define(wxBufferedPaintDC_new_3, 753). +-define(wxBufferedPaintDC_new_2, 754). +-define(wxBufferedPaintDC_destruct, 755). +-define(wxGraphicsObject_destruct, 756). +-define(wxGraphicsObject_GetRenderer, 757). +-define(wxGraphicsObject_IsNull, 758). +-define(wxGraphicsContext_destruct, 759). +-define(wxGraphicsContext_Create_1_1, 760). +-define(wxGraphicsContext_Create_1_0, 761). +-define(wxGraphicsContext_Create_0, 762). +-define(wxGraphicsContext_CreatePen, 763). +-define(wxGraphicsContext_CreateBrush, 764). +-define(wxGraphicsContext_CreateRadialGradientBrush, 765). +-define(wxGraphicsContext_CreateLinearGradientBrush, 766). +-define(wxGraphicsContext_CreateFont, 767). +-define(wxGraphicsContext_CreateMatrix, 768). +-define(wxGraphicsContext_CreatePath, 769). +-define(wxGraphicsContext_Clip_1, 770). +-define(wxGraphicsContext_Clip_4, 771). +-define(wxGraphicsContext_ResetClip, 772). +-define(wxGraphicsContext_DrawBitmap, 773). +-define(wxGraphicsContext_DrawEllipse, 774). +-define(wxGraphicsContext_DrawIcon, 775). +-define(wxGraphicsContext_DrawLines, 776). +-define(wxGraphicsContext_DrawPath, 777). +-define(wxGraphicsContext_DrawRectangle, 778). +-define(wxGraphicsContext_DrawRoundedRectangle, 779). +-define(wxGraphicsContext_DrawText_3, 780). +-define(wxGraphicsContext_DrawText_4_0, 781). +-define(wxGraphicsContext_DrawText_4_1, 782). +-define(wxGraphicsContext_DrawText_5, 783). +-define(wxGraphicsContext_FillPath, 784). +-define(wxGraphicsContext_StrokePath, 785). +-define(wxGraphicsContext_GetPartialTextExtents, 786). +-define(wxGraphicsContext_GetTextExtent, 787). +-define(wxGraphicsContext_Rotate, 788). +-define(wxGraphicsContext_Scale, 789). +-define(wxGraphicsContext_Translate, 790). +-define(wxGraphicsContext_GetTransform, 791). +-define(wxGraphicsContext_SetTransform, 792). +-define(wxGraphicsContext_ConcatTransform, 793). +-define(wxGraphicsContext_SetBrush_1_1, 794). +-define(wxGraphicsContext_SetBrush_1_0, 795). +-define(wxGraphicsContext_SetFont_1, 796). +-define(wxGraphicsContext_SetFont_2, 797). +-define(wxGraphicsContext_SetPen_1_0, 798). +-define(wxGraphicsContext_SetPen_1_1, 799). +-define(wxGraphicsContext_StrokeLine, 800). +-define(wxGraphicsContext_StrokeLines, 801). +-define(wxGraphicsMatrix_Concat, 803). +-define(wxGraphicsMatrix_Get, 805). +-define(wxGraphicsMatrix_Invert, 806). +-define(wxGraphicsMatrix_IsEqual, 807). +-define(wxGraphicsMatrix_IsIdentity, 809). +-define(wxGraphicsMatrix_Rotate, 810). +-define(wxGraphicsMatrix_Scale, 811). +-define(wxGraphicsMatrix_Translate, 812). +-define(wxGraphicsMatrix_Set, 813). +-define(wxGraphicsMatrix_TransformPoint, 814). +-define(wxGraphicsMatrix_TransformDistance, 815). +-define(wxGraphicsPath_MoveToPoint_2, 816). +-define(wxGraphicsPath_MoveToPoint_1, 817). +-define(wxGraphicsPath_AddArc_6, 818). +-define(wxGraphicsPath_AddArc_5, 819). +-define(wxGraphicsPath_AddArcToPoint, 820). +-define(wxGraphicsPath_AddCircle, 821). +-define(wxGraphicsPath_AddCurveToPoint_6, 822). +-define(wxGraphicsPath_AddCurveToPoint_3, 823). +-define(wxGraphicsPath_AddEllipse, 824). +-define(wxGraphicsPath_AddLineToPoint_2, 825). +-define(wxGraphicsPath_AddLineToPoint_1, 826). +-define(wxGraphicsPath_AddPath, 827). +-define(wxGraphicsPath_AddQuadCurveToPoint, 828). +-define(wxGraphicsPath_AddRectangle, 829). +-define(wxGraphicsPath_AddRoundedRectangle, 830). +-define(wxGraphicsPath_CloseSubpath, 831). +-define(wxGraphicsPath_Contains_3, 832). +-define(wxGraphicsPath_Contains_2, 833). +-define(wxGraphicsPath_GetBox, 835). +-define(wxGraphicsPath_GetCurrentPoint, 837). +-define(wxGraphicsPath_Transform, 838). +-define(wxGraphicsRenderer_GetDefaultRenderer, 839). +-define(wxGraphicsRenderer_CreateContext_1_1, 840). +-define(wxGraphicsRenderer_CreateContext_1_0, 841). +-define(wxGraphicsRenderer_CreatePen, 842). +-define(wxGraphicsRenderer_CreateBrush, 843). +-define(wxGraphicsRenderer_CreateLinearGradientBrush, 844). +-define(wxGraphicsRenderer_CreateRadialGradientBrush, 845). +-define(wxGraphicsRenderer_CreateFont, 846). +-define(wxGraphicsRenderer_CreateMatrix, 847). +-define(wxGraphicsRenderer_CreatePath, 848). +-define(wxMenuBar_new_1, 850). +-define(wxMenuBar_new_0, 852). +-define(wxMenuBar_destruct, 854). +-define(wxMenuBar_Append, 855). +-define(wxMenuBar_Check, 856). +-define(wxMenuBar_Enable_2, 857). +-define(wxMenuBar_Enable_1, 858). +-define(wxMenuBar_EnableTop, 859). +-define(wxMenuBar_FindMenu, 860). +-define(wxMenuBar_FindMenuItem, 861). +-define(wxMenuBar_FindItem, 862). +-define(wxMenuBar_GetHelpString, 863). +-define(wxMenuBar_GetLabel_1, 864). +-define(wxMenuBar_GetLabel_0, 865). +-define(wxMenuBar_GetLabelTop, 866). +-define(wxMenuBar_GetMenu, 867). +-define(wxMenuBar_GetMenuCount, 868). +-define(wxMenuBar_Insert, 869). +-define(wxMenuBar_IsChecked, 870). +-define(wxMenuBar_IsEnabled_1, 871). +-define(wxMenuBar_IsEnabled_0, 872). +-define(wxMenuBar_Remove, 873). +-define(wxMenuBar_Replace, 874). +-define(wxMenuBar_SetHelpString, 875). +-define(wxMenuBar_SetLabel_2, 876). +-define(wxMenuBar_SetLabel_1, 877). +-define(wxMenuBar_SetLabelTop, 878). +-define(wxControl_GetLabel, 879). +-define(wxControl_SetLabel, 880). +-define(wxControlWithItems_Append_1, 881). +-define(wxControlWithItems_Append_2, 882). +-define(wxControlWithItems_appendStrings_1, 883). +-define(wxControlWithItems_Clear, 884). +-define(wxControlWithItems_Delete, 885). +-define(wxControlWithItems_FindString, 886). +-define(wxControlWithItems_getClientData, 887). +-define(wxControlWithItems_setClientData, 888). +-define(wxControlWithItems_GetCount, 889). +-define(wxControlWithItems_GetSelection, 890). +-define(wxControlWithItems_GetString, 891). +-define(wxControlWithItems_GetStringSelection, 892). +-define(wxControlWithItems_Insert_2, 893). +-define(wxControlWithItems_Insert_3, 894). +-define(wxControlWithItems_IsEmpty, 895). +-define(wxControlWithItems_Select, 896). +-define(wxControlWithItems_SetSelection, 897). +-define(wxControlWithItems_SetString, 898). +-define(wxControlWithItems_SetStringSelection, 899). +-define(wxMenu_new_2, 902). +-define(wxMenu_new_1, 903). +-define(wxMenu_destruct, 905). +-define(wxMenu_Append_3, 906). +-define(wxMenu_Append_1, 907). +-define(wxMenu_Append_4_0, 908). +-define(wxMenu_Append_4_1, 909). +-define(wxMenu_AppendCheckItem, 910). +-define(wxMenu_AppendRadioItem, 911). +-define(wxMenu_AppendSeparator, 912). +-define(wxMenu_Break, 913). +-define(wxMenu_Check, 914). +-define(wxMenu_Delete_1_0, 915). +-define(wxMenu_Delete_1_1, 916). +-define(wxMenu_Destroy_1_0, 917). +-define(wxMenu_Destroy_1_1, 918). +-define(wxMenu_Enable, 919). +-define(wxMenu_FindItem_1, 920). +-define(wxMenu_FindItem_2, 921). +-define(wxMenu_FindItemByPosition, 922). +-define(wxMenu_GetHelpString, 923). +-define(wxMenu_GetLabel, 924). +-define(wxMenu_GetMenuItemCount, 925). +-define(wxMenu_GetMenuItems, 926). +-define(wxMenu_GetTitle, 928). +-define(wxMenu_Insert_2, 929). +-define(wxMenu_Insert_3, 930). +-define(wxMenu_Insert_5_1, 931). +-define(wxMenu_Insert_5_0, 932). +-define(wxMenu_InsertCheckItem, 933). +-define(wxMenu_InsertRadioItem, 934). +-define(wxMenu_InsertSeparator, 935). +-define(wxMenu_IsChecked, 936). +-define(wxMenu_IsEnabled, 937). +-define(wxMenu_Prepend_1, 938). +-define(wxMenu_Prepend_2, 939). +-define(wxMenu_Prepend_4_1, 940). +-define(wxMenu_Prepend_4_0, 941). +-define(wxMenu_PrependCheckItem, 942). +-define(wxMenu_PrependRadioItem, 943). +-define(wxMenu_PrependSeparator, 944). +-define(wxMenu_Remove_1_0, 945). +-define(wxMenu_Remove_1_1, 946). +-define(wxMenu_SetHelpString, 947). +-define(wxMenu_SetLabel, 948). +-define(wxMenu_SetTitle, 949). +-define(wxMenuItem_new, 950). +-define(wxMenuItem_destruct, 952). +-define(wxMenuItem_Check, 953). +-define(wxMenuItem_Enable, 954). +-define(wxMenuItem_GetBitmap, 955). +-define(wxMenuItem_GetHelp, 956). +-define(wxMenuItem_GetId, 957). +-define(wxMenuItem_GetKind, 958). +-define(wxMenuItem_GetLabel, 959). +-define(wxMenuItem_GetLabelFromText, 960). +-define(wxMenuItem_GetMenu, 961). +-define(wxMenuItem_GetText, 962). +-define(wxMenuItem_GetSubMenu, 963). +-define(wxMenuItem_IsCheckable, 964). +-define(wxMenuItem_IsChecked, 965). +-define(wxMenuItem_IsEnabled, 966). +-define(wxMenuItem_IsSeparator, 967). +-define(wxMenuItem_IsSubMenu, 968). +-define(wxMenuItem_SetBitmap, 969). +-define(wxMenuItem_SetHelp, 970). +-define(wxMenuItem_SetMenu, 971). +-define(wxMenuItem_SetSubMenu, 972). +-define(wxMenuItem_SetText, 973). +-define(wxToolBar_AddControl, 974). +-define(wxToolBar_AddSeparator, 975). +-define(wxToolBar_AddTool_5, 976). +-define(wxToolBar_AddTool_4_0, 977). +-define(wxToolBar_AddTool_1, 978). +-define(wxToolBar_AddTool_4_1, 979). +-define(wxToolBar_AddTool_3, 980). +-define(wxToolBar_AddTool_6, 981). +-define(wxToolBar_AddCheckTool, 982). +-define(wxToolBar_AddRadioTool, 983). +-define(wxToolBar_DeleteTool, 984). +-define(wxToolBar_DeleteToolByPos, 985). +-define(wxToolBar_EnableTool, 986). +-define(wxToolBar_FindById, 987). +-define(wxToolBar_FindControl, 988). +-define(wxToolBar_FindToolForPosition, 989). +-define(wxToolBar_GetToolSize, 990). +-define(wxToolBar_GetToolBitmapSize, 991). +-define(wxToolBar_GetMargins, 992). +-define(wxToolBar_GetToolEnabled, 993). +-define(wxToolBar_GetToolLongHelp, 994). +-define(wxToolBar_GetToolPacking, 995). +-define(wxToolBar_GetToolPos, 996). +-define(wxToolBar_GetToolSeparation, 997). +-define(wxToolBar_GetToolShortHelp, 998). +-define(wxToolBar_GetToolState, 999). +-define(wxToolBar_InsertControl, 1000). +-define(wxToolBar_InsertSeparator, 1001). +-define(wxToolBar_InsertTool_5, 1002). +-define(wxToolBar_InsertTool_2, 1003). +-define(wxToolBar_InsertTool_4, 1004). +-define(wxToolBar_Realize, 1005). +-define(wxToolBar_RemoveTool, 1006). +-define(wxToolBar_SetMargins, 1007). +-define(wxToolBar_SetToolBitmapSize, 1008). +-define(wxToolBar_SetToolLongHelp, 1009). +-define(wxToolBar_SetToolPacking, 1010). +-define(wxToolBar_SetToolShortHelp, 1011). +-define(wxToolBar_SetToolSeparation, 1012). +-define(wxToolBar_ToggleTool, 1013). +-define(wxStatusBar_new_0, 1015). +-define(wxStatusBar_new_2, 1016). +-define(wxStatusBar_destruct, 1018). +-define(wxStatusBar_Create, 1019). +-define(wxStatusBar_GetFieldRect, 1020). +-define(wxStatusBar_GetFieldsCount, 1021). +-define(wxStatusBar_GetStatusText, 1022). +-define(wxStatusBar_PopStatusText, 1023). +-define(wxStatusBar_PushStatusText, 1024). +-define(wxStatusBar_SetFieldsCount, 1025). +-define(wxStatusBar_SetMinHeight, 1026). +-define(wxStatusBar_SetStatusText, 1027). +-define(wxStatusBar_SetStatusWidths, 1028). +-define(wxStatusBar_SetStatusStyles, 1029). +-define(wxBitmap_new_0, 1030). +-define(wxBitmap_new_3, 1031). +-define(wxBitmap_new_4, 1032). +-define(wxBitmap_new_2_0, 1033). +-define(wxBitmap_new_2_1, 1034). +-define(wxBitmap_destruct, 1035). +-define(wxBitmap_ConvertToImage, 1036). +-define(wxBitmap_CopyFromIcon, 1037). +-define(wxBitmap_Create, 1038). +-define(wxBitmap_GetDepth, 1039). +-define(wxBitmap_GetHeight, 1040). +-define(wxBitmap_GetPalette, 1041). +-define(wxBitmap_GetMask, 1042). +-define(wxBitmap_GetWidth, 1043). +-define(wxBitmap_GetSubBitmap, 1044). +-define(wxBitmap_LoadFile, 1045). +-define(wxBitmap_Ok, 1046). +-define(wxBitmap_SaveFile, 1047). +-define(wxBitmap_SetDepth, 1048). +-define(wxBitmap_SetHeight, 1049). +-define(wxBitmap_SetMask, 1050). +-define(wxBitmap_SetPalette, 1051). +-define(wxBitmap_SetWidth, 1052). +-define(wxIcon_new_0, 1053). +-define(wxIcon_new_2, 1054). +-define(wxIcon_new_1, 1055). +-define(wxIcon_CopyFromBitmap, 1056). +-define(wxIcon_destroy, 1057). +-define(wxIconBundle_new_0, 1058). +-define(wxIconBundle_new_2, 1059). +-define(wxIconBundle_new_1_0, 1060). +-define(wxIconBundle_new_1_1, 1061). +-define(wxIconBundle_destruct, 1062). +-define(wxIconBundle_AddIcon_2, 1063). +-define(wxIconBundle_AddIcon_1, 1064). +-define(wxIconBundle_GetIcon_1_1, 1065). +-define(wxIconBundle_GetIcon_1_0, 1066). +-define(wxCursor_new_0, 1067). +-define(wxCursor_new_1_0, 1068). +-define(wxCursor_new_1_1, 1069). +-define(wxCursor_new_4, 1070). +-define(wxCursor_destruct, 1071). +-define(wxCursor_Ok, 1072). +-define(wxMask_new_0, 1073). +-define(wxMask_new_2_1, 1074). +-define(wxMask_new_2_0, 1075). +-define(wxMask_new_1, 1076). +-define(wxMask_destruct, 1077). +-define(wxMask_Create_2_1, 1078). +-define(wxMask_Create_2_0, 1079). +-define(wxMask_Create_1, 1080). +-define(wxImage_new_0, 1081). +-define(wxImage_new_3_0, 1082). +-define(wxImage_new_4, 1083). +-define(wxImage_new_5, 1084). +-define(wxImage_new_2, 1085). +-define(wxImage_new_3_1, 1086). +-define(wxImage_Blur, 1087). +-define(wxImage_BlurHorizontal, 1088). +-define(wxImage_BlurVertical, 1089). +-define(wxImage_ConvertAlphaToMask, 1090). +-define(wxImage_ConvertToGreyscale, 1091). +-define(wxImage_ConvertToMono, 1092). +-define(wxImage_Copy, 1093). +-define(wxImage_Create_3, 1094). +-define(wxImage_Create_4, 1095). +-define(wxImage_Create_5, 1096). +-define(wxImage_Destroy, 1097). +-define(wxImage_FindFirstUnusedColour, 1098). +-define(wxImage_GetImageExtWildcard, 1099). +-define(wxImage_GetAlpha_2, 1100). +-define(wxImage_GetAlpha_0, 1101). +-define(wxImage_GetBlue, 1102). +-define(wxImage_GetData, 1103). +-define(wxImage_GetGreen, 1104). +-define(wxImage_GetImageCount, 1105). +-define(wxImage_GetHeight, 1106). +-define(wxImage_GetMaskBlue, 1107). +-define(wxImage_GetMaskGreen, 1108). +-define(wxImage_GetMaskRed, 1109). +-define(wxImage_GetOrFindMaskColour, 1110). +-define(wxImage_GetPalette, 1111). +-define(wxImage_GetRed, 1112). +-define(wxImage_GetSubImage, 1113). +-define(wxImage_GetWidth, 1114). +-define(wxImage_HasAlpha, 1115). +-define(wxImage_HasMask, 1116). +-define(wxImage_GetOption, 1117). +-define(wxImage_GetOptionInt, 1118). +-define(wxImage_HasOption, 1119). +-define(wxImage_InitAlpha, 1120). +-define(wxImage_InitStandardHandlers, 1121). +-define(wxImage_IsTransparent, 1122). +-define(wxImage_LoadFile_2, 1123). +-define(wxImage_LoadFile_3, 1124). +-define(wxImage_Ok, 1125). +-define(wxImage_RemoveHandler, 1126). +-define(wxImage_Mirror, 1127). +-define(wxImage_Replace, 1128). +-define(wxImage_Rescale, 1129). +-define(wxImage_Resize, 1130). +-define(wxImage_Rotate, 1131). +-define(wxImage_RotateHue, 1132). +-define(wxImage_Rotate90, 1133). +-define(wxImage_SaveFile_1, 1134). +-define(wxImage_SaveFile_2_0, 1135). +-define(wxImage_SaveFile_2_1, 1136). +-define(wxImage_Scale, 1137). +-define(wxImage_Size, 1138). +-define(wxImage_SetAlpha_3, 1139). +-define(wxImage_SetAlpha_2, 1140). +-define(wxImage_SetData_2, 1141). +-define(wxImage_SetData_4, 1142). +-define(wxImage_SetMask, 1143). +-define(wxImage_SetMaskColour, 1144). +-define(wxImage_SetMaskFromImage, 1145). +-define(wxImage_SetOption_2_1, 1146). +-define(wxImage_SetOption_2_0, 1147). +-define(wxImage_SetPalette, 1148). +-define(wxImage_SetRGB_5, 1149). +-define(wxImage_SetRGB_4, 1150). +-define(wxImage_destroy, 1151). +-define(wxBrush_new_0, 1152). +-define(wxBrush_new_2, 1153). +-define(wxBrush_new_1, 1154). +-define(wxBrush_destruct, 1156). +-define(wxBrush_GetColour, 1157). +-define(wxBrush_GetStipple, 1158). +-define(wxBrush_GetStyle, 1159). +-define(wxBrush_IsHatch, 1160). +-define(wxBrush_IsOk, 1161). +-define(wxBrush_SetColour_1, 1162). +-define(wxBrush_SetColour_3, 1163). +-define(wxBrush_SetStipple, 1164). +-define(wxBrush_SetStyle, 1165). +-define(wxPen_new_0, 1166). +-define(wxPen_new_2, 1167). +-define(wxPen_destruct, 1168). +-define(wxPen_GetCap, 1169). +-define(wxPen_GetColour, 1170). +-define(wxPen_GetJoin, 1171). +-define(wxPen_GetStyle, 1172). +-define(wxPen_GetWidth, 1173). +-define(wxPen_IsOk, 1174). +-define(wxPen_SetCap, 1175). +-define(wxPen_SetColour_1, 1176). +-define(wxPen_SetColour_3, 1177). +-define(wxPen_SetJoin, 1178). +-define(wxPen_SetStyle, 1179). +-define(wxPen_SetWidth, 1180). +-define(wxRegion_new_0, 1181). +-define(wxRegion_new_4, 1182). +-define(wxRegion_new_2, 1183). +-define(wxRegion_new_1_1, 1184). +-define(wxRegion_new_1_0, 1186). +-define(wxRegion_destruct, 1188). +-define(wxRegion_Clear, 1189). +-define(wxRegion_Contains_2, 1190). +-define(wxRegion_Contains_1_0, 1191). +-define(wxRegion_Contains_4, 1192). +-define(wxRegion_Contains_1_1, 1193). +-define(wxRegion_ConvertToBitmap, 1194). +-define(wxRegion_GetBox, 1195). +-define(wxRegion_Intersect_4, 1196). +-define(wxRegion_Intersect_1_1, 1197). +-define(wxRegion_Intersect_1_0, 1198). +-define(wxRegion_IsEmpty, 1199). +-define(wxRegion_Subtract_4, 1200). +-define(wxRegion_Subtract_1_1, 1201). +-define(wxRegion_Subtract_1_0, 1202). +-define(wxRegion_Offset_2, 1203). +-define(wxRegion_Offset_1, 1204). +-define(wxRegion_Union_4, 1205). +-define(wxRegion_Union_1_2, 1206). +-define(wxRegion_Union_1_1, 1207). +-define(wxRegion_Union_1_0, 1208). +-define(wxRegion_Union_3, 1209). +-define(wxRegion_Xor_4, 1210). +-define(wxRegion_Xor_1_1, 1211). +-define(wxRegion_Xor_1_0, 1212). +-define(wxAcceleratorTable_new_0, 1213). +-define(wxAcceleratorTable_new_2, 1214). +-define(wxAcceleratorTable_destruct, 1215). +-define(wxAcceleratorTable_Ok, 1216). +-define(wxAcceleratorEntry_new_1_0, 1217). +-define(wxAcceleratorEntry_new_1_1, 1218). +-define(wxAcceleratorEntry_GetCommand, 1219). +-define(wxAcceleratorEntry_GetFlags, 1220). +-define(wxAcceleratorEntry_GetKeyCode, 1221). +-define(wxAcceleratorEntry_Set, 1222). +-define(wxAcceleratorEntry_destroy, 1223). +-define(wxCaret_new_3, 1228). +-define(wxCaret_new_2, 1229). +-define(wxCaret_destruct, 1231). +-define(wxCaret_Create_3, 1232). +-define(wxCaret_Create_2, 1233). +-define(wxCaret_GetBlinkTime, 1234). +-define(wxCaret_GetPosition, 1236). +-define(wxCaret_GetSize, 1238). +-define(wxCaret_GetWindow, 1239). +-define(wxCaret_Hide, 1240). +-define(wxCaret_IsOk, 1241). +-define(wxCaret_IsVisible, 1242). +-define(wxCaret_Move_2, 1243). +-define(wxCaret_Move_1, 1244). +-define(wxCaret_SetBlinkTime, 1245). +-define(wxCaret_SetSize_2, 1246). +-define(wxCaret_SetSize_1, 1247). +-define(wxCaret_Show, 1248). +-define(wxSizer_Add_2_1, 1249). +-define(wxSizer_Add_2_0, 1250). +-define(wxSizer_Add_3, 1251). +-define(wxSizer_Add_2_3, 1252). +-define(wxSizer_Add_2_2, 1253). +-define(wxSizer_AddSpacer, 1254). +-define(wxSizer_AddStretchSpacer, 1255). +-define(wxSizer_CalcMin, 1256). +-define(wxSizer_Clear, 1257). +-define(wxSizer_Detach_1_2, 1258). +-define(wxSizer_Detach_1_1, 1259). +-define(wxSizer_Detach_1_0, 1260). +-define(wxSizer_Fit, 1261). +-define(wxSizer_FitInside, 1262). +-define(wxSizer_GetChildren, 1263). +-define(wxSizer_GetItem_2_1, 1264). +-define(wxSizer_GetItem_2_0, 1265). +-define(wxSizer_GetItem_1, 1266). +-define(wxSizer_GetSize, 1267). +-define(wxSizer_GetPosition, 1268). +-define(wxSizer_GetMinSize, 1269). +-define(wxSizer_Hide_2_0, 1270). +-define(wxSizer_Hide_2_1, 1271). +-define(wxSizer_Hide_1, 1272). +-define(wxSizer_Insert_3_1, 1273). +-define(wxSizer_Insert_3_0, 1274). +-define(wxSizer_Insert_4, 1275). +-define(wxSizer_Insert_3_3, 1276). +-define(wxSizer_Insert_3_2, 1277). +-define(wxSizer_Insert_2, 1278). +-define(wxSizer_InsertSpacer, 1279). +-define(wxSizer_InsertStretchSpacer, 1280). +-define(wxSizer_IsShown_1_2, 1281). +-define(wxSizer_IsShown_1_1, 1282). +-define(wxSizer_IsShown_1_0, 1283). +-define(wxSizer_Layout, 1284). +-define(wxSizer_Prepend_2_1, 1285). +-define(wxSizer_Prepend_2_0, 1286). +-define(wxSizer_Prepend_3, 1287). +-define(wxSizer_Prepend_2_3, 1288). +-define(wxSizer_Prepend_2_2, 1289). +-define(wxSizer_Prepend_1, 1290). +-define(wxSizer_PrependSpacer, 1291). +-define(wxSizer_PrependStretchSpacer, 1292). +-define(wxSizer_RecalcSizes, 1293). +-define(wxSizer_Remove_1_1, 1294). +-define(wxSizer_Remove_1_0, 1295). +-define(wxSizer_Replace_3_1, 1296). +-define(wxSizer_Replace_3_0, 1297). +-define(wxSizer_Replace_2, 1298). +-define(wxSizer_SetDimension, 1299). +-define(wxSizer_SetMinSize_2, 1300). +-define(wxSizer_SetMinSize_1, 1301). +-define(wxSizer_SetItemMinSize_3_2, 1302). +-define(wxSizer_SetItemMinSize_2_2, 1303). +-define(wxSizer_SetItemMinSize_3_1, 1304). +-define(wxSizer_SetItemMinSize_2_1, 1305). +-define(wxSizer_SetItemMinSize_3_0, 1306). +-define(wxSizer_SetItemMinSize_2_0, 1307). +-define(wxSizer_SetSizeHints, 1308). +-define(wxSizer_SetVirtualSizeHints, 1309). +-define(wxSizer_Show_2_2, 1310). +-define(wxSizer_Show_2_1, 1311). +-define(wxSizer_Show_2_0, 1312). +-define(wxSizer_Show_1, 1313). +-define(wxSizerFlags_new, 1314). +-define(wxSizerFlags_Align, 1315). +-define(wxSizerFlags_Border_2, 1316). +-define(wxSizerFlags_Border_1, 1317). +-define(wxSizerFlags_Center, 1318). +-define(wxSizerFlags_Centre, 1319). +-define(wxSizerFlags_Expand, 1320). +-define(wxSizerFlags_Left, 1321). +-define(wxSizerFlags_Proportion, 1322). +-define(wxSizerFlags_Right, 1323). +-define(wxSizerFlags_destroy, 1324). +-define(wxSizerItem_new_5_1, 1325). +-define(wxSizerItem_new_2_1, 1326). +-define(wxSizerItem_new_5_0, 1327). +-define(wxSizerItem_new_2_0, 1328). +-define(wxSizerItem_new_6, 1329). +-define(wxSizerItem_new_3, 1330). +-define(wxSizerItem_new_0, 1331). +-define(wxSizerItem_destruct, 1332). +-define(wxSizerItem_CalcMin, 1333). +-define(wxSizerItem_DeleteWindows, 1334). +-define(wxSizerItem_DetachSizer, 1335). +-define(wxSizerItem_GetBorder, 1336). +-define(wxSizerItem_GetFlag, 1337). +-define(wxSizerItem_GetMinSize, 1338). +-define(wxSizerItem_GetPosition, 1339). +-define(wxSizerItem_GetProportion, 1340). +-define(wxSizerItem_GetRatio, 1341). +-define(wxSizerItem_GetRect, 1342). +-define(wxSizerItem_GetSize, 1343). +-define(wxSizerItem_GetSizer, 1344). +-define(wxSizerItem_GetSpacer, 1345). +-define(wxSizerItem_GetUserData, 1346). +-define(wxSizerItem_GetWindow, 1347). +-define(wxSizerItem_IsSizer, 1348). +-define(wxSizerItem_IsShown, 1349). +-define(wxSizerItem_IsSpacer, 1350). +-define(wxSizerItem_IsWindow, 1351). +-define(wxSizerItem_SetBorder, 1352). +-define(wxSizerItem_SetDimension, 1353). +-define(wxSizerItem_SetFlag, 1354). +-define(wxSizerItem_SetInitSize, 1355). +-define(wxSizerItem_SetMinSize_1, 1356). +-define(wxSizerItem_SetMinSize_2, 1357). +-define(wxSizerItem_SetProportion, 1358). +-define(wxSizerItem_SetRatio_2, 1359). +-define(wxSizerItem_SetRatio_1_1, 1360). +-define(wxSizerItem_SetRatio_1_0, 1361). +-define(wxSizerItem_SetSizer, 1362). +-define(wxSizerItem_SetSpacer_1, 1363). +-define(wxSizerItem_SetSpacer_2, 1364). +-define(wxSizerItem_SetWindow, 1365). +-define(wxSizerItem_Show, 1366). +-define(wxBoxSizer_new, 1367). +-define(wxBoxSizer_GetOrientation, 1368). +-define(wxBoxSizer_destroy, 1369). +-define(wxStaticBoxSizer_new_2, 1370). +-define(wxStaticBoxSizer_new_3, 1371). +-define(wxStaticBoxSizer_GetStaticBox, 1372). +-define(wxStaticBoxSizer_destroy, 1373). +-define(wxGridSizer_new_4, 1374). +-define(wxGridSizer_new_2, 1375). +-define(wxGridSizer_GetCols, 1376). +-define(wxGridSizer_GetHGap, 1377). +-define(wxGridSizer_GetRows, 1378). +-define(wxGridSizer_GetVGap, 1379). +-define(wxGridSizer_SetCols, 1380). +-define(wxGridSizer_SetHGap, 1381). +-define(wxGridSizer_SetRows, 1382). +-define(wxGridSizer_SetVGap, 1383). +-define(wxGridSizer_destroy, 1384). +-define(wxFlexGridSizer_new_4, 1385). +-define(wxFlexGridSizer_new_2, 1386). +-define(wxFlexGridSizer_AddGrowableCol, 1387). +-define(wxFlexGridSizer_AddGrowableRow, 1388). +-define(wxFlexGridSizer_GetFlexibleDirection, 1389). +-define(wxFlexGridSizer_GetNonFlexibleGrowMode, 1390). +-define(wxFlexGridSizer_RemoveGrowableCol, 1391). +-define(wxFlexGridSizer_RemoveGrowableRow, 1392). +-define(wxFlexGridSizer_SetFlexibleDirection, 1393). +-define(wxFlexGridSizer_SetNonFlexibleGrowMode, 1394). +-define(wxFlexGridSizer_destroy, 1395). +-define(wxGridBagSizer_new, 1396). +-define(wxGridBagSizer_Add_3_2, 1397). +-define(wxGridBagSizer_Add_3_1, 1398). +-define(wxGridBagSizer_Add_4, 1399). +-define(wxGridBagSizer_Add_1_0, 1400). +-define(wxGridBagSizer_Add_2_1, 1401). +-define(wxGridBagSizer_Add_2_0, 1402). +-define(wxGridBagSizer_Add_3_0, 1403). +-define(wxGridBagSizer_Add_1_1, 1404). +-define(wxGridBagSizer_CalcMin, 1405). +-define(wxGridBagSizer_CheckForIntersection_2, 1406). +-define(wxGridBagSizer_CheckForIntersection_3, 1407). +-define(wxGridBagSizer_FindItem_1_1, 1408). +-define(wxGridBagSizer_FindItem_1_0, 1409). +-define(wxGridBagSizer_FindItemAtPoint, 1410). +-define(wxGridBagSizer_FindItemAtPosition, 1411). +-define(wxGridBagSizer_FindItemWithData, 1412). +-define(wxGridBagSizer_GetCellSize, 1413). +-define(wxGridBagSizer_GetEmptyCellSize, 1414). +-define(wxGridBagSizer_GetItemPosition_1_2, 1415). +-define(wxGridBagSizer_GetItemPosition_1_1, 1416). +-define(wxGridBagSizer_GetItemPosition_1_0, 1417). +-define(wxGridBagSizer_GetItemSpan_1_2, 1418). +-define(wxGridBagSizer_GetItemSpan_1_1, 1419). +-define(wxGridBagSizer_GetItemSpan_1_0, 1420). +-define(wxGridBagSizer_SetEmptyCellSize, 1421). +-define(wxGridBagSizer_SetItemPosition_2_2, 1422). +-define(wxGridBagSizer_SetItemPosition_2_1, 1423). +-define(wxGridBagSizer_SetItemPosition_2_0, 1424). +-define(wxGridBagSizer_SetItemSpan_2_2, 1425). +-define(wxGridBagSizer_SetItemSpan_2_1, 1426). +-define(wxGridBagSizer_SetItemSpan_2_0, 1427). +-define(wxGridBagSizer_destroy, 1428). +-define(wxStdDialogButtonSizer_new, 1429). +-define(wxStdDialogButtonSizer_AddButton, 1430). +-define(wxStdDialogButtonSizer_Realize, 1431). +-define(wxStdDialogButtonSizer_SetAffirmativeButton, 1432). +-define(wxStdDialogButtonSizer_SetCancelButton, 1433). +-define(wxStdDialogButtonSizer_SetNegativeButton, 1434). +-define(wxStdDialogButtonSizer_destroy, 1435). +-define(wxFont_new_0, 1436). +-define(wxFont_new_1, 1437). +-define(wxFont_new_5, 1438). +-define(wxFont_destruct, 1440). +-define(wxFont_IsFixedWidth, 1441). +-define(wxFont_GetDefaultEncoding, 1442). +-define(wxFont_GetFaceName, 1443). +-define(wxFont_GetFamily, 1444). +-define(wxFont_GetNativeFontInfoDesc, 1445). +-define(wxFont_GetNativeFontInfoUserDesc, 1446). +-define(wxFont_GetPointSize, 1447). +-define(wxFont_GetStyle, 1448). +-define(wxFont_GetUnderlined, 1449). +-define(wxFont_GetWeight, 1450). +-define(wxFont_Ok, 1451). +-define(wxFont_SetDefaultEncoding, 1452). +-define(wxFont_SetFaceName, 1453). +-define(wxFont_SetFamily, 1454). +-define(wxFont_SetPointSize, 1455). +-define(wxFont_SetStyle, 1456). +-define(wxFont_SetUnderlined, 1457). +-define(wxFont_SetWeight, 1458). +-define(wxToolTip_Enable, 1459). +-define(wxToolTip_SetDelay, 1460). +-define(wxToolTip_new, 1461). +-define(wxToolTip_SetTip, 1462). +-define(wxToolTip_GetTip, 1463). +-define(wxToolTip_GetWindow, 1464). +-define(wxToolTip_destroy, 1465). +-define(wxButton_new_3, 1467). +-define(wxButton_new_0, 1468). +-define(wxButton_destruct, 1469). +-define(wxButton_Create, 1470). +-define(wxButton_GetDefaultSize, 1471). +-define(wxButton_SetDefault, 1472). +-define(wxButton_SetLabel, 1473). +-define(wxBitmapButton_new_4, 1475). +-define(wxBitmapButton_new_0, 1476). +-define(wxBitmapButton_Create, 1477). +-define(wxBitmapButton_GetBitmapDisabled, 1478). +-define(wxBitmapButton_GetBitmapFocus, 1480). +-define(wxBitmapButton_GetBitmapLabel, 1482). +-define(wxBitmapButton_GetBitmapSelected, 1484). +-define(wxBitmapButton_SetBitmapDisabled, 1486). +-define(wxBitmapButton_SetBitmapFocus, 1487). +-define(wxBitmapButton_SetBitmapLabel, 1488). +-define(wxBitmapButton_SetBitmapSelected, 1489). +-define(wxBitmapButton_destroy, 1490). +-define(wxToggleButton_new_0, 1491). +-define(wxToggleButton_new_4, 1492). +-define(wxToggleButton_Create, 1493). +-define(wxToggleButton_GetValue, 1494). +-define(wxToggleButton_SetValue, 1495). +-define(wxToggleButton_destroy, 1496). +-define(wxCalendarCtrl_new_0, 1497). +-define(wxCalendarCtrl_new_3, 1498). +-define(wxCalendarCtrl_Create, 1499). +-define(wxCalendarCtrl_destruct, 1500). +-define(wxCalendarCtrl_SetDate, 1501). +-define(wxCalendarCtrl_GetDate, 1502). +-define(wxCalendarCtrl_EnableYearChange, 1503). +-define(wxCalendarCtrl_EnableMonthChange, 1504). +-define(wxCalendarCtrl_EnableHolidayDisplay, 1505). +-define(wxCalendarCtrl_SetHeaderColours, 1506). +-define(wxCalendarCtrl_GetHeaderColourFg, 1507). +-define(wxCalendarCtrl_GetHeaderColourBg, 1508). +-define(wxCalendarCtrl_SetHighlightColours, 1509). +-define(wxCalendarCtrl_GetHighlightColourFg, 1510). +-define(wxCalendarCtrl_GetHighlightColourBg, 1511). +-define(wxCalendarCtrl_SetHolidayColours, 1512). +-define(wxCalendarCtrl_GetHolidayColourFg, 1513). +-define(wxCalendarCtrl_GetHolidayColourBg, 1514). +-define(wxCalendarCtrl_GetAttr, 1515). +-define(wxCalendarCtrl_SetAttr, 1516). +-define(wxCalendarCtrl_SetHoliday, 1517). +-define(wxCalendarCtrl_ResetAttr, 1518). +-define(wxCalendarCtrl_HitTest, 1519). +-define(wxCalendarDateAttr_new_0, 1520). +-define(wxCalendarDateAttr_new_2_1, 1521). +-define(wxCalendarDateAttr_new_2_0, 1522). +-define(wxCalendarDateAttr_SetTextColour, 1523). +-define(wxCalendarDateAttr_SetBackgroundColour, 1524). +-define(wxCalendarDateAttr_SetBorderColour, 1525). +-define(wxCalendarDateAttr_SetFont, 1526). +-define(wxCalendarDateAttr_SetBorder, 1527). +-define(wxCalendarDateAttr_SetHoliday, 1528). +-define(wxCalendarDateAttr_HasTextColour, 1529). +-define(wxCalendarDateAttr_HasBackgroundColour, 1530). +-define(wxCalendarDateAttr_HasBorderColour, 1531). +-define(wxCalendarDateAttr_HasFont, 1532). +-define(wxCalendarDateAttr_HasBorder, 1533). +-define(wxCalendarDateAttr_IsHoliday, 1534). +-define(wxCalendarDateAttr_GetTextColour, 1535). +-define(wxCalendarDateAttr_GetBackgroundColour, 1536). +-define(wxCalendarDateAttr_GetBorderColour, 1537). +-define(wxCalendarDateAttr_GetFont, 1538). +-define(wxCalendarDateAttr_GetBorder, 1539). +-define(wxCalendarDateAttr_destroy, 1540). +-define(wxCheckBox_new_4, 1542). +-define(wxCheckBox_new_0, 1543). +-define(wxCheckBox_Create, 1544). +-define(wxCheckBox_GetValue, 1545). +-define(wxCheckBox_Get3StateValue, 1546). +-define(wxCheckBox_Is3rdStateAllowedForUser, 1547). +-define(wxCheckBox_Is3State, 1548). +-define(wxCheckBox_IsChecked, 1549). +-define(wxCheckBox_SetValue, 1550). +-define(wxCheckBox_Set3StateValue, 1551). +-define(wxCheckBox_destroy, 1552). +-define(wxCheckListBox_new_0, 1553). +-define(wxCheckListBox_new_3, 1555). +-define(wxCheckListBox_Check, 1556). +-define(wxCheckListBox_IsChecked, 1557). +-define(wxCheckListBox_destroy, 1558). +-define(wxChoice_new_3, 1561). +-define(wxChoice_new_0, 1562). +-define(wxChoice_destruct, 1564). +-define(wxChoice_Create, 1566). +-define(wxChoice_Delete, 1567). +-define(wxChoice_GetColumns, 1568). +-define(wxChoice_SetColumns, 1569). +-define(wxComboBox_new_0, 1570). +-define(wxComboBox_new_3, 1572). +-define(wxComboBox_destruct, 1573). +-define(wxComboBox_Create, 1575). +-define(wxComboBox_CanCopy, 1576). +-define(wxComboBox_CanCut, 1577). +-define(wxComboBox_CanPaste, 1578). +-define(wxComboBox_CanRedo, 1579). +-define(wxComboBox_CanUndo, 1580). +-define(wxComboBox_Copy, 1581). +-define(wxComboBox_Cut, 1582). +-define(wxComboBox_GetInsertionPoint, 1583). +-define(wxComboBox_GetLastPosition, 1584). +-define(wxComboBox_GetValue, 1585). +-define(wxComboBox_Paste, 1586). +-define(wxComboBox_Redo, 1587). +-define(wxComboBox_Replace, 1588). +-define(wxComboBox_Remove, 1589). +-define(wxComboBox_SetInsertionPoint, 1590). +-define(wxComboBox_SetInsertionPointEnd, 1591). +-define(wxComboBox_SetSelection_1, 1592). +-define(wxComboBox_SetSelection_2, 1593). +-define(wxComboBox_SetValue, 1594). +-define(wxComboBox_Undo, 1595). +-define(wxGauge_new_0, 1596). +-define(wxGauge_new_4, 1597). +-define(wxGauge_Create, 1598). +-define(wxGauge_GetBezelFace, 1599). +-define(wxGauge_GetRange, 1600). +-define(wxGauge_GetShadowWidth, 1601). +-define(wxGauge_GetValue, 1602). +-define(wxGauge_IsVertical, 1603). +-define(wxGauge_SetBezelFace, 1604). +-define(wxGauge_SetRange, 1605). +-define(wxGauge_SetShadowWidth, 1606). +-define(wxGauge_SetValue, 1607). +-define(wxGauge_Pulse, 1608). +-define(wxGauge_destroy, 1609). +-define(wxGenericDirCtrl_new_0, 1610). +-define(wxGenericDirCtrl_new_2, 1611). +-define(wxGenericDirCtrl_destruct, 1612). +-define(wxGenericDirCtrl_Create, 1613). +-define(wxGenericDirCtrl_Init, 1614). +-define(wxGenericDirCtrl_CollapseTree, 1615). +-define(wxGenericDirCtrl_ExpandPath, 1616). +-define(wxGenericDirCtrl_GetDefaultPath, 1617). +-define(wxGenericDirCtrl_GetPath, 1618). +-define(wxGenericDirCtrl_GetFilePath, 1619). +-define(wxGenericDirCtrl_GetFilter, 1620). +-define(wxGenericDirCtrl_GetFilterIndex, 1621). +-define(wxGenericDirCtrl_GetRootId, 1622). +-define(wxGenericDirCtrl_GetTreeCtrl, 1623). +-define(wxGenericDirCtrl_ReCreateTree, 1624). +-define(wxGenericDirCtrl_SetDefaultPath, 1625). +-define(wxGenericDirCtrl_SetFilter, 1626). +-define(wxGenericDirCtrl_SetFilterIndex, 1627). +-define(wxGenericDirCtrl_SetPath, 1628). +-define(wxStaticBox_new_4, 1630). +-define(wxStaticBox_new_0, 1631). +-define(wxStaticBox_Create, 1632). +-define(wxStaticBox_destroy, 1633). +-define(wxStaticLine_new_2, 1635). +-define(wxStaticLine_new_0, 1636). +-define(wxStaticLine_Create, 1637). +-define(wxStaticLine_IsVertical, 1638). +-define(wxStaticLine_GetDefaultSize, 1639). +-define(wxStaticLine_destroy, 1640). +-define(wxListBox_new_3, 1643). +-define(wxListBox_new_0, 1644). +-define(wxListBox_destruct, 1646). +-define(wxListBox_Create, 1648). +-define(wxListBox_Deselect, 1649). +-define(wxListBox_GetSelections, 1650). +-define(wxListBox_InsertItems, 1651). +-define(wxListBox_IsSelected, 1652). +-define(wxListBox_Set, 1654). +-define(wxListBox_HitTest, 1655). +-define(wxListBox_SetFirstItem_1_0, 1656). +-define(wxListBox_SetFirstItem_1_1, 1657). +-define(wxListCtrl_new_0, 1658). +-define(wxListCtrl_new_2, 1659). +-define(wxListCtrl_Arrange, 1660). +-define(wxListCtrl_AssignImageList, 1661). +-define(wxListCtrl_ClearAll, 1662). +-define(wxListCtrl_Create, 1663). +-define(wxListCtrl_DeleteAllItems, 1664). +-define(wxListCtrl_DeleteColumn, 1665). +-define(wxListCtrl_DeleteItem, 1666). +-define(wxListCtrl_EditLabel, 1667). +-define(wxListCtrl_EnsureVisible, 1668). +-define(wxListCtrl_FindItem_3_0, 1669). +-define(wxListCtrl_FindItem_3_1, 1670). +-define(wxListCtrl_GetColumn, 1671). +-define(wxListCtrl_GetColumnCount, 1672). +-define(wxListCtrl_GetColumnWidth, 1673). +-define(wxListCtrl_GetCountPerPage, 1674). +-define(wxListCtrl_GetEditControl, 1675). +-define(wxListCtrl_GetImageList, 1676). +-define(wxListCtrl_GetItem, 1677). +-define(wxListCtrl_GetItemBackgroundColour, 1678). +-define(wxListCtrl_GetItemCount, 1679). +-define(wxListCtrl_GetItemData, 1680). +-define(wxListCtrl_GetItemFont, 1681). +-define(wxListCtrl_GetItemPosition, 1682). +-define(wxListCtrl_GetItemRect, 1683). +-define(wxListCtrl_GetItemSpacing, 1684). +-define(wxListCtrl_GetItemState, 1685). +-define(wxListCtrl_GetItemText, 1686). +-define(wxListCtrl_GetItemTextColour, 1687). +-define(wxListCtrl_GetNextItem, 1688). +-define(wxListCtrl_GetSelectedItemCount, 1689). +-define(wxListCtrl_GetTextColour, 1690). +-define(wxListCtrl_GetTopItem, 1691). +-define(wxListCtrl_GetViewRect, 1692). +-define(wxListCtrl_HitTest, 1693). +-define(wxListCtrl_InsertColumn_2, 1694). +-define(wxListCtrl_InsertColumn_3, 1695). +-define(wxListCtrl_InsertItem_1, 1696). +-define(wxListCtrl_InsertItem_2_1, 1697). +-define(wxListCtrl_InsertItem_2_0, 1698). +-define(wxListCtrl_InsertItem_3, 1699). +-define(wxListCtrl_RefreshItem, 1700). +-define(wxListCtrl_RefreshItems, 1701). +-define(wxListCtrl_ScrollList, 1702). +-define(wxListCtrl_SetBackgroundColour, 1703). +-define(wxListCtrl_SetColumn, 1704). +-define(wxListCtrl_SetColumnWidth, 1705). +-define(wxListCtrl_SetImageList, 1706). +-define(wxListCtrl_SetItem_1, 1707). +-define(wxListCtrl_SetItem_4, 1708). +-define(wxListCtrl_SetItemBackgroundColour, 1709). +-define(wxListCtrl_SetItemCount, 1710). +-define(wxListCtrl_SetItemData, 1711). +-define(wxListCtrl_SetItemFont, 1712). +-define(wxListCtrl_SetItemImage, 1713). +-define(wxListCtrl_SetItemColumnImage, 1714). +-define(wxListCtrl_SetItemPosition, 1715). +-define(wxListCtrl_SetItemState, 1716). +-define(wxListCtrl_SetItemText, 1717). +-define(wxListCtrl_SetItemTextColour, 1718). +-define(wxListCtrl_SetSingleStyle, 1719). +-define(wxListCtrl_SetTextColour, 1720). +-define(wxListCtrl_SetWindowStyleFlag, 1721). +-define(wxListCtrl_SortItems, 1722). +-define(wxListCtrl_destroy, 1723). +-define(wxListView_ClearColumnImage, 1724). +-define(wxListView_Focus, 1725). +-define(wxListView_GetFirstSelected, 1726). +-define(wxListView_GetFocusedItem, 1727). +-define(wxListView_GetNextSelected, 1728). +-define(wxListView_IsSelected, 1729). +-define(wxListView_Select, 1730). +-define(wxListView_SetColumnImage, 1731). +-define(wxListItem_new_0, 1732). +-define(wxListItem_new_1, 1733). +-define(wxListItem_destruct, 1734). +-define(wxListItem_Clear, 1735). +-define(wxListItem_GetAlign, 1736). +-define(wxListItem_GetBackgroundColour, 1737). +-define(wxListItem_GetColumn, 1738). +-define(wxListItem_GetFont, 1739). +-define(wxListItem_GetId, 1740). +-define(wxListItem_GetImage, 1741). +-define(wxListItem_GetMask, 1742). +-define(wxListItem_GetState, 1743). +-define(wxListItem_GetText, 1744). +-define(wxListItem_GetTextColour, 1745). +-define(wxListItem_GetWidth, 1746). +-define(wxListItem_SetAlign, 1747). +-define(wxListItem_SetBackgroundColour, 1748). +-define(wxListItem_SetColumn, 1749). +-define(wxListItem_SetFont, 1750). +-define(wxListItem_SetId, 1751). +-define(wxListItem_SetImage, 1752). +-define(wxListItem_SetMask, 1753). +-define(wxListItem_SetState, 1754). +-define(wxListItem_SetStateMask, 1755). +-define(wxListItem_SetText, 1756). +-define(wxListItem_SetTextColour, 1757). +-define(wxListItem_SetWidth, 1758). +-define(wxListItemAttr_new_0, 1759). +-define(wxListItemAttr_new_3, 1760). +-define(wxListItemAttr_GetBackgroundColour, 1761). +-define(wxListItemAttr_GetFont, 1762). +-define(wxListItemAttr_GetTextColour, 1763). +-define(wxListItemAttr_HasBackgroundColour, 1764). +-define(wxListItemAttr_HasFont, 1765). +-define(wxListItemAttr_HasTextColour, 1766). +-define(wxListItemAttr_SetBackgroundColour, 1767). +-define(wxListItemAttr_SetFont, 1768). +-define(wxListItemAttr_SetTextColour, 1769). +-define(wxListItemAttr_destroy, 1770). +-define(wxImageList_new_0, 1771). +-define(wxImageList_new_3, 1772). +-define(wxImageList_Add_1, 1773). +-define(wxImageList_Add_2_0, 1774). +-define(wxImageList_Add_2_1, 1775). +-define(wxImageList_Create, 1776). +-define(wxImageList_Draw, 1778). +-define(wxImageList_GetBitmap, 1779). +-define(wxImageList_GetIcon, 1780). +-define(wxImageList_GetImageCount, 1781). +-define(wxImageList_GetSize, 1782). +-define(wxImageList_Remove, 1783). +-define(wxImageList_RemoveAll, 1784). +-define(wxImageList_Replace_2, 1785). +-define(wxImageList_Replace_3, 1786). +-define(wxImageList_destroy, 1787). +-define(wxTextAttr_new_0, 1788). +-define(wxTextAttr_new_2, 1789). +-define(wxTextAttr_GetAlignment, 1790). +-define(wxTextAttr_GetBackgroundColour, 1791). +-define(wxTextAttr_GetFont, 1792). +-define(wxTextAttr_GetLeftIndent, 1793). +-define(wxTextAttr_GetLeftSubIndent, 1794). +-define(wxTextAttr_GetRightIndent, 1795). +-define(wxTextAttr_GetTabs, 1796). +-define(wxTextAttr_GetTextColour, 1797). +-define(wxTextAttr_HasBackgroundColour, 1798). +-define(wxTextAttr_HasFont, 1799). +-define(wxTextAttr_HasTextColour, 1800). +-define(wxTextAttr_GetFlags, 1801). +-define(wxTextAttr_IsDefault, 1802). +-define(wxTextAttr_SetAlignment, 1803). +-define(wxTextAttr_SetBackgroundColour, 1804). +-define(wxTextAttr_SetFlags, 1805). +-define(wxTextAttr_SetFont, 1806). +-define(wxTextAttr_SetLeftIndent, 1807). +-define(wxTextAttr_SetRightIndent, 1808). +-define(wxTextAttr_SetTabs, 1809). +-define(wxTextAttr_SetTextColour, 1810). +-define(wxTextAttr_destroy, 1811). +-define(wxTextCtrl_new_3, 1813). +-define(wxTextCtrl_new_0, 1814). +-define(wxTextCtrl_destruct, 1816). +-define(wxTextCtrl_AppendText, 1817). +-define(wxTextCtrl_CanCopy, 1818). +-define(wxTextCtrl_CanCut, 1819). +-define(wxTextCtrl_CanPaste, 1820). +-define(wxTextCtrl_CanRedo, 1821). +-define(wxTextCtrl_CanUndo, 1822). +-define(wxTextCtrl_Clear, 1823). +-define(wxTextCtrl_Copy, 1824). +-define(wxTextCtrl_Create, 1825). +-define(wxTextCtrl_Cut, 1826). +-define(wxTextCtrl_DiscardEdits, 1827). +-define(wxTextCtrl_EmulateKeyPress, 1828). +-define(wxTextCtrl_GetDefaultStyle, 1829). +-define(wxTextCtrl_GetInsertionPoint, 1830). +-define(wxTextCtrl_GetLastPosition, 1831). +-define(wxTextCtrl_GetLineLength, 1832). +-define(wxTextCtrl_GetLineText, 1833). +-define(wxTextCtrl_GetNumberOfLines, 1834). +-define(wxTextCtrl_GetRange, 1835). +-define(wxTextCtrl_GetSelection, 1836). +-define(wxTextCtrl_GetStringSelection, 1837). +-define(wxTextCtrl_GetStyle, 1838). +-define(wxTextCtrl_GetValue, 1839). +-define(wxTextCtrl_IsEditable, 1840). +-define(wxTextCtrl_IsModified, 1841). +-define(wxTextCtrl_IsMultiLine, 1842). +-define(wxTextCtrl_IsSingleLine, 1843). +-define(wxTextCtrl_LoadFile, 1844). +-define(wxTextCtrl_MarkDirty, 1845). +-define(wxTextCtrl_Paste, 1846). +-define(wxTextCtrl_PositionToXY, 1847). +-define(wxTextCtrl_Redo, 1848). +-define(wxTextCtrl_Remove, 1849). +-define(wxTextCtrl_Replace, 1850). +-define(wxTextCtrl_SaveFile, 1851). +-define(wxTextCtrl_SetDefaultStyle, 1852). +-define(wxTextCtrl_SetEditable, 1853). +-define(wxTextCtrl_SetInsertionPoint, 1854). +-define(wxTextCtrl_SetInsertionPointEnd, 1855). +-define(wxTextCtrl_SetMaxLength, 1857). +-define(wxTextCtrl_SetSelection, 1858). +-define(wxTextCtrl_SetStyle, 1859). +-define(wxTextCtrl_SetValue, 1860). +-define(wxTextCtrl_ShowPosition, 1861). +-define(wxTextCtrl_Undo, 1862). +-define(wxTextCtrl_WriteText, 1863). +-define(wxTextCtrl_XYToPosition, 1864). +-define(wxNotebook_new_0, 1867). +-define(wxNotebook_new_3, 1868). +-define(wxNotebook_destruct, 1869). +-define(wxNotebook_AddPage, 1870). +-define(wxNotebook_AdvanceSelection, 1871). +-define(wxNotebook_AssignImageList, 1872). +-define(wxNotebook_Create, 1873). +-define(wxNotebook_DeleteAllPages, 1874). +-define(wxNotebook_DeletePage, 1875). +-define(wxNotebook_RemovePage, 1876). +-define(wxNotebook_GetCurrentPage, 1877). +-define(wxNotebook_GetImageList, 1878). +-define(wxNotebook_GetPage, 1880). +-define(wxNotebook_GetPageCount, 1881). +-define(wxNotebook_GetPageImage, 1882). +-define(wxNotebook_GetPageText, 1883). +-define(wxNotebook_GetRowCount, 1884). +-define(wxNotebook_GetSelection, 1885). +-define(wxNotebook_GetThemeBackgroundColour, 1886). +-define(wxNotebook_HitTest, 1888). +-define(wxNotebook_InsertPage, 1890). +-define(wxNotebook_SetImageList, 1891). +-define(wxNotebook_SetPadding, 1892). +-define(wxNotebook_SetPageSize, 1893). +-define(wxNotebook_SetPageImage, 1894). +-define(wxNotebook_SetPageText, 1895). +-define(wxNotebook_SetSelection, 1896). +-define(wxNotebook_ChangeSelection, 1897). +-define(wxChoicebook_new_0, 1898). +-define(wxChoicebook_new_3, 1899). +-define(wxChoicebook_AddPage, 1900). +-define(wxChoicebook_AdvanceSelection, 1901). +-define(wxChoicebook_AssignImageList, 1902). +-define(wxChoicebook_Create, 1903). +-define(wxChoicebook_DeleteAllPages, 1904). +-define(wxChoicebook_DeletePage, 1905). +-define(wxChoicebook_RemovePage, 1906). +-define(wxChoicebook_GetCurrentPage, 1907). +-define(wxChoicebook_GetImageList, 1908). +-define(wxChoicebook_GetPage, 1910). +-define(wxChoicebook_GetPageCount, 1911). +-define(wxChoicebook_GetPageImage, 1912). +-define(wxChoicebook_GetPageText, 1913). +-define(wxChoicebook_GetSelection, 1914). +-define(wxChoicebook_HitTest, 1915). +-define(wxChoicebook_InsertPage, 1916). +-define(wxChoicebook_SetImageList, 1917). +-define(wxChoicebook_SetPageSize, 1918). +-define(wxChoicebook_SetPageImage, 1919). +-define(wxChoicebook_SetPageText, 1920). +-define(wxChoicebook_SetSelection, 1921). +-define(wxChoicebook_ChangeSelection, 1922). +-define(wxChoicebook_destroy, 1923). +-define(wxToolbook_new_0, 1924). +-define(wxToolbook_new_3, 1925). +-define(wxToolbook_AddPage, 1926). +-define(wxToolbook_AdvanceSelection, 1927). +-define(wxToolbook_AssignImageList, 1928). +-define(wxToolbook_Create, 1929). +-define(wxToolbook_DeleteAllPages, 1930). +-define(wxToolbook_DeletePage, 1931). +-define(wxToolbook_RemovePage, 1932). +-define(wxToolbook_GetCurrentPage, 1933). +-define(wxToolbook_GetImageList, 1934). +-define(wxToolbook_GetPage, 1936). +-define(wxToolbook_GetPageCount, 1937). +-define(wxToolbook_GetPageImage, 1938). +-define(wxToolbook_GetPageText, 1939). +-define(wxToolbook_GetSelection, 1940). +-define(wxToolbook_HitTest, 1942). +-define(wxToolbook_InsertPage, 1943). +-define(wxToolbook_SetImageList, 1944). +-define(wxToolbook_SetPageSize, 1945). +-define(wxToolbook_SetPageImage, 1946). +-define(wxToolbook_SetPageText, 1947). +-define(wxToolbook_SetSelection, 1948). +-define(wxToolbook_ChangeSelection, 1949). +-define(wxToolbook_destroy, 1950). +-define(wxListbook_new_0, 1951). +-define(wxListbook_new_3, 1952). +-define(wxListbook_AddPage, 1953). +-define(wxListbook_AdvanceSelection, 1954). +-define(wxListbook_AssignImageList, 1955). +-define(wxListbook_Create, 1956). +-define(wxListbook_DeleteAllPages, 1957). +-define(wxListbook_DeletePage, 1958). +-define(wxListbook_RemovePage, 1959). +-define(wxListbook_GetCurrentPage, 1960). +-define(wxListbook_GetImageList, 1961). +-define(wxListbook_GetPage, 1963). +-define(wxListbook_GetPageCount, 1964). +-define(wxListbook_GetPageImage, 1965). +-define(wxListbook_GetPageText, 1966). +-define(wxListbook_GetSelection, 1967). +-define(wxListbook_HitTest, 1969). +-define(wxListbook_InsertPage, 1970). +-define(wxListbook_SetImageList, 1971). +-define(wxListbook_SetPageSize, 1972). +-define(wxListbook_SetPageImage, 1973). +-define(wxListbook_SetPageText, 1974). +-define(wxListbook_SetSelection, 1975). +-define(wxListbook_ChangeSelection, 1976). +-define(wxListbook_destroy, 1977). +-define(wxTreebook_new_0, 1978). +-define(wxTreebook_new_3, 1979). +-define(wxTreebook_AddPage, 1980). +-define(wxTreebook_AdvanceSelection, 1981). +-define(wxTreebook_AssignImageList, 1982). +-define(wxTreebook_Create, 1983). +-define(wxTreebook_DeleteAllPages, 1984). +-define(wxTreebook_DeletePage, 1985). +-define(wxTreebook_RemovePage, 1986). +-define(wxTreebook_GetCurrentPage, 1987). +-define(wxTreebook_GetImageList, 1988). +-define(wxTreebook_GetPage, 1990). +-define(wxTreebook_GetPageCount, 1991). +-define(wxTreebook_GetPageImage, 1992). +-define(wxTreebook_GetPageText, 1993). +-define(wxTreebook_GetSelection, 1994). +-define(wxTreebook_ExpandNode, 1995). +-define(wxTreebook_IsNodeExpanded, 1996). +-define(wxTreebook_HitTest, 1998). +-define(wxTreebook_InsertPage, 1999). +-define(wxTreebook_InsertSubPage, 2000). +-define(wxTreebook_SetImageList, 2001). +-define(wxTreebook_SetPageSize, 2002). +-define(wxTreebook_SetPageImage, 2003). +-define(wxTreebook_SetPageText, 2004). +-define(wxTreebook_SetSelection, 2005). +-define(wxTreebook_ChangeSelection, 2006). +-define(wxTreebook_destroy, 2007). +-define(wxTreeCtrl_new_2, 2010). +-define(wxTreeCtrl_new_0, 2011). +-define(wxTreeCtrl_destruct, 2013). +-define(wxTreeCtrl_AddRoot, 2014). +-define(wxTreeCtrl_AppendItem, 2015). +-define(wxTreeCtrl_AssignImageList, 2016). +-define(wxTreeCtrl_AssignStateImageList, 2017). +-define(wxTreeCtrl_Collapse, 2018). +-define(wxTreeCtrl_CollapseAndReset, 2019). +-define(wxTreeCtrl_Create, 2020). +-define(wxTreeCtrl_Delete, 2021). +-define(wxTreeCtrl_DeleteAllItems, 2022). +-define(wxTreeCtrl_DeleteChildren, 2023). +-define(wxTreeCtrl_EditLabel, 2024). +-define(wxTreeCtrl_EnsureVisible, 2025). +-define(wxTreeCtrl_Expand, 2026). +-define(wxTreeCtrl_GetBoundingRect, 2027). +-define(wxTreeCtrl_GetChildrenCount, 2029). +-define(wxTreeCtrl_GetCount, 2030). +-define(wxTreeCtrl_GetEditControl, 2031). +-define(wxTreeCtrl_GetFirstChild, 2032). +-define(wxTreeCtrl_GetNextChild, 2033). +-define(wxTreeCtrl_GetFirstVisibleItem, 2034). +-define(wxTreeCtrl_GetImageList, 2035). +-define(wxTreeCtrl_GetIndent, 2036). +-define(wxTreeCtrl_GetItemBackgroundColour, 2037). +-define(wxTreeCtrl_GetItemData, 2038). +-define(wxTreeCtrl_GetItemFont, 2039). +-define(wxTreeCtrl_GetItemImage_1, 2040). +-define(wxTreeCtrl_GetItemImage_2, 2041). +-define(wxTreeCtrl_GetItemText, 2042). +-define(wxTreeCtrl_GetItemTextColour, 2043). +-define(wxTreeCtrl_GetLastChild, 2044). +-define(wxTreeCtrl_GetNextSibling, 2045). +-define(wxTreeCtrl_GetNextVisible, 2046). +-define(wxTreeCtrl_GetItemParent, 2047). +-define(wxTreeCtrl_GetPrevSibling, 2048). +-define(wxTreeCtrl_GetPrevVisible, 2049). +-define(wxTreeCtrl_GetRootItem, 2050). +-define(wxTreeCtrl_GetSelection, 2051). +-define(wxTreeCtrl_GetSelections, 2052). +-define(wxTreeCtrl_GetStateImageList, 2053). +-define(wxTreeCtrl_HitTest, 2054). +-define(wxTreeCtrl_InsertItem, 2056). +-define(wxTreeCtrl_IsBold, 2057). +-define(wxTreeCtrl_IsExpanded, 2058). +-define(wxTreeCtrl_IsSelected, 2059). +-define(wxTreeCtrl_IsVisible, 2060). +-define(wxTreeCtrl_ItemHasChildren, 2061). +-define(wxTreeCtrl_IsTreeItemIdOk, 2062). +-define(wxTreeCtrl_PrependItem, 2063). +-define(wxTreeCtrl_ScrollTo, 2064). +-define(wxTreeCtrl_SelectItem_1, 2065). +-define(wxTreeCtrl_SelectItem_2, 2066). +-define(wxTreeCtrl_SetIndent, 2067). +-define(wxTreeCtrl_SetImageList, 2068). +-define(wxTreeCtrl_SetItemBackgroundColour, 2069). +-define(wxTreeCtrl_SetItemBold, 2070). +-define(wxTreeCtrl_SetItemData, 2071). +-define(wxTreeCtrl_SetItemDropHighlight, 2072). +-define(wxTreeCtrl_SetItemFont, 2073). +-define(wxTreeCtrl_SetItemHasChildren, 2074). +-define(wxTreeCtrl_SetItemImage_2, 2075). +-define(wxTreeCtrl_SetItemImage_3, 2076). +-define(wxTreeCtrl_SetItemText, 2077). +-define(wxTreeCtrl_SetItemTextColour, 2078). +-define(wxTreeCtrl_SetStateImageList, 2079). +-define(wxTreeCtrl_SetWindowStyle, 2080). +-define(wxTreeCtrl_SortChildren, 2081). +-define(wxTreeCtrl_Toggle, 2082). +-define(wxTreeCtrl_ToggleItemSelection, 2083). +-define(wxTreeCtrl_Unselect, 2084). +-define(wxTreeCtrl_UnselectAll, 2085). +-define(wxTreeCtrl_UnselectItem, 2086). +-define(wxScrollBar_new_0, 2087). +-define(wxScrollBar_new_3, 2088). +-define(wxScrollBar_destruct, 2089). +-define(wxScrollBar_Create, 2090). +-define(wxScrollBar_GetRange, 2091). +-define(wxScrollBar_GetPageSize, 2092). +-define(wxScrollBar_GetThumbPosition, 2093). +-define(wxScrollBar_GetThumbSize, 2094). +-define(wxScrollBar_SetThumbPosition, 2095). +-define(wxScrollBar_SetScrollbar, 2096). +-define(wxSpinButton_new_2, 2098). +-define(wxSpinButton_new_0, 2099). +-define(wxSpinButton_Create, 2100). +-define(wxSpinButton_GetMax, 2101). +-define(wxSpinButton_GetMin, 2102). +-define(wxSpinButton_GetValue, 2103). +-define(wxSpinButton_SetRange, 2104). +-define(wxSpinButton_SetValue, 2105). +-define(wxSpinButton_destroy, 2106). +-define(wxSpinCtrl_new_0, 2107). +-define(wxSpinCtrl_new_2, 2108). +-define(wxSpinCtrl_Create, 2110). +-define(wxSpinCtrl_SetValue_1_1, 2113). +-define(wxSpinCtrl_SetValue_1_0, 2114). +-define(wxSpinCtrl_GetValue, 2116). +-define(wxSpinCtrl_SetRange, 2118). +-define(wxSpinCtrl_SetSelection, 2119). +-define(wxSpinCtrl_GetMin, 2121). +-define(wxSpinCtrl_GetMax, 2123). +-define(wxSpinCtrl_destroy, 2124). +-define(wxStaticText_new_0, 2125). +-define(wxStaticText_new_4, 2126). +-define(wxStaticText_Create, 2127). +-define(wxStaticText_GetLabel, 2128). +-define(wxStaticText_SetLabel, 2129). +-define(wxStaticText_Wrap, 2130). +-define(wxStaticText_destroy, 2131). +-define(wxStaticBitmap_new_0, 2132). +-define(wxStaticBitmap_new_4, 2133). +-define(wxStaticBitmap_Create, 2134). +-define(wxStaticBitmap_GetBitmap, 2135). +-define(wxStaticBitmap_SetBitmap, 2136). +-define(wxStaticBitmap_destroy, 2137). +-define(wxRadioBox_new, 2138). +-define(wxRadioBox_destruct, 2140). +-define(wxRadioBox_Create, 2141). +-define(wxRadioBox_Enable_2, 2142). +-define(wxRadioBox_Enable_1, 2143). +-define(wxRadioBox_GetSelection, 2144). +-define(wxRadioBox_GetString, 2145). +-define(wxRadioBox_SetSelection, 2146). +-define(wxRadioBox_Show_2, 2147). +-define(wxRadioBox_Show_1, 2148). +-define(wxRadioBox_GetColumnCount, 2149). +-define(wxRadioBox_GetItemHelpText, 2150). +-define(wxRadioBox_GetItemToolTip, 2151). +-define(wxRadioBox_GetItemFromPoint, 2153). +-define(wxRadioBox_GetRowCount, 2154). +-define(wxRadioBox_IsItemEnabled, 2155). +-define(wxRadioBox_IsItemShown, 2156). +-define(wxRadioBox_SetItemHelpText, 2157). +-define(wxRadioBox_SetItemToolTip, 2158). +-define(wxRadioButton_new_0, 2159). +-define(wxRadioButton_new_4, 2160). +-define(wxRadioButton_Create, 2161). +-define(wxRadioButton_GetValue, 2162). +-define(wxRadioButton_SetValue, 2163). +-define(wxRadioButton_destroy, 2164). +-define(wxSlider_new_6, 2166). +-define(wxSlider_new_0, 2167). +-define(wxSlider_Create, 2168). +-define(wxSlider_GetLineSize, 2169). +-define(wxSlider_GetMax, 2170). +-define(wxSlider_GetMin, 2171). +-define(wxSlider_GetPageSize, 2172). +-define(wxSlider_GetThumbLength, 2173). +-define(wxSlider_GetValue, 2174). +-define(wxSlider_SetLineSize, 2175). +-define(wxSlider_SetPageSize, 2176). +-define(wxSlider_SetRange, 2177). +-define(wxSlider_SetThumbLength, 2178). +-define(wxSlider_SetValue, 2179). +-define(wxSlider_destroy, 2180). +-define(wxDialog_new_4, 2182). +-define(wxDialog_new_0, 2183). +-define(wxDialog_destruct, 2185). +-define(wxDialog_Create, 2186). +-define(wxDialog_CreateButtonSizer, 2187). +-define(wxDialog_CreateStdDialogButtonSizer, 2188). +-define(wxDialog_EndModal, 2189). +-define(wxDialog_GetAffirmativeId, 2190). +-define(wxDialog_GetReturnCode, 2191). +-define(wxDialog_IsModal, 2192). +-define(wxDialog_SetAffirmativeId, 2193). +-define(wxDialog_SetReturnCode, 2194). +-define(wxDialog_Show, 2195). +-define(wxDialog_ShowModal, 2196). +-define(wxColourDialog_new_0, 2197). +-define(wxColourDialog_new_2, 2198). +-define(wxColourDialog_destruct, 2199). +-define(wxColourDialog_Create, 2200). +-define(wxColourDialog_GetColourData, 2201). +-define(wxColourData_new_0, 2202). +-define(wxColourData_new_1, 2203). +-define(wxColourData_destruct, 2204). +-define(wxColourData_GetChooseFull, 2205). +-define(wxColourData_GetColour, 2206). +-define(wxColourData_GetCustomColour, 2208). +-define(wxColourData_SetChooseFull, 2209). +-define(wxColourData_SetColour, 2210). +-define(wxColourData_SetCustomColour, 2211). +-define(wxPalette_new_0, 2212). +-define(wxPalette_new_4, 2213). +-define(wxPalette_destruct, 2215). +-define(wxPalette_Create, 2216). +-define(wxPalette_GetColoursCount, 2217). +-define(wxPalette_GetPixel, 2218). +-define(wxPalette_GetRGB, 2219). +-define(wxPalette_IsOk, 2220). +-define(wxDirDialog_new, 2224). +-define(wxDirDialog_destruct, 2225). +-define(wxDirDialog_GetPath, 2226). +-define(wxDirDialog_GetMessage, 2227). +-define(wxDirDialog_SetMessage, 2228). +-define(wxDirDialog_SetPath, 2229). +-define(wxFileDialog_new, 2233). +-define(wxFileDialog_destruct, 2234). +-define(wxFileDialog_GetDirectory, 2235). +-define(wxFileDialog_GetFilename, 2236). +-define(wxFileDialog_GetFilenames, 2237). +-define(wxFileDialog_GetFilterIndex, 2238). +-define(wxFileDialog_GetMessage, 2239). +-define(wxFileDialog_GetPath, 2240). +-define(wxFileDialog_GetPaths, 2241). +-define(wxFileDialog_GetWildcard, 2242). +-define(wxFileDialog_SetDirectory, 2243). +-define(wxFileDialog_SetFilename, 2244). +-define(wxFileDialog_SetFilterIndex, 2245). +-define(wxFileDialog_SetMessage, 2246). +-define(wxFileDialog_SetPath, 2247). +-define(wxFileDialog_SetWildcard, 2248). +-define(wxPickerBase_SetInternalMargin, 2249). +-define(wxPickerBase_GetInternalMargin, 2250). +-define(wxPickerBase_SetTextCtrlProportion, 2251). +-define(wxPickerBase_SetPickerCtrlProportion, 2252). +-define(wxPickerBase_GetTextCtrlProportion, 2253). +-define(wxPickerBase_GetPickerCtrlProportion, 2254). +-define(wxPickerBase_HasTextCtrl, 2255). +-define(wxPickerBase_GetTextCtrl, 2256). +-define(wxPickerBase_IsTextCtrlGrowable, 2257). +-define(wxPickerBase_SetPickerCtrlGrowable, 2258). +-define(wxPickerBase_SetTextCtrlGrowable, 2259). +-define(wxPickerBase_IsPickerCtrlGrowable, 2260). +-define(wxFilePickerCtrl_new_0, 2261). +-define(wxFilePickerCtrl_new_3, 2262). +-define(wxFilePickerCtrl_Create, 2263). +-define(wxFilePickerCtrl_GetPath, 2264). +-define(wxFilePickerCtrl_SetPath, 2265). +-define(wxFilePickerCtrl_destroy, 2266). +-define(wxDirPickerCtrl_new_0, 2267). +-define(wxDirPickerCtrl_new_3, 2268). +-define(wxDirPickerCtrl_Create, 2269). +-define(wxDirPickerCtrl_GetPath, 2270). +-define(wxDirPickerCtrl_SetPath, 2271). +-define(wxDirPickerCtrl_destroy, 2272). +-define(wxColourPickerCtrl_new_0, 2273). +-define(wxColourPickerCtrl_new_3, 2274). +-define(wxColourPickerCtrl_Create, 2275). +-define(wxColourPickerCtrl_GetColour, 2276). +-define(wxColourPickerCtrl_SetColour_1_1, 2277). +-define(wxColourPickerCtrl_SetColour_1_0, 2278). +-define(wxColourPickerCtrl_destroy, 2279). +-define(wxDatePickerCtrl_new_0, 2280). +-define(wxDatePickerCtrl_new_3, 2281). +-define(wxDatePickerCtrl_GetRange, 2282). +-define(wxDatePickerCtrl_GetValue, 2283). +-define(wxDatePickerCtrl_SetRange, 2284). +-define(wxDatePickerCtrl_SetValue, 2285). +-define(wxDatePickerCtrl_destroy, 2286). +-define(wxFontPickerCtrl_new_0, 2287). +-define(wxFontPickerCtrl_new_3, 2288). +-define(wxFontPickerCtrl_Create, 2289). +-define(wxFontPickerCtrl_GetSelectedFont, 2290). +-define(wxFontPickerCtrl_SetSelectedFont, 2291). +-define(wxFontPickerCtrl_GetMaxPointSize, 2292). +-define(wxFontPickerCtrl_SetMaxPointSize, 2293). +-define(wxFontPickerCtrl_destroy, 2294). +-define(wxFindReplaceDialog_new_0, 2297). +-define(wxFindReplaceDialog_new_4, 2298). +-define(wxFindReplaceDialog_destruct, 2299). +-define(wxFindReplaceDialog_Create, 2300). +-define(wxFindReplaceDialog_GetData, 2301). +-define(wxFindReplaceData_new_0, 2302). +-define(wxFindReplaceData_new_1, 2303). +-define(wxFindReplaceData_GetFindString, 2304). +-define(wxFindReplaceData_GetReplaceString, 2305). +-define(wxFindReplaceData_GetFlags, 2306). +-define(wxFindReplaceData_SetFlags, 2307). +-define(wxFindReplaceData_SetFindString, 2308). +-define(wxFindReplaceData_SetReplaceString, 2309). +-define(wxFindReplaceData_destroy, 2310). +-define(wxMultiChoiceDialog_new_0, 2311). +-define(wxMultiChoiceDialog_new_5, 2313). +-define(wxMultiChoiceDialog_GetSelections, 2314). +-define(wxMultiChoiceDialog_SetSelections, 2315). +-define(wxMultiChoiceDialog_destroy, 2316). +-define(wxSingleChoiceDialog_new_0, 2317). +-define(wxSingleChoiceDialog_new_5, 2319). +-define(wxSingleChoiceDialog_GetSelection, 2320). +-define(wxSingleChoiceDialog_GetStringSelection, 2321). +-define(wxSingleChoiceDialog_SetSelection, 2322). +-define(wxSingleChoiceDialog_destroy, 2323). +-define(wxTextEntryDialog_new, 2324). +-define(wxTextEntryDialog_GetValue, 2325). +-define(wxTextEntryDialog_SetValue, 2326). +-define(wxTextEntryDialog_destroy, 2327). +-define(wxPasswordEntryDialog_new, 2328). +-define(wxPasswordEntryDialog_destroy, 2329). +-define(wxFontData_new_0, 2330). +-define(wxFontData_new_1, 2331). +-define(wxFontData_destruct, 2332). +-define(wxFontData_EnableEffects, 2333). +-define(wxFontData_GetAllowSymbols, 2334). +-define(wxFontData_GetColour, 2335). +-define(wxFontData_GetChosenFont, 2336). +-define(wxFontData_GetEnableEffects, 2337). +-define(wxFontData_GetInitialFont, 2338). +-define(wxFontData_GetShowHelp, 2339). +-define(wxFontData_SetAllowSymbols, 2340). +-define(wxFontData_SetChosenFont, 2341). +-define(wxFontData_SetColour, 2342). +-define(wxFontData_SetInitialFont, 2343). +-define(wxFontData_SetRange, 2344). +-define(wxFontData_SetShowHelp, 2345). +-define(wxFontDialog_new_0, 2349). +-define(wxFontDialog_new_2, 2351). +-define(wxFontDialog_Create, 2353). +-define(wxFontDialog_GetFontData, 2354). +-define(wxFontDialog_destroy, 2356). +-define(wxProgressDialog_new, 2357). +-define(wxProgressDialog_destruct, 2358). +-define(wxProgressDialog_Resume, 2359). +-define(wxProgressDialog_Update_2, 2360). +-define(wxProgressDialog_Update_0, 2361). +-define(wxMessageDialog_new, 2362). +-define(wxMessageDialog_destruct, 2363). +-define(wxPageSetupDialog_new, 2364). +-define(wxPageSetupDialog_destruct, 2365). +-define(wxPageSetupDialog_GetPageSetupData, 2366). +-define(wxPageSetupDialog_ShowModal, 2367). +-define(wxPageSetupDialogData_new_0, 2368). +-define(wxPageSetupDialogData_new_1_0, 2369). +-define(wxPageSetupDialogData_new_1_1, 2370). +-define(wxPageSetupDialogData_destruct, 2371). +-define(wxPageSetupDialogData_EnableHelp, 2372). +-define(wxPageSetupDialogData_EnableMargins, 2373). +-define(wxPageSetupDialogData_EnableOrientation, 2374). +-define(wxPageSetupDialogData_EnablePaper, 2375). +-define(wxPageSetupDialogData_EnablePrinter, 2376). +-define(wxPageSetupDialogData_GetDefaultMinMargins, 2377). +-define(wxPageSetupDialogData_GetEnableMargins, 2378). +-define(wxPageSetupDialogData_GetEnableOrientation, 2379). +-define(wxPageSetupDialogData_GetEnablePaper, 2380). +-define(wxPageSetupDialogData_GetEnablePrinter, 2381). +-define(wxPageSetupDialogData_GetEnableHelp, 2382). +-define(wxPageSetupDialogData_GetDefaultInfo, 2383). +-define(wxPageSetupDialogData_GetMarginTopLeft, 2384). +-define(wxPageSetupDialogData_GetMarginBottomRight, 2385). +-define(wxPageSetupDialogData_GetMinMarginTopLeft, 2386). +-define(wxPageSetupDialogData_GetMinMarginBottomRight, 2387). +-define(wxPageSetupDialogData_GetPaperId, 2388). +-define(wxPageSetupDialogData_GetPaperSize, 2389). +-define(wxPageSetupDialogData_GetPrintData, 2391). +-define(wxPageSetupDialogData_IsOk, 2392). +-define(wxPageSetupDialogData_SetDefaultInfo, 2393). +-define(wxPageSetupDialogData_SetDefaultMinMargins, 2394). +-define(wxPageSetupDialogData_SetMarginTopLeft, 2395). +-define(wxPageSetupDialogData_SetMarginBottomRight, 2396). +-define(wxPageSetupDialogData_SetMinMarginTopLeft, 2397). +-define(wxPageSetupDialogData_SetMinMarginBottomRight, 2398). +-define(wxPageSetupDialogData_SetPaperId, 2399). +-define(wxPageSetupDialogData_SetPaperSize_1_1, 2400). +-define(wxPageSetupDialogData_SetPaperSize_1_0, 2401). +-define(wxPageSetupDialogData_SetPrintData, 2402). +-define(wxPrintDialog_new_2_0, 2403). +-define(wxPrintDialog_new_2_1, 2404). +-define(wxPrintDialog_destruct, 2405). +-define(wxPrintDialog_GetPrintDialogData, 2406). +-define(wxPrintDialog_GetPrintDC, 2407). +-define(wxPrintDialogData_new_0, 2408). +-define(wxPrintDialogData_new_1_1, 2409). +-define(wxPrintDialogData_new_1_0, 2410). +-define(wxPrintDialogData_destruct, 2411). +-define(wxPrintDialogData_EnableHelp, 2412). +-define(wxPrintDialogData_EnablePageNumbers, 2413). +-define(wxPrintDialogData_EnablePrintToFile, 2414). +-define(wxPrintDialogData_EnableSelection, 2415). +-define(wxPrintDialogData_GetAllPages, 2416). +-define(wxPrintDialogData_GetCollate, 2417). +-define(wxPrintDialogData_GetFromPage, 2418). +-define(wxPrintDialogData_GetMaxPage, 2419). +-define(wxPrintDialogData_GetMinPage, 2420). +-define(wxPrintDialogData_GetNoCopies, 2421). +-define(wxPrintDialogData_GetPrintData, 2422). +-define(wxPrintDialogData_GetPrintToFile, 2423). +-define(wxPrintDialogData_GetSelection, 2424). +-define(wxPrintDialogData_GetToPage, 2425). +-define(wxPrintDialogData_IsOk, 2426). +-define(wxPrintDialogData_SetCollate, 2427). +-define(wxPrintDialogData_SetFromPage, 2428). +-define(wxPrintDialogData_SetMaxPage, 2429). +-define(wxPrintDialogData_SetMinPage, 2430). +-define(wxPrintDialogData_SetNoCopies, 2431). +-define(wxPrintDialogData_SetPrintData, 2432). +-define(wxPrintDialogData_SetPrintToFile, 2433). +-define(wxPrintDialogData_SetSelection, 2434). +-define(wxPrintDialogData_SetToPage, 2435). +-define(wxPrintData_new_0, 2436). +-define(wxPrintData_new_1, 2437). +-define(wxPrintData_destruct, 2438). +-define(wxPrintData_GetCollate, 2439). +-define(wxPrintData_GetBin, 2440). +-define(wxPrintData_GetColour, 2441). +-define(wxPrintData_GetDuplex, 2442). +-define(wxPrintData_GetNoCopies, 2443). +-define(wxPrintData_GetOrientation, 2444). +-define(wxPrintData_GetPaperId, 2445). +-define(wxPrintData_GetPrinterName, 2446). +-define(wxPrintData_GetQuality, 2447). +-define(wxPrintData_IsOk, 2448). +-define(wxPrintData_SetBin, 2449). +-define(wxPrintData_SetCollate, 2450). +-define(wxPrintData_SetColour, 2451). +-define(wxPrintData_SetDuplex, 2452). +-define(wxPrintData_SetNoCopies, 2453). +-define(wxPrintData_SetOrientation, 2454). +-define(wxPrintData_SetPaperId, 2455). +-define(wxPrintData_SetPrinterName, 2456). +-define(wxPrintData_SetQuality, 2457). +-define(wxPrintPreview_new_2, 2460). +-define(wxPrintPreview_new_3, 2461). +-define(wxPrintPreview_destruct, 2463). +-define(wxPrintPreview_GetCanvas, 2464). +-define(wxPrintPreview_GetCurrentPage, 2465). +-define(wxPrintPreview_GetFrame, 2466). +-define(wxPrintPreview_GetMaxPage, 2467). +-define(wxPrintPreview_GetMinPage, 2468). +-define(wxPrintPreview_GetPrintout, 2469). +-define(wxPrintPreview_GetPrintoutForPrinting, 2470). +-define(wxPrintPreview_IsOk, 2471). +-define(wxPrintPreview_PaintPage, 2472). +-define(wxPrintPreview_Print, 2473). +-define(wxPrintPreview_RenderPage, 2474). +-define(wxPrintPreview_SetCanvas, 2475). +-define(wxPrintPreview_SetCurrentPage, 2476). +-define(wxPrintPreview_SetFrame, 2477). +-define(wxPrintPreview_SetPrintout, 2478). +-define(wxPrintPreview_SetZoom, 2479). +-define(wxPreviewFrame_new, 2480). +-define(wxPreviewFrame_destruct, 2481). +-define(wxPreviewFrame_CreateControlBar, 2482). +-define(wxPreviewFrame_CreateCanvas, 2483). +-define(wxPreviewFrame_Initialize, 2484). +-define(wxPreviewFrame_OnCloseWindow, 2485). +-define(wxPreviewControlBar_new, 2486). +-define(wxPreviewControlBar_destruct, 2487). +-define(wxPreviewControlBar_CreateButtons, 2488). +-define(wxPreviewControlBar_GetPrintPreview, 2489). +-define(wxPreviewControlBar_GetZoomControl, 2490). +-define(wxPreviewControlBar_SetZoomControl, 2491). +-define(wxPrinter_new, 2493). +-define(wxPrinter_CreateAbortWindow, 2494). +-define(wxPrinter_GetAbort, 2495). +-define(wxPrinter_GetLastError, 2496). +-define(wxPrinter_GetPrintDialogData, 2497). +-define(wxPrinter_Print, 2498). +-define(wxPrinter_PrintDialog, 2499). +-define(wxPrinter_ReportError, 2500). +-define(wxPrinter_Setup, 2501). +-define(wxPrinter_destroy, 2502). +-define(wxXmlResource_new_1, 2503). +-define(wxXmlResource_new_2, 2504). +-define(wxXmlResource_destruct, 2505). +-define(wxXmlResource_AttachUnknownControl, 2506). +-define(wxXmlResource_ClearHandlers, 2507). +-define(wxXmlResource_CompareVersion, 2508). +-define(wxXmlResource_Get, 2509). +-define(wxXmlResource_GetFlags, 2510). +-define(wxXmlResource_GetVersion, 2511). +-define(wxXmlResource_GetXRCID, 2512). +-define(wxXmlResource_InitAllHandlers, 2513). +-define(wxXmlResource_Load, 2514). +-define(wxXmlResource_LoadBitmap, 2515). +-define(wxXmlResource_LoadDialog_2, 2516). +-define(wxXmlResource_LoadDialog_3, 2517). +-define(wxXmlResource_LoadFrame_2, 2518). +-define(wxXmlResource_LoadFrame_3, 2519). +-define(wxXmlResource_LoadIcon, 2520). +-define(wxXmlResource_LoadMenu, 2521). +-define(wxXmlResource_LoadMenuBar_2, 2522). +-define(wxXmlResource_LoadMenuBar_1, 2523). +-define(wxXmlResource_LoadPanel_2, 2524). +-define(wxXmlResource_LoadPanel_3, 2525). +-define(wxXmlResource_LoadToolBar, 2526). +-define(wxXmlResource_Set, 2527). +-define(wxXmlResource_SetFlags, 2528). +-define(wxXmlResource_Unload, 2529). +-define(wxXmlResource_xrcctrl, 2530). +-define(wxHtmlEasyPrinting_new, 2531). +-define(wxHtmlEasyPrinting_destruct, 2532). +-define(wxHtmlEasyPrinting_GetPrintData, 2533). +-define(wxHtmlEasyPrinting_GetPageSetupData, 2534). +-define(wxHtmlEasyPrinting_PreviewFile, 2535). +-define(wxHtmlEasyPrinting_PreviewText, 2536). +-define(wxHtmlEasyPrinting_PrintFile, 2537). +-define(wxHtmlEasyPrinting_PrintText, 2538). +-define(wxHtmlEasyPrinting_PageSetup, 2539). +-define(wxHtmlEasyPrinting_SetFonts, 2540). +-define(wxHtmlEasyPrinting_SetHeader, 2541). +-define(wxHtmlEasyPrinting_SetFooter, 2542). +-define(wxGLCanvas_new_2, 2544). +-define(wxGLCanvas_new_3_1, 2545). +-define(wxGLCanvas_new_3_0, 2546). +-define(wxGLCanvas_GetContext, 2547). +-define(wxGLCanvas_SetCurrent, 2549). +-define(wxGLCanvas_SwapBuffers, 2550). +-define(wxGLCanvas_destroy, 2551). +-define(wxAuiManager_new, 2552). +-define(wxAuiManager_destruct, 2553). +-define(wxAuiManager_AddPane_2_1, 2554). +-define(wxAuiManager_AddPane_3, 2555). +-define(wxAuiManager_AddPane_2_0, 2556). +-define(wxAuiManager_DetachPane, 2557). +-define(wxAuiManager_GetAllPanes, 2558). +-define(wxAuiManager_GetArtProvider, 2559). +-define(wxAuiManager_GetDockSizeConstraint, 2560). +-define(wxAuiManager_GetFlags, 2561). +-define(wxAuiManager_GetManagedWindow, 2562). +-define(wxAuiManager_GetManager, 2563). +-define(wxAuiManager_GetPane_1_1, 2564). +-define(wxAuiManager_GetPane_1_0, 2565). +-define(wxAuiManager_HideHint, 2566). +-define(wxAuiManager_InsertPane, 2567). +-define(wxAuiManager_LoadPaneInfo, 2568). +-define(wxAuiManager_LoadPerspective, 2569). +-define(wxAuiManager_SavePaneInfo, 2570). +-define(wxAuiManager_SavePerspective, 2571). +-define(wxAuiManager_SetArtProvider, 2572). +-define(wxAuiManager_SetDockSizeConstraint, 2573). +-define(wxAuiManager_SetFlags, 2574). +-define(wxAuiManager_SetManagedWindow, 2575). +-define(wxAuiManager_ShowHint, 2576). +-define(wxAuiManager_UnInit, 2577). +-define(wxAuiManager_Update, 2578). +-define(wxAuiPaneInfo_new_0, 2579). +-define(wxAuiPaneInfo_new_1, 2580). +-define(wxAuiPaneInfo_destruct, 2581). +-define(wxAuiPaneInfo_BestSize_1, 2582). +-define(wxAuiPaneInfo_BestSize_2, 2583). +-define(wxAuiPaneInfo_Bottom, 2584). +-define(wxAuiPaneInfo_BottomDockable, 2585). +-define(wxAuiPaneInfo_Caption, 2586). +-define(wxAuiPaneInfo_CaptionVisible, 2587). +-define(wxAuiPaneInfo_Centre, 2588). +-define(wxAuiPaneInfo_CentrePane, 2589). +-define(wxAuiPaneInfo_CloseButton, 2590). +-define(wxAuiPaneInfo_DefaultPane, 2591). +-define(wxAuiPaneInfo_DestroyOnClose, 2592). +-define(wxAuiPaneInfo_Direction, 2593). +-define(wxAuiPaneInfo_Dock, 2594). +-define(wxAuiPaneInfo_Dockable, 2595). +-define(wxAuiPaneInfo_Fixed, 2596). +-define(wxAuiPaneInfo_Float, 2597). +-define(wxAuiPaneInfo_Floatable, 2598). +-define(wxAuiPaneInfo_FloatingPosition_1, 2599). +-define(wxAuiPaneInfo_FloatingPosition_2, 2600). +-define(wxAuiPaneInfo_FloatingSize_1, 2601). +-define(wxAuiPaneInfo_FloatingSize_2, 2602). +-define(wxAuiPaneInfo_Gripper, 2603). +-define(wxAuiPaneInfo_GripperTop, 2604). +-define(wxAuiPaneInfo_HasBorder, 2605). +-define(wxAuiPaneInfo_HasCaption, 2606). +-define(wxAuiPaneInfo_HasCloseButton, 2607). +-define(wxAuiPaneInfo_HasFlag, 2608). +-define(wxAuiPaneInfo_HasGripper, 2609). +-define(wxAuiPaneInfo_HasGripperTop, 2610). +-define(wxAuiPaneInfo_HasMaximizeButton, 2611). +-define(wxAuiPaneInfo_HasMinimizeButton, 2612). +-define(wxAuiPaneInfo_HasPinButton, 2613). +-define(wxAuiPaneInfo_Hide, 2614). +-define(wxAuiPaneInfo_IsBottomDockable, 2615). +-define(wxAuiPaneInfo_IsDocked, 2616). +-define(wxAuiPaneInfo_IsFixed, 2617). +-define(wxAuiPaneInfo_IsFloatable, 2618). +-define(wxAuiPaneInfo_IsFloating, 2619). +-define(wxAuiPaneInfo_IsLeftDockable, 2620). +-define(wxAuiPaneInfo_IsMovable, 2621). +-define(wxAuiPaneInfo_IsOk, 2622). +-define(wxAuiPaneInfo_IsResizable, 2623). +-define(wxAuiPaneInfo_IsRightDockable, 2624). +-define(wxAuiPaneInfo_IsShown, 2625). +-define(wxAuiPaneInfo_IsToolbar, 2626). +-define(wxAuiPaneInfo_IsTopDockable, 2627). +-define(wxAuiPaneInfo_Layer, 2628). +-define(wxAuiPaneInfo_Left, 2629). +-define(wxAuiPaneInfo_LeftDockable, 2630). +-define(wxAuiPaneInfo_MaxSize_1, 2631). +-define(wxAuiPaneInfo_MaxSize_2, 2632). +-define(wxAuiPaneInfo_MaximizeButton, 2633). +-define(wxAuiPaneInfo_MinSize_1, 2634). +-define(wxAuiPaneInfo_MinSize_2, 2635). +-define(wxAuiPaneInfo_MinimizeButton, 2636). +-define(wxAuiPaneInfo_Movable, 2637). +-define(wxAuiPaneInfo_Name, 2638). +-define(wxAuiPaneInfo_PaneBorder, 2639). +-define(wxAuiPaneInfo_PinButton, 2640). +-define(wxAuiPaneInfo_Position, 2641). +-define(wxAuiPaneInfo_Resizable, 2642). +-define(wxAuiPaneInfo_Right, 2643). +-define(wxAuiPaneInfo_RightDockable, 2644). +-define(wxAuiPaneInfo_Row, 2645). +-define(wxAuiPaneInfo_SafeSet, 2646). +-define(wxAuiPaneInfo_SetFlag, 2647). +-define(wxAuiPaneInfo_Show, 2648). +-define(wxAuiPaneInfo_ToolbarPane, 2649). +-define(wxAuiPaneInfo_Top, 2650). +-define(wxAuiPaneInfo_TopDockable, 2651). +-define(wxAuiPaneInfo_Window, 2652). +-define(wxAuiNotebook_new_0, 2653). +-define(wxAuiNotebook_new_2, 2654). +-define(wxAuiNotebook_AddPage, 2655). +-define(wxAuiNotebook_Create, 2656). +-define(wxAuiNotebook_DeletePage, 2657). +-define(wxAuiNotebook_GetArtProvider, 2658). +-define(wxAuiNotebook_GetPage, 2659). +-define(wxAuiNotebook_GetPageBitmap, 2660). +-define(wxAuiNotebook_GetPageCount, 2661). +-define(wxAuiNotebook_GetPageIndex, 2662). +-define(wxAuiNotebook_GetPageText, 2663). +-define(wxAuiNotebook_GetSelection, 2664). +-define(wxAuiNotebook_InsertPage, 2665). +-define(wxAuiNotebook_RemovePage, 2666). +-define(wxAuiNotebook_SetArtProvider, 2667). +-define(wxAuiNotebook_SetFont, 2668). +-define(wxAuiNotebook_SetPageBitmap, 2669). +-define(wxAuiNotebook_SetPageText, 2670). +-define(wxAuiNotebook_SetSelection, 2671). +-define(wxAuiNotebook_SetTabCtrlHeight, 2672). +-define(wxAuiNotebook_SetUniformBitmapSize, 2673). +-define(wxAuiNotebook_destroy, 2674). +-define(wxMDIParentFrame_new_0, 2675). +-define(wxMDIParentFrame_new_4, 2676). +-define(wxMDIParentFrame_destruct, 2677). +-define(wxMDIParentFrame_ActivateNext, 2678). +-define(wxMDIParentFrame_ActivatePrevious, 2679). +-define(wxMDIParentFrame_ArrangeIcons, 2680). +-define(wxMDIParentFrame_Cascade, 2681). +-define(wxMDIParentFrame_Create, 2682). +-define(wxMDIParentFrame_GetActiveChild, 2683). +-define(wxMDIParentFrame_GetClientWindow, 2684). +-define(wxMDIParentFrame_Tile, 2685). +-define(wxMDIChildFrame_new_0, 2686). +-define(wxMDIChildFrame_new_4, 2687). +-define(wxMDIChildFrame_destruct, 2688). +-define(wxMDIChildFrame_Activate, 2689). +-define(wxMDIChildFrame_Create, 2690). +-define(wxMDIChildFrame_Maximize, 2691). +-define(wxMDIChildFrame_Restore, 2692). +-define(wxMDIClientWindow_new_0, 2693). +-define(wxMDIClientWindow_new_2, 2694). +-define(wxMDIClientWindow_destruct, 2695). +-define(wxMDIClientWindow_CreateClient, 2696). +-define(wxLayoutAlgorithm_new, 2697). +-define(wxLayoutAlgorithm_LayoutFrame, 2698). +-define(wxLayoutAlgorithm_LayoutMDIFrame, 2699). +-define(wxLayoutAlgorithm_LayoutWindow, 2700). +-define(wxLayoutAlgorithm_destroy, 2701). +-define(wxEvent_GetId, 2702). +-define(wxEvent_GetSkipped, 2703). +-define(wxEvent_GetTimestamp, 2704). +-define(wxEvent_IsCommandEvent, 2705). +-define(wxEvent_ResumePropagation, 2706). +-define(wxEvent_ShouldPropagate, 2707). +-define(wxEvent_Skip, 2708). +-define(wxEvent_StopPropagation, 2709). +-define(wxCommandEvent_getClientData, 2710). +-define(wxCommandEvent_GetExtraLong, 2711). +-define(wxCommandEvent_GetInt, 2712). +-define(wxCommandEvent_GetSelection, 2713). +-define(wxCommandEvent_GetString, 2714). +-define(wxCommandEvent_IsChecked, 2715). +-define(wxCommandEvent_IsSelection, 2716). +-define(wxCommandEvent_SetInt, 2717). +-define(wxCommandEvent_SetString, 2718). +-define(wxScrollEvent_GetOrientation, 2719). +-define(wxScrollEvent_GetPosition, 2720). +-define(wxScrollWinEvent_GetOrientation, 2721). +-define(wxScrollWinEvent_GetPosition, 2722). +-define(wxMouseEvent_AltDown, 2723). +-define(wxMouseEvent_Button, 2724). +-define(wxMouseEvent_ButtonDClick, 2725). +-define(wxMouseEvent_ButtonDown, 2726). +-define(wxMouseEvent_ButtonUp, 2727). +-define(wxMouseEvent_CmdDown, 2728). +-define(wxMouseEvent_ControlDown, 2729). +-define(wxMouseEvent_Dragging, 2730). +-define(wxMouseEvent_Entering, 2731). +-define(wxMouseEvent_GetButton, 2732). +-define(wxMouseEvent_GetPosition, 2735). +-define(wxMouseEvent_GetLogicalPosition, 2736). +-define(wxMouseEvent_GetLinesPerAction, 2737). +-define(wxMouseEvent_GetWheelRotation, 2738). +-define(wxMouseEvent_GetWheelDelta, 2739). +-define(wxMouseEvent_GetX, 2740). +-define(wxMouseEvent_GetY, 2741). +-define(wxMouseEvent_IsButton, 2742). +-define(wxMouseEvent_IsPageScroll, 2743). +-define(wxMouseEvent_Leaving, 2744). +-define(wxMouseEvent_LeftDClick, 2745). +-define(wxMouseEvent_LeftDown, 2746). +-define(wxMouseEvent_LeftIsDown, 2747). +-define(wxMouseEvent_LeftUp, 2748). +-define(wxMouseEvent_MetaDown, 2749). +-define(wxMouseEvent_MiddleDClick, 2750). +-define(wxMouseEvent_MiddleDown, 2751). +-define(wxMouseEvent_MiddleIsDown, 2752). +-define(wxMouseEvent_MiddleUp, 2753). +-define(wxMouseEvent_Moving, 2754). +-define(wxMouseEvent_RightDClick, 2755). +-define(wxMouseEvent_RightDown, 2756). +-define(wxMouseEvent_RightIsDown, 2757). +-define(wxMouseEvent_RightUp, 2758). +-define(wxMouseEvent_ShiftDown, 2759). +-define(wxSetCursorEvent_GetCursor, 2760). +-define(wxSetCursorEvent_GetX, 2761). +-define(wxSetCursorEvent_GetY, 2762). +-define(wxSetCursorEvent_HasCursor, 2763). +-define(wxSetCursorEvent_SetCursor, 2764). +-define(wxKeyEvent_AltDown, 2765). +-define(wxKeyEvent_CmdDown, 2766). +-define(wxKeyEvent_ControlDown, 2767). +-define(wxKeyEvent_GetKeyCode, 2768). +-define(wxKeyEvent_GetModifiers, 2769). +-define(wxKeyEvent_GetPosition, 2772). +-define(wxKeyEvent_GetRawKeyCode, 2773). +-define(wxKeyEvent_GetRawKeyFlags, 2774). +-define(wxKeyEvent_GetUnicodeKey, 2775). +-define(wxKeyEvent_GetX, 2776). +-define(wxKeyEvent_GetY, 2777). +-define(wxKeyEvent_HasModifiers, 2778). +-define(wxKeyEvent_MetaDown, 2779). +-define(wxKeyEvent_ShiftDown, 2780). +-define(wxSizeEvent_GetSize, 2781). +-define(wxMoveEvent_GetPosition, 2782). +-define(wxEraseEvent_GetDC, 2783). +-define(wxFocusEvent_GetWindow, 2784). +-define(wxChildFocusEvent_GetWindow, 2785). +-define(wxMenuEvent_GetMenu, 2786). +-define(wxMenuEvent_GetMenuId, 2787). +-define(wxMenuEvent_IsPopup, 2788). +-define(wxCloseEvent_CanVeto, 2789). +-define(wxCloseEvent_GetLoggingOff, 2790). +-define(wxCloseEvent_SetCanVeto, 2791). +-define(wxCloseEvent_SetLoggingOff, 2792). +-define(wxCloseEvent_Veto, 2793). +-define(wxShowEvent_SetShow, 2794). +-define(wxShowEvent_GetShow, 2795). +-define(wxIconizeEvent_Iconized, 2796). +-define(wxJoystickEvent_ButtonDown, 2797). +-define(wxJoystickEvent_ButtonIsDown, 2798). +-define(wxJoystickEvent_ButtonUp, 2799). +-define(wxJoystickEvent_GetButtonChange, 2800). +-define(wxJoystickEvent_GetButtonState, 2801). +-define(wxJoystickEvent_GetJoystick, 2802). +-define(wxJoystickEvent_GetPosition, 2803). +-define(wxJoystickEvent_GetZPosition, 2804). +-define(wxJoystickEvent_IsButton, 2805). +-define(wxJoystickEvent_IsMove, 2806). +-define(wxJoystickEvent_IsZMove, 2807). +-define(wxUpdateUIEvent_CanUpdate, 2808). +-define(wxUpdateUIEvent_Check, 2809). +-define(wxUpdateUIEvent_Enable, 2810). +-define(wxUpdateUIEvent_Show, 2811). +-define(wxUpdateUIEvent_GetChecked, 2812). +-define(wxUpdateUIEvent_GetEnabled, 2813). +-define(wxUpdateUIEvent_GetShown, 2814). +-define(wxUpdateUIEvent_GetSetChecked, 2815). +-define(wxUpdateUIEvent_GetSetEnabled, 2816). +-define(wxUpdateUIEvent_GetSetShown, 2817). +-define(wxUpdateUIEvent_GetSetText, 2818). +-define(wxUpdateUIEvent_GetText, 2819). +-define(wxUpdateUIEvent_GetMode, 2820). +-define(wxUpdateUIEvent_GetUpdateInterval, 2821). +-define(wxUpdateUIEvent_ResetUpdateTime, 2822). +-define(wxUpdateUIEvent_SetMode, 2823). +-define(wxUpdateUIEvent_SetText, 2824). +-define(wxUpdateUIEvent_SetUpdateInterval, 2825). +-define(wxMouseCaptureChangedEvent_GetCapturedWindow, 2826). +-define(wxPaletteChangedEvent_SetChangedWindow, 2827). +-define(wxPaletteChangedEvent_GetChangedWindow, 2828). +-define(wxQueryNewPaletteEvent_SetPaletteRealized, 2829). +-define(wxQueryNewPaletteEvent_GetPaletteRealized, 2830). +-define(wxNavigationKeyEvent_GetDirection, 2831). +-define(wxNavigationKeyEvent_SetDirection, 2832). +-define(wxNavigationKeyEvent_IsWindowChange, 2833). +-define(wxNavigationKeyEvent_SetWindowChange, 2834). +-define(wxNavigationKeyEvent_IsFromTab, 2835). +-define(wxNavigationKeyEvent_SetFromTab, 2836). +-define(wxNavigationKeyEvent_GetCurrentFocus, 2837). +-define(wxNavigationKeyEvent_SetCurrentFocus, 2838). +-define(wxHelpEvent_GetOrigin, 2839). +-define(wxHelpEvent_GetPosition, 2840). +-define(wxHelpEvent_SetOrigin, 2841). +-define(wxHelpEvent_SetPosition, 2842). +-define(wxContextMenuEvent_GetPosition, 2843). +-define(wxContextMenuEvent_SetPosition, 2844). +-define(wxIdleEvent_CanSend, 2845). +-define(wxIdleEvent_GetMode, 2846). +-define(wxIdleEvent_RequestMore, 2847). +-define(wxIdleEvent_MoreRequested, 2848). +-define(wxIdleEvent_SetMode, 2849). +-define(wxGridEvent_AltDown, 2850). +-define(wxGridEvent_ControlDown, 2851). +-define(wxGridEvent_GetCol, 2852). +-define(wxGridEvent_GetPosition, 2853). +-define(wxGridEvent_GetRow, 2854). +-define(wxGridEvent_MetaDown, 2855). +-define(wxGridEvent_Selecting, 2856). +-define(wxGridEvent_ShiftDown, 2857). +-define(wxNotifyEvent_Allow, 2858). +-define(wxNotifyEvent_IsAllowed, 2859). +-define(wxNotifyEvent_Veto, 2860). +-define(wxSashEvent_GetEdge, 2861). +-define(wxSashEvent_GetDragRect, 2862). +-define(wxSashEvent_GetDragStatus, 2863). +-define(wxListEvent_GetCacheFrom, 2864). +-define(wxListEvent_GetCacheTo, 2865). +-define(wxListEvent_GetKeyCode, 2866). +-define(wxListEvent_GetIndex, 2867). +-define(wxListEvent_GetColumn, 2868). +-define(wxListEvent_GetPoint, 2869). +-define(wxListEvent_GetLabel, 2870). +-define(wxListEvent_GetText, 2871). +-define(wxListEvent_GetImage, 2872). +-define(wxListEvent_GetData, 2873). +-define(wxListEvent_GetMask, 2874). +-define(wxListEvent_GetItem, 2875). +-define(wxListEvent_IsEditCancelled, 2876). +-define(wxDateEvent_GetDate, 2877). +-define(wxCalendarEvent_GetWeekDay, 2878). +-define(wxFileDirPickerEvent_GetPath, 2879). +-define(wxColourPickerEvent_GetColour, 2880). +-define(wxFontPickerEvent_GetFont, 2881). +-define(wxStyledTextEvent_GetPosition, 2882). +-define(wxStyledTextEvent_GetKey, 2883). +-define(wxStyledTextEvent_GetModifiers, 2884). +-define(wxStyledTextEvent_GetModificationType, 2885). +-define(wxStyledTextEvent_GetText, 2886). +-define(wxStyledTextEvent_GetLength, 2887). +-define(wxStyledTextEvent_GetLinesAdded, 2888). +-define(wxStyledTextEvent_GetLine, 2889). +-define(wxStyledTextEvent_GetFoldLevelNow, 2890). +-define(wxStyledTextEvent_GetFoldLevelPrev, 2891). +-define(wxStyledTextEvent_GetMargin, 2892). +-define(wxStyledTextEvent_GetMessage, 2893). +-define(wxStyledTextEvent_GetWParam, 2894). +-define(wxStyledTextEvent_GetLParam, 2895). +-define(wxStyledTextEvent_GetListType, 2896). +-define(wxStyledTextEvent_GetX, 2897). +-define(wxStyledTextEvent_GetY, 2898). +-define(wxStyledTextEvent_GetDragText, 2899). +-define(wxStyledTextEvent_GetDragAllowMove, 2900). +-define(wxStyledTextEvent_GetDragResult, 2901). +-define(wxStyledTextEvent_GetShift, 2902). +-define(wxStyledTextEvent_GetControl, 2903). +-define(wxStyledTextEvent_GetAlt, 2904). +-define(utils_wxGetKeyState, 2905). +-define(utils_wxGetMousePosition, 2906). +-define(utils_wxGetMouseState, 2907). +-define(utils_wxSetDetectableAutoRepeat, 2908). +-define(utils_wxBell, 2909). +-define(utils_wxFindMenuItemId, 2910). +-define(utils_wxGenericFindWindowAtPoint, 2911). +-define(utils_wxFindWindowAtPoint, 2912). +-define(utils_wxBeginBusyCursor, 2913). +-define(utils_wxEndBusyCursor, 2914). +-define(utils_wxIsBusy, 2915). +-define(utils_wxShutdown, 2916). +-define(utils_wxShell, 2917). +-define(utils_wxLaunchDefaultBrowser, 2918). +-define(utils_wxGetEmailAddress, 2919). +-define(utils_wxGetUserId, 2920). +-define(utils_wxGetHomeDir, 2921). +-define(utils_wxNewId, 2922). +-define(utils_wxRegisterId, 2923). +-define(utils_wxGetCurrentId, 2924). +-define(utils_wxGetOsDescription, 2925). +-define(utils_wxIsPlatformLittleEndian, 2926). +-define(utils_wxIsPlatform64Bit, 2927). +-define(wxPrintout_new, 2928). +-define(wxPrintout_destruct, 2929). +-define(wxPrintout_GetDC, 2930). +-define(wxPrintout_GetPageSizeMM, 2931). +-define(wxPrintout_GetPageSizePixels, 2932). +-define(wxPrintout_GetPaperRectPixels, 2933). +-define(wxPrintout_GetPPIPrinter, 2934). +-define(wxPrintout_GetPPIScreen, 2935). +-define(wxPrintout_GetTitle, 2936). +-define(wxPrintout_IsPreview, 2937). +-define(wxPrintout_FitThisSizeToPaper, 2938). +-define(wxPrintout_FitThisSizeToPage, 2939). +-define(wxPrintout_FitThisSizeToPageMargins, 2940). +-define(wxPrintout_MapScreenSizeToPaper, 2941). +-define(wxPrintout_MapScreenSizeToPage, 2942). +-define(wxPrintout_MapScreenSizeToPageMargins, 2943). +-define(wxPrintout_MapScreenSizeToDevice, 2944). +-define(wxPrintout_GetLogicalPaperRect, 2945). +-define(wxPrintout_GetLogicalPageRect, 2946). +-define(wxPrintout_GetLogicalPageMarginsRect, 2947). +-define(wxPrintout_SetLogicalOrigin, 2948). +-define(wxPrintout_OffsetLogicalOrigin, 2949). +-define(wxStyledTextCtrl_new_2, 2950). +-define(wxStyledTextCtrl_new_0, 2951). +-define(wxStyledTextCtrl_destruct, 2952). +-define(wxStyledTextCtrl_Create, 2953). +-define(wxStyledTextCtrl_AddText, 2954). +-define(wxStyledTextCtrl_AddStyledText, 2955). +-define(wxStyledTextCtrl_InsertText, 2956). +-define(wxStyledTextCtrl_ClearAll, 2957). +-define(wxStyledTextCtrl_ClearDocumentStyle, 2958). +-define(wxStyledTextCtrl_GetLength, 2959). +-define(wxStyledTextCtrl_GetCharAt, 2960). +-define(wxStyledTextCtrl_GetCurrentPos, 2961). +-define(wxStyledTextCtrl_GetAnchor, 2962). +-define(wxStyledTextCtrl_GetStyleAt, 2963). +-define(wxStyledTextCtrl_Redo, 2964). +-define(wxStyledTextCtrl_SetUndoCollection, 2965). +-define(wxStyledTextCtrl_SelectAll, 2966). +-define(wxStyledTextCtrl_SetSavePoint, 2967). +-define(wxStyledTextCtrl_GetStyledText, 2968). +-define(wxStyledTextCtrl_CanRedo, 2969). +-define(wxStyledTextCtrl_MarkerLineFromHandle, 2970). +-define(wxStyledTextCtrl_MarkerDeleteHandle, 2971). +-define(wxStyledTextCtrl_GetUndoCollection, 2972). +-define(wxStyledTextCtrl_GetViewWhiteSpace, 2973). +-define(wxStyledTextCtrl_SetViewWhiteSpace, 2974). +-define(wxStyledTextCtrl_PositionFromPoint, 2975). +-define(wxStyledTextCtrl_PositionFromPointClose, 2976). +-define(wxStyledTextCtrl_GotoLine, 2977). +-define(wxStyledTextCtrl_GotoPos, 2978). +-define(wxStyledTextCtrl_SetAnchor, 2979). +-define(wxStyledTextCtrl_GetCurLine, 2980). +-define(wxStyledTextCtrl_GetEndStyled, 2981). +-define(wxStyledTextCtrl_ConvertEOLs, 2982). +-define(wxStyledTextCtrl_GetEOLMode, 2983). +-define(wxStyledTextCtrl_SetEOLMode, 2984). +-define(wxStyledTextCtrl_StartStyling, 2985). +-define(wxStyledTextCtrl_SetStyling, 2986). +-define(wxStyledTextCtrl_GetBufferedDraw, 2987). +-define(wxStyledTextCtrl_SetBufferedDraw, 2988). +-define(wxStyledTextCtrl_SetTabWidth, 2989). +-define(wxStyledTextCtrl_GetTabWidth, 2990). +-define(wxStyledTextCtrl_SetCodePage, 2991). +-define(wxStyledTextCtrl_MarkerDefine, 2992). +-define(wxStyledTextCtrl_MarkerSetForeground, 2993). +-define(wxStyledTextCtrl_MarkerSetBackground, 2994). +-define(wxStyledTextCtrl_MarkerAdd, 2995). +-define(wxStyledTextCtrl_MarkerDelete, 2996). +-define(wxStyledTextCtrl_MarkerDeleteAll, 2997). +-define(wxStyledTextCtrl_MarkerGet, 2998). +-define(wxStyledTextCtrl_MarkerNext, 2999). +-define(wxStyledTextCtrl_MarkerPrevious, 3000). +-define(wxStyledTextCtrl_MarkerDefineBitmap, 3001). +-define(wxStyledTextCtrl_MarkerAddSet, 3002). +-define(wxStyledTextCtrl_MarkerSetAlpha, 3003). +-define(wxStyledTextCtrl_SetMarginType, 3004). +-define(wxStyledTextCtrl_GetMarginType, 3005). +-define(wxStyledTextCtrl_SetMarginWidth, 3006). +-define(wxStyledTextCtrl_GetMarginWidth, 3007). +-define(wxStyledTextCtrl_SetMarginMask, 3008). +-define(wxStyledTextCtrl_GetMarginMask, 3009). +-define(wxStyledTextCtrl_SetMarginSensitive, 3010). +-define(wxStyledTextCtrl_GetMarginSensitive, 3011). +-define(wxStyledTextCtrl_StyleClearAll, 3012). +-define(wxStyledTextCtrl_StyleSetForeground, 3013). +-define(wxStyledTextCtrl_StyleSetBackground, 3014). +-define(wxStyledTextCtrl_StyleSetBold, 3015). +-define(wxStyledTextCtrl_StyleSetItalic, 3016). +-define(wxStyledTextCtrl_StyleSetSize, 3017). +-define(wxStyledTextCtrl_StyleSetFaceName, 3018). +-define(wxStyledTextCtrl_StyleSetEOLFilled, 3019). +-define(wxStyledTextCtrl_StyleResetDefault, 3020). +-define(wxStyledTextCtrl_StyleSetUnderline, 3021). +-define(wxStyledTextCtrl_StyleSetCase, 3022). +-define(wxStyledTextCtrl_StyleSetHotSpot, 3023). +-define(wxStyledTextCtrl_SetSelForeground, 3024). +-define(wxStyledTextCtrl_SetSelBackground, 3025). +-define(wxStyledTextCtrl_GetSelAlpha, 3026). +-define(wxStyledTextCtrl_SetSelAlpha, 3027). +-define(wxStyledTextCtrl_SetCaretForeground, 3028). +-define(wxStyledTextCtrl_CmdKeyAssign, 3029). +-define(wxStyledTextCtrl_CmdKeyClear, 3030). +-define(wxStyledTextCtrl_CmdKeyClearAll, 3031). +-define(wxStyledTextCtrl_SetStyleBytes, 3032). +-define(wxStyledTextCtrl_StyleSetVisible, 3033). +-define(wxStyledTextCtrl_GetCaretPeriod, 3034). +-define(wxStyledTextCtrl_SetCaretPeriod, 3035). +-define(wxStyledTextCtrl_SetWordChars, 3036). +-define(wxStyledTextCtrl_BeginUndoAction, 3037). +-define(wxStyledTextCtrl_EndUndoAction, 3038). +-define(wxStyledTextCtrl_IndicatorSetStyle, 3039). +-define(wxStyledTextCtrl_IndicatorGetStyle, 3040). +-define(wxStyledTextCtrl_IndicatorSetForeground, 3041). +-define(wxStyledTextCtrl_IndicatorGetForeground, 3042). +-define(wxStyledTextCtrl_SetWhitespaceForeground, 3043). +-define(wxStyledTextCtrl_SetWhitespaceBackground, 3044). +-define(wxStyledTextCtrl_GetStyleBits, 3045). +-define(wxStyledTextCtrl_SetLineState, 3046). +-define(wxStyledTextCtrl_GetLineState, 3047). +-define(wxStyledTextCtrl_GetMaxLineState, 3048). +-define(wxStyledTextCtrl_GetCaretLineVisible, 3049). +-define(wxStyledTextCtrl_SetCaretLineVisible, 3050). +-define(wxStyledTextCtrl_GetCaretLineBackground, 3051). +-define(wxStyledTextCtrl_SetCaretLineBackground, 3052). +-define(wxStyledTextCtrl_AutoCompShow, 3053). +-define(wxStyledTextCtrl_AutoCompCancel, 3054). +-define(wxStyledTextCtrl_AutoCompActive, 3055). +-define(wxStyledTextCtrl_AutoCompPosStart, 3056). +-define(wxStyledTextCtrl_AutoCompComplete, 3057). +-define(wxStyledTextCtrl_AutoCompStops, 3058). +-define(wxStyledTextCtrl_AutoCompSetSeparator, 3059). +-define(wxStyledTextCtrl_AutoCompGetSeparator, 3060). +-define(wxStyledTextCtrl_AutoCompSelect, 3061). +-define(wxStyledTextCtrl_AutoCompSetCancelAtStart, 3062). +-define(wxStyledTextCtrl_AutoCompGetCancelAtStart, 3063). +-define(wxStyledTextCtrl_AutoCompSetFillUps, 3064). +-define(wxStyledTextCtrl_AutoCompSetChooseSingle, 3065). +-define(wxStyledTextCtrl_AutoCompGetChooseSingle, 3066). +-define(wxStyledTextCtrl_AutoCompSetIgnoreCase, 3067). +-define(wxStyledTextCtrl_AutoCompGetIgnoreCase, 3068). +-define(wxStyledTextCtrl_UserListShow, 3069). +-define(wxStyledTextCtrl_AutoCompSetAutoHide, 3070). +-define(wxStyledTextCtrl_AutoCompGetAutoHide, 3071). +-define(wxStyledTextCtrl_AutoCompSetDropRestOfWord, 3072). +-define(wxStyledTextCtrl_AutoCompGetDropRestOfWord, 3073). +-define(wxStyledTextCtrl_RegisterImage, 3074). +-define(wxStyledTextCtrl_ClearRegisteredImages, 3075). +-define(wxStyledTextCtrl_AutoCompGetTypeSeparator, 3076). +-define(wxStyledTextCtrl_AutoCompSetTypeSeparator, 3077). +-define(wxStyledTextCtrl_AutoCompSetMaxWidth, 3078). +-define(wxStyledTextCtrl_AutoCompGetMaxWidth, 3079). +-define(wxStyledTextCtrl_AutoCompSetMaxHeight, 3080). +-define(wxStyledTextCtrl_AutoCompGetMaxHeight, 3081). +-define(wxStyledTextCtrl_SetIndent, 3082). +-define(wxStyledTextCtrl_GetIndent, 3083). +-define(wxStyledTextCtrl_SetUseTabs, 3084). +-define(wxStyledTextCtrl_GetUseTabs, 3085). +-define(wxStyledTextCtrl_SetLineIndentation, 3086). +-define(wxStyledTextCtrl_GetLineIndentation, 3087). +-define(wxStyledTextCtrl_GetLineIndentPosition, 3088). +-define(wxStyledTextCtrl_GetColumn, 3089). +-define(wxStyledTextCtrl_SetUseHorizontalScrollBar, 3090). +-define(wxStyledTextCtrl_GetUseHorizontalScrollBar, 3091). +-define(wxStyledTextCtrl_SetIndentationGuides, 3092). +-define(wxStyledTextCtrl_GetIndentationGuides, 3093). +-define(wxStyledTextCtrl_SetHighlightGuide, 3094). +-define(wxStyledTextCtrl_GetHighlightGuide, 3095). +-define(wxStyledTextCtrl_GetLineEndPosition, 3096). +-define(wxStyledTextCtrl_GetCodePage, 3097). +-define(wxStyledTextCtrl_GetCaretForeground, 3098). +-define(wxStyledTextCtrl_GetReadOnly, 3099). +-define(wxStyledTextCtrl_SetCurrentPos, 3100). +-define(wxStyledTextCtrl_SetSelectionStart, 3101). +-define(wxStyledTextCtrl_GetSelectionStart, 3102). +-define(wxStyledTextCtrl_SetSelectionEnd, 3103). +-define(wxStyledTextCtrl_GetSelectionEnd, 3104). +-define(wxStyledTextCtrl_SetPrintMagnification, 3105). +-define(wxStyledTextCtrl_GetPrintMagnification, 3106). +-define(wxStyledTextCtrl_SetPrintColourMode, 3107). +-define(wxStyledTextCtrl_GetPrintColourMode, 3108). +-define(wxStyledTextCtrl_FindText, 3109). +-define(wxStyledTextCtrl_FormatRange, 3110). +-define(wxStyledTextCtrl_GetFirstVisibleLine, 3111). +-define(wxStyledTextCtrl_GetLine, 3112). +-define(wxStyledTextCtrl_GetLineCount, 3113). +-define(wxStyledTextCtrl_SetMarginLeft, 3114). +-define(wxStyledTextCtrl_GetMarginLeft, 3115). +-define(wxStyledTextCtrl_SetMarginRight, 3116). +-define(wxStyledTextCtrl_GetMarginRight, 3117). +-define(wxStyledTextCtrl_GetModify, 3118). +-define(wxStyledTextCtrl_SetSelection, 3119). +-define(wxStyledTextCtrl_GetSelectedText, 3120). +-define(wxStyledTextCtrl_GetTextRange, 3121). +-define(wxStyledTextCtrl_HideSelection, 3122). +-define(wxStyledTextCtrl_LineFromPosition, 3123). +-define(wxStyledTextCtrl_PositionFromLine, 3124). +-define(wxStyledTextCtrl_LineScroll, 3125). +-define(wxStyledTextCtrl_EnsureCaretVisible, 3126). +-define(wxStyledTextCtrl_ReplaceSelection, 3127). +-define(wxStyledTextCtrl_SetReadOnly, 3128). +-define(wxStyledTextCtrl_CanPaste, 3129). +-define(wxStyledTextCtrl_CanUndo, 3130). +-define(wxStyledTextCtrl_EmptyUndoBuffer, 3131). +-define(wxStyledTextCtrl_Undo, 3132). +-define(wxStyledTextCtrl_Cut, 3133). +-define(wxStyledTextCtrl_Copy, 3134). +-define(wxStyledTextCtrl_Paste, 3135). +-define(wxStyledTextCtrl_Clear, 3136). +-define(wxStyledTextCtrl_SetText, 3137). +-define(wxStyledTextCtrl_GetText, 3138). +-define(wxStyledTextCtrl_GetTextLength, 3139). +-define(wxStyledTextCtrl_GetOvertype, 3140). +-define(wxStyledTextCtrl_SetCaretWidth, 3141). +-define(wxStyledTextCtrl_GetCaretWidth, 3142). +-define(wxStyledTextCtrl_SetTargetStart, 3143). +-define(wxStyledTextCtrl_GetTargetStart, 3144). +-define(wxStyledTextCtrl_SetTargetEnd, 3145). +-define(wxStyledTextCtrl_GetTargetEnd, 3146). +-define(wxStyledTextCtrl_ReplaceTarget, 3147). +-define(wxStyledTextCtrl_SearchInTarget, 3148). +-define(wxStyledTextCtrl_SetSearchFlags, 3149). +-define(wxStyledTextCtrl_GetSearchFlags, 3150). +-define(wxStyledTextCtrl_CallTipShow, 3151). +-define(wxStyledTextCtrl_CallTipCancel, 3152). +-define(wxStyledTextCtrl_CallTipActive, 3153). +-define(wxStyledTextCtrl_CallTipPosAtStart, 3154). +-define(wxStyledTextCtrl_CallTipSetHighlight, 3155). +-define(wxStyledTextCtrl_CallTipSetBackground, 3156). +-define(wxStyledTextCtrl_CallTipSetForeground, 3157). +-define(wxStyledTextCtrl_CallTipSetForegroundHighlight, 3158). +-define(wxStyledTextCtrl_CallTipUseStyle, 3159). +-define(wxStyledTextCtrl_VisibleFromDocLine, 3160). +-define(wxStyledTextCtrl_DocLineFromVisible, 3161). +-define(wxStyledTextCtrl_WrapCount, 3162). +-define(wxStyledTextCtrl_SetFoldLevel, 3163). +-define(wxStyledTextCtrl_GetFoldLevel, 3164). +-define(wxStyledTextCtrl_GetLastChild, 3165). +-define(wxStyledTextCtrl_GetFoldParent, 3166). +-define(wxStyledTextCtrl_ShowLines, 3167). +-define(wxStyledTextCtrl_HideLines, 3168). +-define(wxStyledTextCtrl_GetLineVisible, 3169). +-define(wxStyledTextCtrl_SetFoldExpanded, 3170). +-define(wxStyledTextCtrl_GetFoldExpanded, 3171). +-define(wxStyledTextCtrl_ToggleFold, 3172). +-define(wxStyledTextCtrl_EnsureVisible, 3173). +-define(wxStyledTextCtrl_SetFoldFlags, 3174). +-define(wxStyledTextCtrl_EnsureVisibleEnforcePolicy, 3175). +-define(wxStyledTextCtrl_SetTabIndents, 3176). +-define(wxStyledTextCtrl_GetTabIndents, 3177). +-define(wxStyledTextCtrl_SetBackSpaceUnIndents, 3178). +-define(wxStyledTextCtrl_GetBackSpaceUnIndents, 3179). +-define(wxStyledTextCtrl_SetMouseDwellTime, 3180). +-define(wxStyledTextCtrl_GetMouseDwellTime, 3181). +-define(wxStyledTextCtrl_WordStartPosition, 3182). +-define(wxStyledTextCtrl_WordEndPosition, 3183). +-define(wxStyledTextCtrl_SetWrapMode, 3184). +-define(wxStyledTextCtrl_GetWrapMode, 3185). +-define(wxStyledTextCtrl_SetWrapVisualFlags, 3186). +-define(wxStyledTextCtrl_GetWrapVisualFlags, 3187). +-define(wxStyledTextCtrl_SetWrapVisualFlagsLocation, 3188). +-define(wxStyledTextCtrl_GetWrapVisualFlagsLocation, 3189). +-define(wxStyledTextCtrl_SetWrapStartIndent, 3190). +-define(wxStyledTextCtrl_GetWrapStartIndent, 3191). +-define(wxStyledTextCtrl_SetLayoutCache, 3192). +-define(wxStyledTextCtrl_GetLayoutCache, 3193). +-define(wxStyledTextCtrl_SetScrollWidth, 3194). +-define(wxStyledTextCtrl_GetScrollWidth, 3195). +-define(wxStyledTextCtrl_TextWidth, 3196). +-define(wxStyledTextCtrl_GetEndAtLastLine, 3197). +-define(wxStyledTextCtrl_TextHeight, 3198). +-define(wxStyledTextCtrl_SetUseVerticalScrollBar, 3199). +-define(wxStyledTextCtrl_GetUseVerticalScrollBar, 3200). +-define(wxStyledTextCtrl_AppendText, 3201). +-define(wxStyledTextCtrl_GetTwoPhaseDraw, 3202). +-define(wxStyledTextCtrl_SetTwoPhaseDraw, 3203). +-define(wxStyledTextCtrl_TargetFromSelection, 3204). +-define(wxStyledTextCtrl_LinesJoin, 3205). +-define(wxStyledTextCtrl_LinesSplit, 3206). +-define(wxStyledTextCtrl_SetFoldMarginColour, 3207). +-define(wxStyledTextCtrl_SetFoldMarginHiColour, 3208). +-define(wxStyledTextCtrl_LineDown, 3209). +-define(wxStyledTextCtrl_LineDownExtend, 3210). +-define(wxStyledTextCtrl_LineUp, 3211). +-define(wxStyledTextCtrl_LineUpExtend, 3212). +-define(wxStyledTextCtrl_CharLeft, 3213). +-define(wxStyledTextCtrl_CharLeftExtend, 3214). +-define(wxStyledTextCtrl_CharRight, 3215). +-define(wxStyledTextCtrl_CharRightExtend, 3216). +-define(wxStyledTextCtrl_WordLeft, 3217). +-define(wxStyledTextCtrl_WordLeftExtend, 3218). +-define(wxStyledTextCtrl_WordRight, 3219). +-define(wxStyledTextCtrl_WordRightExtend, 3220). +-define(wxStyledTextCtrl_Home, 3221). +-define(wxStyledTextCtrl_HomeExtend, 3222). +-define(wxStyledTextCtrl_LineEnd, 3223). +-define(wxStyledTextCtrl_LineEndExtend, 3224). +-define(wxStyledTextCtrl_DocumentStart, 3225). +-define(wxStyledTextCtrl_DocumentStartExtend, 3226). +-define(wxStyledTextCtrl_DocumentEnd, 3227). +-define(wxStyledTextCtrl_DocumentEndExtend, 3228). +-define(wxStyledTextCtrl_PageUp, 3229). +-define(wxStyledTextCtrl_PageUpExtend, 3230). +-define(wxStyledTextCtrl_PageDown, 3231). +-define(wxStyledTextCtrl_PageDownExtend, 3232). +-define(wxStyledTextCtrl_EditToggleOvertype, 3233). +-define(wxStyledTextCtrl_Cancel, 3234). +-define(wxStyledTextCtrl_DeleteBack, 3235). +-define(wxStyledTextCtrl_Tab, 3236). +-define(wxStyledTextCtrl_BackTab, 3237). +-define(wxStyledTextCtrl_NewLine, 3238). +-define(wxStyledTextCtrl_FormFeed, 3239). +-define(wxStyledTextCtrl_VCHome, 3240). +-define(wxStyledTextCtrl_VCHomeExtend, 3241). +-define(wxStyledTextCtrl_ZoomIn, 3242). +-define(wxStyledTextCtrl_ZoomOut, 3243). +-define(wxStyledTextCtrl_DelWordLeft, 3244). +-define(wxStyledTextCtrl_DelWordRight, 3245). +-define(wxStyledTextCtrl_LineCut, 3246). +-define(wxStyledTextCtrl_LineDelete, 3247). +-define(wxStyledTextCtrl_LineTranspose, 3248). +-define(wxStyledTextCtrl_LineDuplicate, 3249). +-define(wxStyledTextCtrl_LowerCase, 3250). +-define(wxStyledTextCtrl_UpperCase, 3251). +-define(wxStyledTextCtrl_LineScrollDown, 3252). +-define(wxStyledTextCtrl_LineScrollUp, 3253). +-define(wxStyledTextCtrl_DeleteBackNotLine, 3254). +-define(wxStyledTextCtrl_HomeDisplay, 3255). +-define(wxStyledTextCtrl_HomeDisplayExtend, 3256). +-define(wxStyledTextCtrl_LineEndDisplay, 3257). +-define(wxStyledTextCtrl_LineEndDisplayExtend, 3258). +-define(wxStyledTextCtrl_HomeWrapExtend, 3259). +-define(wxStyledTextCtrl_LineEndWrap, 3260). +-define(wxStyledTextCtrl_LineEndWrapExtend, 3261). +-define(wxStyledTextCtrl_VCHomeWrap, 3262). +-define(wxStyledTextCtrl_VCHomeWrapExtend, 3263). +-define(wxStyledTextCtrl_LineCopy, 3264). +-define(wxStyledTextCtrl_MoveCaretInsideView, 3265). +-define(wxStyledTextCtrl_LineLength, 3266). +-define(wxStyledTextCtrl_BraceHighlight, 3267). +-define(wxStyledTextCtrl_BraceBadLight, 3268). +-define(wxStyledTextCtrl_BraceMatch, 3269). +-define(wxStyledTextCtrl_GetViewEOL, 3270). +-define(wxStyledTextCtrl_SetViewEOL, 3271). +-define(wxStyledTextCtrl_SetModEventMask, 3272). +-define(wxStyledTextCtrl_GetEdgeColumn, 3273). +-define(wxStyledTextCtrl_SetEdgeColumn, 3274). +-define(wxStyledTextCtrl_SetEdgeMode, 3275). +-define(wxStyledTextCtrl_GetEdgeMode, 3276). +-define(wxStyledTextCtrl_GetEdgeColour, 3277). +-define(wxStyledTextCtrl_SetEdgeColour, 3278). +-define(wxStyledTextCtrl_SearchAnchor, 3279). +-define(wxStyledTextCtrl_SearchNext, 3280). +-define(wxStyledTextCtrl_SearchPrev, 3281). +-define(wxStyledTextCtrl_LinesOnScreen, 3282). +-define(wxStyledTextCtrl_UsePopUp, 3283). +-define(wxStyledTextCtrl_SelectionIsRectangle, 3284). +-define(wxStyledTextCtrl_SetZoom, 3285). +-define(wxStyledTextCtrl_GetZoom, 3286). +-define(wxStyledTextCtrl_GetModEventMask, 3287). +-define(wxStyledTextCtrl_SetSTCFocus, 3288). +-define(wxStyledTextCtrl_GetSTCFocus, 3289). +-define(wxStyledTextCtrl_SetStatus, 3290). +-define(wxStyledTextCtrl_GetStatus, 3291). +-define(wxStyledTextCtrl_SetMouseDownCaptures, 3292). +-define(wxStyledTextCtrl_GetMouseDownCaptures, 3293). +-define(wxStyledTextCtrl_SetSTCCursor, 3294). +-define(wxStyledTextCtrl_GetSTCCursor, 3295). +-define(wxStyledTextCtrl_SetControlCharSymbol, 3296). +-define(wxStyledTextCtrl_GetControlCharSymbol, 3297). +-define(wxStyledTextCtrl_WordPartLeft, 3298). +-define(wxStyledTextCtrl_WordPartLeftExtend, 3299). +-define(wxStyledTextCtrl_WordPartRight, 3300). +-define(wxStyledTextCtrl_WordPartRightExtend, 3301). +-define(wxStyledTextCtrl_SetVisiblePolicy, 3302). +-define(wxStyledTextCtrl_DelLineLeft, 3303). +-define(wxStyledTextCtrl_DelLineRight, 3304). +-define(wxStyledTextCtrl_GetXOffset, 3305). +-define(wxStyledTextCtrl_ChooseCaretX, 3306). +-define(wxStyledTextCtrl_SetXCaretPolicy, 3307). +-define(wxStyledTextCtrl_SetYCaretPolicy, 3308). +-define(wxStyledTextCtrl_GetPrintWrapMode, 3309). +-define(wxStyledTextCtrl_SetHotspotActiveForeground, 3310). +-define(wxStyledTextCtrl_SetHotspotActiveBackground, 3311). +-define(wxStyledTextCtrl_SetHotspotActiveUnderline, 3312). +-define(wxStyledTextCtrl_SetHotspotSingleLine, 3313). +-define(wxStyledTextCtrl_ParaDownExtend, 3314). +-define(wxStyledTextCtrl_ParaUp, 3315). +-define(wxStyledTextCtrl_ParaUpExtend, 3316). +-define(wxStyledTextCtrl_PositionBefore, 3317). +-define(wxStyledTextCtrl_PositionAfter, 3318). +-define(wxStyledTextCtrl_CopyRange, 3319). +-define(wxStyledTextCtrl_CopyText, 3320). +-define(wxStyledTextCtrl_SetSelectionMode, 3321). +-define(wxStyledTextCtrl_GetSelectionMode, 3322). +-define(wxStyledTextCtrl_LineDownRectExtend, 3323). +-define(wxStyledTextCtrl_LineUpRectExtend, 3324). +-define(wxStyledTextCtrl_CharLeftRectExtend, 3325). +-define(wxStyledTextCtrl_CharRightRectExtend, 3326). +-define(wxStyledTextCtrl_HomeRectExtend, 3327). +-define(wxStyledTextCtrl_VCHomeRectExtend, 3328). +-define(wxStyledTextCtrl_LineEndRectExtend, 3329). +-define(wxStyledTextCtrl_PageUpRectExtend, 3330). +-define(wxStyledTextCtrl_PageDownRectExtend, 3331). +-define(wxStyledTextCtrl_StutteredPageUp, 3332). +-define(wxStyledTextCtrl_StutteredPageUpExtend, 3333). +-define(wxStyledTextCtrl_StutteredPageDown, 3334). +-define(wxStyledTextCtrl_StutteredPageDownExtend, 3335). +-define(wxStyledTextCtrl_WordLeftEnd, 3336). +-define(wxStyledTextCtrl_WordLeftEndExtend, 3337). +-define(wxStyledTextCtrl_WordRightEnd, 3338). +-define(wxStyledTextCtrl_WordRightEndExtend, 3339). +-define(wxStyledTextCtrl_SetWhitespaceChars, 3340). +-define(wxStyledTextCtrl_SetCharsDefault, 3341). +-define(wxStyledTextCtrl_AutoCompGetCurrent, 3342). +-define(wxStyledTextCtrl_Allocate, 3343). +-define(wxStyledTextCtrl_FindColumn, 3344). +-define(wxStyledTextCtrl_GetCaretSticky, 3345). +-define(wxStyledTextCtrl_SetCaretSticky, 3346). +-define(wxStyledTextCtrl_ToggleCaretSticky, 3347). +-define(wxStyledTextCtrl_SetPasteConvertEndings, 3348). +-define(wxStyledTextCtrl_GetPasteConvertEndings, 3349). +-define(wxStyledTextCtrl_SelectionDuplicate, 3350). +-define(wxStyledTextCtrl_SetCaretLineBackAlpha, 3351). +-define(wxStyledTextCtrl_GetCaretLineBackAlpha, 3352). +-define(wxStyledTextCtrl_StartRecord, 3353). +-define(wxStyledTextCtrl_StopRecord, 3354). +-define(wxStyledTextCtrl_SetLexer, 3355). +-define(wxStyledTextCtrl_GetLexer, 3356). +-define(wxStyledTextCtrl_Colourise, 3357). +-define(wxStyledTextCtrl_SetProperty, 3358). +-define(wxStyledTextCtrl_SetKeyWords, 3359). +-define(wxStyledTextCtrl_SetLexerLanguage, 3360). +-define(wxStyledTextCtrl_GetProperty, 3361). +-define(wxStyledTextCtrl_GetStyleBitsNeeded, 3362). +-define(wxStyledTextCtrl_GetCurrentLine, 3363). +-define(wxStyledTextCtrl_StyleSetSpec, 3364). +-define(wxStyledTextCtrl_StyleSetFont, 3365). +-define(wxStyledTextCtrl_StyleSetFontAttr, 3366). +-define(wxStyledTextCtrl_StyleSetCharacterSet, 3367). +-define(wxStyledTextCtrl_StyleSetFontEncoding, 3368). +-define(wxStyledTextCtrl_CmdKeyExecute, 3369). +-define(wxStyledTextCtrl_SetMargins, 3370). +-define(wxStyledTextCtrl_GetSelection, 3371). +-define(wxStyledTextCtrl_PointFromPosition, 3372). +-define(wxStyledTextCtrl_ScrollToLine, 3373). +-define(wxStyledTextCtrl_ScrollToColumn, 3374). +-define(wxStyledTextCtrl_SetVScrollBar, 3375). +-define(wxStyledTextCtrl_SetHScrollBar, 3376). +-define(wxStyledTextCtrl_GetLastKeydownProcessed, 3377). +-define(wxStyledTextCtrl_SetLastKeydownProcessed, 3378). +-define(wxStyledTextCtrl_SaveFile, 3379). +-define(wxStyledTextCtrl_LoadFile, 3380). +-define(wxStyledTextCtrl_DoDragOver, 3381). +-define(wxStyledTextCtrl_DoDropText, 3382). +-define(wxStyledTextCtrl_GetUseAntiAliasing, 3383). +-define(wxStyledTextCtrl_AddTextRaw, 3384). +-define(wxStyledTextCtrl_InsertTextRaw, 3385). +-define(wxStyledTextCtrl_GetCurLineRaw, 3386). +-define(wxStyledTextCtrl_GetLineRaw, 3387). +-define(wxStyledTextCtrl_GetSelectedTextRaw, 3388). +-define(wxStyledTextCtrl_GetTextRangeRaw, 3389). +-define(wxStyledTextCtrl_SetTextRaw, 3390). +-define(wxStyledTextCtrl_GetTextRaw, 3391). +-define(wxStyledTextCtrl_AppendTextRaw, 3392). +-define(wxArtProvider_GetBitmap, 3393). +-define(wxArtProvider_GetIcon, 3394). +-define(wxTreeEvent_GetKeyCode, 3395). +-define(wxTreeEvent_GetItem, 3396). +-define(wxTreeEvent_GetKeyEvent, 3397). +-define(wxTreeEvent_GetLabel, 3398). +-define(wxTreeEvent_GetOldItem, 3399). +-define(wxTreeEvent_GetPoint, 3400). +-define(wxTreeEvent_IsEditCancelled, 3401). +-define(wxTreeEvent_SetToolTip, 3402). +-define(wxNotebookEvent_GetOldSelection, 3403). +-define(wxNotebookEvent_GetSelection, 3404). +-define(wxNotebookEvent_SetOldSelection, 3405). +-define(wxNotebookEvent_SetSelection, 3406). +-define(wxFileDataObject_new, 3407). +-define(wxFileDataObject_AddFile, 3408). +-define(wxFileDataObject_GetFilenames, 3409). +-define(wxFileDataObject_destroy, 3410). +-define(wxTextDataObject_new, 3411). +-define(wxTextDataObject_GetTextLength, 3412). +-define(wxTextDataObject_GetText, 3413). +-define(wxTextDataObject_SetText, 3414). +-define(wxTextDataObject_destroy, 3415). +-define(wxBitmapDataObject_new_1_1, 3416). +-define(wxBitmapDataObject_new_1_0, 3417). +-define(wxBitmapDataObject_GetBitmap, 3418). +-define(wxBitmapDataObject_SetBitmap, 3419). +-define(wxBitmapDataObject_destroy, 3420). +-define(wxClipboard_new, 3422). +-define(wxClipboard_destruct, 3423). +-define(wxClipboard_AddData, 3424). +-define(wxClipboard_Clear, 3425). +-define(wxClipboard_Close, 3426). +-define(wxClipboard_Flush, 3427). +-define(wxClipboard_GetData, 3428). +-define(wxClipboard_IsOpened, 3429). +-define(wxClipboard_Open, 3430). +-define(wxClipboard_SetData, 3431). +-define(wxClipboard_UsePrimarySelection, 3433). +-define(wxClipboard_IsSupported, 3434). +-define(wxClipboard_Get, 3435). +-define(wxSpinEvent_GetPosition, 3436). +-define(wxSpinEvent_SetPosition, 3437). +-define(wxSplitterWindow_new_0, 3438). +-define(wxSplitterWindow_new_2, 3439). +-define(wxSplitterWindow_destruct, 3440). +-define(wxSplitterWindow_Create, 3441). +-define(wxSplitterWindow_GetMinimumPaneSize, 3442). +-define(wxSplitterWindow_GetSashGravity, 3443). +-define(wxSplitterWindow_GetSashPosition, 3444). +-define(wxSplitterWindow_GetSplitMode, 3445). +-define(wxSplitterWindow_GetWindow1, 3446). +-define(wxSplitterWindow_GetWindow2, 3447). +-define(wxSplitterWindow_Initialize, 3448). +-define(wxSplitterWindow_IsSplit, 3449). +-define(wxSplitterWindow_ReplaceWindow, 3450). +-define(wxSplitterWindow_SetSashGravity, 3451). +-define(wxSplitterWindow_SetSashPosition, 3452). +-define(wxSplitterWindow_SetSashSize, 3453). +-define(wxSplitterWindow_SetMinimumPaneSize, 3454). +-define(wxSplitterWindow_SetSplitMode, 3455). +-define(wxSplitterWindow_SplitHorizontally, 3456). +-define(wxSplitterWindow_SplitVertically, 3457). +-define(wxSplitterWindow_Unsplit, 3458). +-define(wxSplitterWindow_UpdateSize, 3459). +-define(wxSplitterEvent_GetSashPosition, 3460). +-define(wxSplitterEvent_GetX, 3461). +-define(wxSplitterEvent_GetY, 3462). +-define(wxSplitterEvent_GetWindowBeingRemoved, 3463). +-define(wxSplitterEvent_SetSashPosition, 3464). +-define(wxHtmlWindow_new_0, 3465). +-define(wxHtmlWindow_new_2, 3466). +-define(wxHtmlWindow_AppendToPage, 3467). +-define(wxHtmlWindow_GetOpenedAnchor, 3468). +-define(wxHtmlWindow_GetOpenedPage, 3469). +-define(wxHtmlWindow_GetOpenedPageTitle, 3470). +-define(wxHtmlWindow_GetRelatedFrame, 3471). +-define(wxHtmlWindow_HistoryBack, 3472). +-define(wxHtmlWindow_HistoryCanBack, 3473). +-define(wxHtmlWindow_HistoryCanForward, 3474). +-define(wxHtmlWindow_HistoryClear, 3475). +-define(wxHtmlWindow_HistoryForward, 3476). +-define(wxHtmlWindow_LoadFile, 3477). +-define(wxHtmlWindow_LoadPage, 3478). +-define(wxHtmlWindow_SelectAll, 3479). +-define(wxHtmlWindow_SelectionToText, 3480). +-define(wxHtmlWindow_SelectLine, 3481). +-define(wxHtmlWindow_SelectWord, 3482). +-define(wxHtmlWindow_SetBorders, 3483). +-define(wxHtmlWindow_SetFonts, 3484). +-define(wxHtmlWindow_SetPage, 3485). +-define(wxHtmlWindow_SetRelatedFrame, 3486). +-define(wxHtmlWindow_SetRelatedStatusBar, 3487). +-define(wxHtmlWindow_ToText, 3488). +-define(wxHtmlWindow_destroy, 3489). +-define(wxHtmlLinkEvent_GetLinkInfo, 3490). +-define(wxSystemSettings_GetColour, 3491). +-define(wxSystemSettings_GetFont, 3492). +-define(wxSystemSettings_GetMetric, 3493). +-define(wxSystemSettings_GetScreenType, 3494). +-define(wxSystemOptions_GetOption, 3495). +-define(wxSystemOptions_GetOptionInt, 3496). +-define(wxSystemOptions_HasOption, 3497). +-define(wxSystemOptions_IsFalse, 3498). +-define(wxSystemOptions_SetOption_2_1, 3499). +-define(wxSystemOptions_SetOption_2_0, 3500). +-define(wxAuiNotebookEvent_SetSelection, 3501). +-define(wxAuiNotebookEvent_GetSelection, 3502). +-define(wxAuiNotebookEvent_SetOldSelection, 3503). +-define(wxAuiNotebookEvent_GetOldSelection, 3504). +-define(wxAuiNotebookEvent_SetDragSource, 3505). +-define(wxAuiNotebookEvent_GetDragSource, 3506). +-define(wxAuiManagerEvent_SetManager, 3507). +-define(wxAuiManagerEvent_GetManager, 3508). +-define(wxAuiManagerEvent_SetPane, 3509). +-define(wxAuiManagerEvent_GetPane, 3510). +-define(wxAuiManagerEvent_SetButton, 3511). +-define(wxAuiManagerEvent_GetButton, 3512). +-define(wxAuiManagerEvent_SetDC, 3513). +-define(wxAuiManagerEvent_GetDC, 3514). +-define(wxAuiManagerEvent_Veto, 3515). +-define(wxAuiManagerEvent_GetVeto, 3516). +-define(wxAuiManagerEvent_SetCanVeto, 3517). +-define(wxAuiManagerEvent_CanVeto, 3518). +-define(wxLogNull_new, 3519). +-define(wxLogNull_destroy, 3520). +-define(wxTaskBarIcon_new, 3521). +-define(wxTaskBarIcon_destruct, 3522). +-define(wxTaskBarIcon_PopupMenu, 3523). +-define(wxTaskBarIcon_RemoveIcon, 3524). +-define(wxTaskBarIcon_SetIcon, 3525). diff --git a/lib/wx/test/wx_class_SUITE.erl b/lib/wx/test/wx_class_SUITE.erl index 7c3eda0be1..0e151ccc9b 100644 --- a/lib/wx/test/wx_class_SUITE.erl +++ b/lib/wx/test/wx_class_SUITE.erl @@ -50,7 +50,7 @@ suite() -> [{ct_hooks,[ts_install_cth]}]. all() -> [calendarCtrl, treeCtrl, notebook, staticBoxSizer, clipboard, helpFrame, htmlWindow, listCtrlSort, listCtrlVirtual, - radioBox, systemSettings, taskBarIcon]. + radioBox, systemSettings, taskBarIcon, toolbar]. groups() -> []. @@ -493,3 +493,20 @@ taskBarIcon(Config) -> wxTaskBarIcon:connect(TBI, taskbar_left_down, [{callback, fun(Ev,_) -> io:format("Left clicked: ~p~n",[Ev]) end}]), wxTaskBarIcon:connect(TBI, taskbar_right_down, [{callback,fun(Ev,_) -> io:format("Right clicked: ~p~n",[Ev]) end}]), wx_test_lib:wx_destroy(Frame,Config). + +toolbar(TestInfo) when is_atom(TestInfo) -> wx_test_lib:tc_info(TestInfo); +toolbar(Config) -> + Wx = wx:new(), + Frame = wxFrame:new(Wx, ?wxID_ANY, "Frame"), + TB = wxFrame:createToolBar(Frame), + wxToolBar:addTool(TB, 747, "PressMe", wxArtProvider:getBitmap("wxART_COPY", [{size, {16,16}}]), + [{shortHelp, "Press Me"}]), + + Add = fun(#wx{}, _) -> + wxToolBar:addTool(TB, -1, "Added", wxArtProvider:getBitmap("wxART_TICK_MARK", [{size, {16,16}}]), + [{shortHelp, "Test 2 popup text"}]) + end, + + wxFrame:connect(Frame, command_menu_selected, [{callback, Add}, {id, 747}]), + wxFrame:show(Frame), + wx_test_lib:wx_destroy(Frame,Config). diff --git a/lib/wx/test/wx_event_SUITE.erl b/lib/wx/test/wx_event_SUITE.erl index 53a2ee7d7b..f19adb430d 100644 --- a/lib/wx/test/wx_event_SUITE.erl +++ b/lib/wx/test/wx_event_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2012. All Rights Reserved. +%% Copyright Ericsson AB 2008-2013. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -47,7 +47,9 @@ suite() -> [{ct_hooks,[ts_install_cth]}]. all() -> [connect, disconnect, connect_msg_20, connect_cb_20, - mouse_on_grid, spin_event, connect_in_callback, recursive]. + mouse_on_grid, spin_event, connect_in_callback, recursive, + char_events + ]. groups() -> []. @@ -398,3 +400,23 @@ recursive(Config) -> wx_test_lib:flush(), wx_test_lib:wx_destroy(Frame, Config). + + +char_events(TestInfo) when is_atom(TestInfo) -> wx_test_lib:tc_info(TestInfo); +char_events(Config) -> + Wx = wx:new(), + Frame = wxFrame:new(Wx, ?wxID_ANY, "Press any key"), + Panel = wxPanel:new(Frame, []), + wxFrame:connect(Frame, enter_window, [{callback, fun(_,_) -> + io:format("Set focus~n"), + wxWindow:setFocus(Panel) + end}]), + KeyEvent = fun(Ev,Obj) -> io:format("Got ~p~n",[Ev]), wxEvent:skip(Obj) end, + [wxWindow:connect(Panel, Types, [{callback,KeyEvent}]) + || Types <- [key_down, key_up, char]], + wxWindow:connect(Frame, char_hook, [{callback,KeyEvent}]), + + wxFrame:show(Frame), + wx_test_lib:flush(), + + wx_test_lib:wx_destroy(Frame, Config). diff --git a/lib/wx/vsn.mk b/lib/wx/vsn.mk index 1c406ccec6..869ed99f16 100644 --- a/lib/wx/vsn.mk +++ b/lib/wx/vsn.mk @@ -1 +1 @@ -WX_VSN = 1.0 +WX_VSN = 1.1 diff --git a/lib/xmerl/doc/src/notes.xml b/lib/xmerl/doc/src/notes.xml index 90b633d1eb..a126f476bb 100644 --- a/lib/xmerl/doc/src/notes.xml +++ b/lib/xmerl/doc/src/notes.xml @@ -31,6 +31,22 @@ <p>This document describes the changes made to the Xmerl application.</p> +<section><title>Xmerl 1.3.4</title> + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Fixed various typos in xmerl documentation. Thanks to + David Welton.</p> + <p> + Own Id: OTP-11224</p> + </item> + </list> + </section> + +</section> + <section><title>Xmerl 1.3.3</title> <section><title>Improvements and New Features</title> diff --git a/lib/xmerl/src/xmerl_regexp.erl b/lib/xmerl/src/xmerl_regexp.erl index 0c53e6f34a..9303bdb125 100644 --- a/lib/xmerl/src/xmerl_regexp.erl +++ b/lib/xmerl/src/xmerl_regexp.erl @@ -593,7 +593,7 @@ sub_first_match(S, {regexp,RE}) -> nomatch -> nomatch end. - + %% This is the regular expression grammar used. It is equivalent to the %% one used in AWK, except that we allow ^ $ to be used anywhere and fail %% in the matching. @@ -961,7 +961,7 @@ re_apply_or(never_match, R2) -> R2; re_apply_or(R1, never_match) -> R1; re_apply_or(nomatch, R2) -> R2; re_apply_or(R1, nomatch) -> R1. - + %% Record definitions for the NFA, DFA and compiler. -record(nfa_state, {no,edges=[],accept=no}). @@ -1026,7 +1026,7 @@ parse_reas([{RegExp,A}|REAs], S) -> {error,E} -> {error,E} end; parse_reas([], Stack) -> {ok,reverse(Stack)}. - + %% build_combined_nfa(RegExpActionList) -> {NFA,StartState}. %% Build the combined NFA using Thompson's construction straight out %% of the book. Build the separate NFAs in the same order as the @@ -1147,7 +1147,7 @@ nfa_comp_class(Cc) -> comp_crs([{C1,C2}|Crs], Last) -> [{Last,C1-1}|comp_crs(Crs, C2+1)]; comp_crs([], Last) -> [{Last,maxchar}]. - + %% build_dfa(NFA, NfaStartState) -> {DFA,DfaStartState}. %% Build a DFA from an NFA using "subset construction". The major %% difference from the book is that we keep the marked and unmarked @@ -1282,7 +1282,7 @@ accept([St|Sts], NFA) -> #nfa_state{accept=no} -> accept(Sts, NFA) end; accept([], _NFA) -> no. - + %% minimise_dfa(DFA, StartState, FirstState) -> {DFA,StartState}. %% Minimise the DFA by removing equivalent states. We consider a %% state if both the transitions and the their accept state is the @@ -1331,7 +1331,7 @@ pack_dfa([D|DFA], NewN, Rs, PDFA) -> pack_dfa(DFA, NewN+1, [{D#dfa_state.no,NewN}|Rs], [D#dfa_state{no=NewN}|PDFA]); pack_dfa([], _NewN, Rs, PDFA) -> {PDFA,Rs}. - + %% comp_apply(String, StartPos, DFAReg) -> {match,RestPos,Rest} | nomatch. %% Apply the DFA of a regular expression to a string. If %% there is a match return the position of the remaining string and diff --git a/lib/xmerl/vsn.mk b/lib/xmerl/vsn.mk index de809e8ce0..af372d8248 100644 --- a/lib/xmerl/vsn.mk +++ b/lib/xmerl/vsn.mk @@ -1 +1 @@ -XMERL_VSN = 1.3.3 +XMERL_VSN = 1.3.4 diff --git a/system/doc/reference_manual/typespec.xml b/system/doc/reference_manual/typespec.xml index 48df57f71b..635476737d 100644 --- a/system/doc/reference_manual/typespec.xml +++ b/system/doc/reference_manual/typespec.xml @@ -124,6 +124,7 @@ List :: list(Type) %% Proper list ([]-terminated) | improper_list(Type1, Type2) %% Type1=contents, Type2=termination | maybe_improper_list(Type1, Type2) %% Type1 and Type2 as above + | nonempty_list(Type) %% Proper non-empty list Tuple :: tuple() %% stands for a tuple of any size | {} @@ -146,9 +147,8 @@ </p> <p> Because lists are commonly used, they have shorthand type notations. - The type <c>list(T)</c> has the shorthand <c>[T]</c>. - The shorthand <c>[T,...]</c> stands for - the set of non-empty proper lists whose elements are of type <c>T</c>. + The types <c>list(T)</c> and <c>nonempty_list(T)</c> have the shorthands + <c>[T]</c> and <c>[T,...]</c>, respectively. The only difference between the two shorthands is that <c>[T]</c> may be an empty list but <c>[T,...]</c> may not. </p> @@ -160,7 +160,7 @@ <p> For convenience, the following types are also built-in. They can be thought as predefined aliases for the type unions also shown in - the table. (Some type unions below slightly abuse the syntax of types.) + the table. </p> <table> <row> @@ -170,10 +170,10 @@ <cell><c>term()</c></cell><cell><c>any()</c></cell> </row> <row> - <cell><c>binary()</c></cell><cell><c><<_:*8>></c></cell> + <cell><c>binary()</c></cell><cell><c><<_:_*8>></c></cell> </row> <row> - <cell><c>bitstring()</c></cell><cell><c><<_:*1>></c></cell> + <cell><c>bitstring()</c></cell><cell><c><<_:_*1>></c></cell> </row> <row> <cell><c>boolean()</c></cell><cell><c>'false' | 'true'</c></cell> @@ -194,7 +194,7 @@ <cell><c>maybe_improper_list()</c></cell><cell><c>maybe_improper_list(any(), any())</c></cell> </row> <row> - <cell><c>maybe_improper_list(T)</c></cell><cell><c>maybe_improper_list(T, any())</c></cell> + <cell><c>nonempty_list()</c></cell><cell><c>nonempty_list(any())</c></cell> </row> <row> <cell><c>string()</c></cell><cell><c>[char()]</c></cell> @@ -203,13 +203,19 @@ <cell><c>nonempty_string()</c></cell><cell><c>[char(),...]</c></cell> </row> <row> + <cell><c>iodata()</c></cell><cell><c>iolist() | binary()</c></cell> + </row> + <row> <cell><c>iolist()</c></cell><cell><c>maybe_improper_list(byte() | binary() | iolist(), binary() | [])</c></cell> </row> <row> <cell><c>module()</c></cell><cell><c>atom()</c></cell> </row> <row> - <cell><c>mfa()</c></cell><cell><c>{atom(),atom(),byte()}</c></cell> + <cell><c>mfa()</c></cell><cell><c>{atom(),atom(),arity()}</c></cell> + </row> + <row> + <cell><c>arity()</c></cell><cell><c>0..255</c></cell> </row> <row> <cell><c>node()</c></cell><cell><c>atom()</c></cell> @@ -245,24 +251,20 @@ Users are not allowed to define types with the same names as the predefined or built-in ones. This is checked by the compiler and its violation results in a compilation error. - (For bootstrapping purposes, it can also result to just a warning - if this involves a built-in type which has just been introduced.) </p> <note> The following built-in list types also exist, but they are expected to be rarely used. Hence, they have long names: </note> <pre> - nonempty_maybe_improper_list(Type) :: nonempty_maybe_improper_list(Type, any()) - nonempty_maybe_improper_list() :: nonempty_maybe_improper_list(any())</pre> - <p> - where the following two types - define the set of Erlang terms one would expect: - </p> - <pre> + nonempty_maybe_improper_list() :: nonempty_maybe_improper_list(any(), any()) nonempty_improper_list(Type1, Type2) nonempty_maybe_improper_list(Type1, Type2)</pre> <p> + where the last two types + define the set of Erlang terms one would expect. + </p> + <p> Also for convenience, we allow for record notation to be used. Records are just shorthands for the corresponding tuples. </p> diff --git a/system/doc/top/src/erl_html_tools.erl b/system/doc/top/src/erl_html_tools.erl index 1e2b8c86af..73d131ec0b 100644 --- a/system/doc/top/src/erl_html_tools.erl +++ b/system/doc/top/src/erl_html_tools.erl @@ -655,7 +655,7 @@ sub_repl([[{St, L}] |Ss], Fun, Acc0, S, Pos) -> {string:substr(S, Pos+1, St-Pos) ++ Rep ++ Rs, NewAcc}; sub_repl([], _Fun, Acc, S, Pos) -> {string:substr(S, Pos+1), Acc}. - + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Error and warnings |