diff options
258 files changed, 14551 insertions, 12318 deletions
diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000000..596615322f --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +.gitattributes export-ignore +.gitignore export-ignore diff --git a/.gitignore b/.gitignore index aa32bd9582..6034a21f87 100644 --- a/.gitignore +++ b/.gitignore @@ -33,6 +33,7 @@ a.out.dSYM/ /config.status /bootstrap/bin/* +/bootstrap/target !/bootstrap/bin/*.script !/bootstrap/bin/*.boot @@ -142,6 +143,7 @@ a.out.dSYM/ /erts/doc/pdf/*.fo /erts/doc/pdf/*.pdf /erts/doc/man[0-9]/*.[0-9] +/erts/doc/CONF_INFO # et @@ -189,6 +191,11 @@ a.out.dSYM/ /lib/kernel/src/inet_dns_record_adts.hrl +# kernel + +/lib/mnesia/test/Mnesia.* +/lib/mnesia/test/test_log* + # otp_mibs /lib/otp_mibs/include/[A-Z]*.hrl @@ -219,9 +226,6 @@ a.out.dSYM/ # ssl /lib/ssl/pkix/*.asn1db -/lib/ssl/examples/certs/done -/lib/ssl/examples/certs/ebin/make_certs.beam -/lib/ssl/examples/certs/etc/ /lib/ssl/include/OTP-PKIX.hrl /lib/ssl/pkix/OTP-PKIX.erl /lib/ssl/pkix/OTP-PKIX.hrl @@ -261,6 +265,8 @@ a.out.dSYM/ /system/doc/tutorial/cnode.xml /system/doc/tutorial/erl_interface.xml /system/doc/tutorial/example.xml +/system/doc/tutorial/nif.xml +/system/doc/html/installation_guide /system/doc/installation_guide/INSTALL.xml /system/doc/installation_guide/INSTALL-CROSS.xml /system/doc/installation_guide/INSTALL-WIN32.xml diff --git a/configure.in b/configure.in index f9fa34cedf..d0879c6291 100644 --- a/configure.in +++ b/configure.in @@ -97,7 +97,7 @@ fi TARGET=$host AC_SUBST(TARGET) -if test X$cross_compiling = Xyes; then +if test "$cross_compiling" = "yes"; then CROSS_COMPILING=yes else CROSS_COMPILING=no diff --git a/erts/aclocal.m4 b/erts/aclocal.m4 index 0fa3fec244..3b1edd7605 100644 --- a/erts/aclocal.m4 +++ b/erts/aclocal.m4 @@ -521,11 +521,13 @@ if test "X$host_os" = "Xwin32"; then THR_DEFS="-DWIN32_THREADS" THR_LIBS= THR_LIB_NAME=win32_threads + THR_LIB_TYPE=win32_threads else AC_MSG_RESULT(no) THR_DEFS= THR_LIBS= THR_LIB_NAME= + THR_LIB_TYPE=posix_unknown dnl Try to find POSIX threads @@ -586,6 +588,7 @@ dnl On ofs1 the '-pthread' switch should be used AC_MSG_WARN([result yes guessed because of cross compilation]) fi if test $nptl = yes; then + THR_LIB_TYPE=posix_nptl need_nptl_incldir=no AC_CHECK_HEADER(nptl/pthread.h, [need_nptl_incldir=yes @@ -694,6 +697,7 @@ ERL_INTERNAL_LIBS ethr_have_native_atomics=no ethr_have_native_spinlock=no ETHR_THR_LIB_BASE="$THR_LIB_NAME" +ETHR_THR_LIB_BASE_TYPE="$THR_LIB_TYPE" ETHR_DEFS="$THR_DEFS" ETHR_X_LIBS="$THR_LIBS $ERTS_INTERNAL_X_LIBS" ETHR_LIBS= diff --git a/erts/configure.in b/erts/configure.in index 2c15b3ce19..8c6f2ac076 100644 --- a/erts/configure.in +++ b/erts/configure.in @@ -90,6 +90,13 @@ else host_os=$host fi +if test "$cross_compiling" = "yes"; then + CROSS_COMPILING=yes +else + CROSS_COMPILING=no +fi +AC_SUBST(CROSS_COMPILING) + ERL_XCOMP_SYSROOT_INIT AC_ISC_POSIX @@ -201,9 +208,6 @@ AC_ARG_ENABLE(native-libs, AC_ARG_ENABLE(tsp, [ --enable-tsp compile tsp app]) -AC_ARG_ENABLE(elib-malloc, -[ --enable-elib-malloc use elib_malloc instead of normal malloc]) - AC_ARG_ENABLE(fp-exceptions, [ --enable-fp-exceptions Use hardware floating point exceptions (default if hipe enabled)], [ case "$enableval" in @@ -1174,17 +1178,15 @@ else enable_child_waiter_thread=yes ;; linux*) - AC_DEFINE(USE_RECURSIVE_MALLOC_MUTEX,[1], - [Define if malloc should use a recursive mutex]) AC_MSG_CHECKING([whether dlopen() needs to be called before first call to dlerror()]) - if test "x$ETHR_THR_LIB_BASE_NAME" != "xnptl"; then + if test "x$ETHR_THR_LIB_BASE_TYPE" != "xposix_nptl"; then AC_DEFINE(ERTS_NEED_DLOPEN_BEFORE_DLERROR,[1], [Define if dlopen() needs to be called before first call to dlerror()]) AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) fi - if test "x$ETHR_THR_LIB_BASE_NAME" != "xnptl"; then + if test "x$ETHR_THR_LIB_BASE_TYPE" != "xposix_nptl"; then # Child waiter thread cannot be enabled disable_child_waiter_thread=yes enable_child_waiter_thread=no @@ -1717,6 +1719,9 @@ AC_CHECK_FUNCS([ieee_handler fpsetmask finite isnan isinf res_gethostbyname dlop gethrtime localtime_r gmtime_r mmap mremap memcpy mallopt \ sbrk _sbrk __sbrk brk _brk __brk \ flockfile fstat strlcpy strlcat setsid posix2time setlocale nl_langinfo poll]) + +AC_CHECK_DECLS([posix2time],,,[#include <time.h>]) + if test "X$host" = "Xwin32"; then ac_cv_func_setvbuf_reversed=yes fi @@ -1783,6 +1788,9 @@ AC_CHECK_FUNCS([fdatasync]) dnl Find which C libraries are required to use fdatasync AC_SEARCH_LIBS(fdatasync, [rt]) +AC_CHECK_HEADERS(net/if_dl.h ifaddrs.h) +AC_CHECK_FUNCS([getifaddrs]) + dnl ---------------------------------------------------------------------- dnl Checks for features/quirks in the system that affects Erlang. dnl ---------------------------------------------------------------------- @@ -3004,17 +3012,6 @@ if test "x$HIPE_ENABLED" = "xyes" ; then fi # -# Check if we should use elib_malloc. -# - -if test X${enable_elib_malloc} = Xyes; then - AC_DEFINE(ENABLE_ELIB_MALLOC,[],[Define to enable use of elib_malloc (a malloc() replacement)]) - AC_DEFINE(ELIB_HEAP_SBRK,[],[Elib sbrk]) - AC_DEFINE(ELIB_ALLOC_IS_CLIB,[],[Use elib malloc as clib]) - AC_DEFINE(ELIB_SORTED_BLOCKS,[],[Define to enable the use of sorted blocks when using elib_malloc]) -fi - -# # Check for working poll(). # AC_MSG_CHECKING([for working poll()]) @@ -3430,7 +3427,6 @@ AC_SUBST(SSL_LINK_WITH_KERBEROS) AC_SUBST(STATIC_KERBEROS_LIBS) AC_SUBST(SSL_LINK_WITH_ZLIB) AC_SUBST(STATIC_ZLIB_LIBS) -AC_SUBST(OPENSSL_CMD) std_ssl_locations="/usr/local /usr/sfw /opt/local /usr /usr/pkg /usr/local/openssl /usr/lib/openssl /usr/openssl /usr/local/ssl /usr/lib/ssl /usr/ssl" @@ -3622,21 +3618,6 @@ case "$erl_xcomp_without_sysroot-$with_ssl" in SSL_DYNAMIC_ONLY=yes fi SSL_BINDIR="$rdir/bin" -dnl Should one use EXEEXT or ac_exeext? - if test -f "$erl_xcomp_sysroot$SSL_BINDIR/openssl$EXEEXT"; then - if test "$cross_compiling" = "yes"; then - dnl Cannot test it; hope it is working... - OPENSSL_CMD="$SSL_BINDIR/openssl" - else - if "$SSL_BINDIR/openssl" version > /dev/null 2>&1; then - OPENSSL_CMD="$SSL_BINDIR/openssl" - else - is_real_ssl=no - fi - fi - else - is_real_ssl=no - fi if test "x$is_real_ssl" = "xyes" ; then SSL_INCLUDE="-I$dir/include" old_CPPFLAGS=$CPPFLAGS @@ -3700,7 +3681,6 @@ dnl Should one use EXEEXT or ac_exeext? SSL_RUNTIME_LIB="/usr/lib" SSL_LIB="$erl_xcomp_sysroot/usr/lib" SSL_BINDIR="/usr/sbin" - OPENSSL_CMD="$SSL_BINDIR/openssl" dnl OpenBSD requires us to link with -L and -l SSL_DYNAMIC_ONLY="yes" fi @@ -3786,7 +3766,6 @@ dnl so it is - be adoptable SSL_DYNAMIC_ONLY=yes fi SSL_INCLUDE="-I$with_ssl/include" - OPENSSL_CMD="$with_ssl/bin/openssl" SSL_APP=ssl CRYPTO_APP=crypto SSH_APP=ssh @@ -4183,7 +4162,6 @@ dnl ../lib/ic/c_src/$host/Makefile:../lib/ic/c_src/Makefile.in ../lib/os_mon/c_src/$host/Makefile:../lib/os_mon/c_src/Makefile.in ../lib/ssl/c_src/$host/Makefile:../lib/ssl/c_src/Makefile.in - ../lib/ssl/examples/certs/$host/Makefile:../lib/ssl/examples/certs/Makefile.in ../lib/crypto/c_src/$host/Makefile:../lib/crypto/c_src/Makefile.in ../lib/orber/c_src/$host/Makefile:../lib/orber/c_src/Makefile.in ../lib/runtime_tools/c_src/$host/Makefile:../lib/runtime_tools/c_src/Makefile.in diff --git a/erts/doc/src/erl.xml b/erts/doc/src/erl.xml index 0e26d62548..e36d0adb0d 100644 --- a/erts/doc/src/erl.xml +++ b/erts/doc/src/erl.xml @@ -685,8 +685,8 @@ <seealso marker="erlang#system_flag_scheduler_bind_type">erlang:system_flag(scheduler_bind_type, default_bind)</seealso>. </p></item> </taglist> - <p>Binding of schedulers are currently only supported on newer - Linux and Solaris systems.</p> + <p>Binding of schedulers is currently only supported on newer + Linux, Solaris, and Windows systems.</p> <p>If no CPU topology is available when the <c>+sbt</c> flag is processed and <c>BindType</c> is any other type than <c>u</c>, the runtime system will fail to start. CPU @@ -831,14 +831,28 @@ <p>For more information, see <seealso marker="erlang#system_flag_cpu_topology">erlang:system_flag(cpu_topology, CpuTopology)</seealso>.</p> </item> + <tag><marker id="+swt"><c>+swt very_low|low|medium|high|very_high</c></marker></tag> + <item> + <p>Set scheduler wakeup threshold. Default is <c>medium</c>. + The threshold determines when to wake up sleeping schedulers + when more work than can be handled by currently awake schedulers + exist. A low threshold will cause earlier wakeups, and a high + threshold will cause later wakeups. Early wakeups will + distribute work over multiple schedulers faster, but work will + more easily bounce between schedulers. + </p> + <p><em>NOTE:</em> This flag may be removed or changed at any time + without prior notice. + </p> + </item> + <tag><marker id="sched_thread_stack_size"><c><![CDATA[+sss size]]></c></marker></tag> + <item> + <p>Suggested stack size, in kilowords, for scheduler threads. + Valid range is 4-8192 kilowords. The default stack size + is OS dependent.</p> + </item> </taglist> </item> - <tag><marker id="sched_thread_stack_size"><c><![CDATA[+sss size]]></c></marker></tag> - <item> - <p>Suggested stack size, in kilowords, for scheduler threads. - Valid range is 4-8192 kilowords. The default stack size - is OS dependent.</p> - </item> <tag><marker id="+t"><c><![CDATA[+t size]]></c></marker></tag> <item> <p>Set the maximum number of atoms the VM can handle. Default is 1048576.</p> diff --git a/erts/doc/src/erl_nif.xml b/erts/doc/src/erl_nif.xml index f7b7b2f346..27887cbdf6 100644 --- a/erts/doc/src/erl_nif.xml +++ b/erts/doc/src/erl_nif.xml @@ -4,7 +4,7 @@ <cref> <header> <copyright> - <year>2001</year><year>2009</year> + <year>2001</year><year>2010</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -34,11 +34,10 @@ <lib>erl_nif</lib> <libsummary>API functions for an Erlang NIF library</libsummary> <description> - <warning><p>The NIF concept was introduced in R13B03 as an - EXPERIMENTAL feature. The interfaces may be changed in any way - in coming releases. The plan is however to lift the experimental label and - maintain interface backward compatibility from R14B.</p> - <p>Incompatible changes in <em>R14A</em>:</p> + <note><p>The NIF concept is officially supported from R14B. NIF source code + written for earlier experimental versions might need adaption to run on R14B.</p> + <p>No incompatible changes between <em>R14B</em> and R14A.</p> + <p>Incompatible changes between <em>R14A</em> and R13B04:</p> <list> <item>Environment argument removed for <c>enif_alloc</c>, <c>enif_realloc</c>, <c>enif_free</c>, <c>enif_alloc_binary</c>, @@ -50,14 +49,14 @@ <item>Module argument added to <c>enif_open_resource_type</c> while changing name spaces of resource types from global to module local.</item> </list> - <p>Incompatible changes in <em>R13B04</em>:</p> + <p>Incompatible changes between <em>R13B04</em> and R13B03:</p> <list> <item>The function prototypes of the NIFs have changed to expect <c>argc</c> and <c>argv</c> arguments. The arity of a NIF is by that no longer limited to 3.</item> <item><c>enif_get_data</c> renamed as <c>enif_priv_data</c>.</item> <item><c>enif_make_string</c> got a third argument for character encoding.</item> </list> - </warning> + </note> <p>A NIF library contains native implementation of some functions of an Erlang module. The native implemented functions (NIFs) are @@ -456,6 +455,10 @@ typedef enum { to return information about the runtime system. Contains currently the exact same content as <seealso marker="erl_driver#ErlDrvSysInfo">ErlDrvSysInfo</seealso>.</p> </item> + <tag><marker id="ErlNifSInt64"/>ErlNifSInt64</tag> + <item><p>A native signed 64-bit integer type.</p></item> + <tag><marker id="ErlNifUInt64"/>ErlNifUInt64</tag> + <item><p>A native unsigned 64-bit integer type.</p></item> </taglist> </section> @@ -571,7 +574,13 @@ typedef enum { <fsummary>Read an integer term</fsummary> <desc><p>Set <c>*ip</c> to the integer value of <c>term</c>. Return true on success or false if <c>term</c> is not an - integer or is outside the bounds of type <c>int</c></p></desc> + integer or is outside the bounds of type <c>int</c>.</p></desc> + </func> + <func><name><ret>int</ret><nametext>enif_get_int64(ErlNifEnv* env, ERL_NIF_TERM term, ErlNifSInt64* ip)</nametext></name> + <fsummary>Read a 64-bit integer term</fsummary> + <desc><p>Set <c>*ip</c> to the integer value of + <c>term</c>. Return true on success or false if <c>term</c> is not an + integer or is outside the bounds of a signed 64-bit integer.</p></desc> </func> <func><name><ret>int</ret><nametext>enif_get_local_pid(ErlNifEnv* env, ERL_NIF_TERM term, ErlNifPid* pid)</nametext></name> <fsummary>Read an local pid term</fsummary> @@ -633,7 +642,12 @@ typedef enum { return true, or return false if <c>term</c> is not an unsigned integer or is outside the bounds of type <c>unsigned int</c>.</p></desc> </func> - + <func><name><ret>int</ret><nametext>enif_get_uint64(ErlNifEnv* env, ERL_NIF_TERM term, ErlNifUInt64* ip)</nametext></name> + <fsummary>Read an unsigned 64-bit integer term.</fsummary> + <desc><p>Set <c>*ip</c> to the unsigned integer value of <c>term</c> and + return true, or return false if <c>term</c> is not an unsigned integer or + is outside the bounds of an unsigned 64-bit integer.</p></desc> + </func> <func><name><ret>int</ret><nametext>enif_get_ulong(ErlNifEnv* env, ERL_NIF_TERM term, unsigned long* ip)</nametext></name> <fsummary>Read an unsigned integer term.</fsummary> <desc><p>Set <c>*ip</c> to the unsigned long integer value of <c>term</c> @@ -758,6 +772,10 @@ typedef enum { <fsummary>Create an integer term</fsummary> <desc><p>Create an integer term.</p></desc> </func> + <func><name><ret>ERL_NIF_TERM</ret><nametext>enif_make_int64(ErlNifEnv* env, ErlNifSInt64 i)</nametext></name> + <fsummary>Create an integer term</fsummary> + <desc><p>Create an integer term from a signed 64-bit integer.</p></desc> + </func> <func><name><ret>ERL_NIF_TERM</ret><nametext>enif_make_list(ErlNifEnv* env, unsigned cnt, ...)</nametext></name> <fsummary>Create a list term.</fsummary> <desc><p>Create an ordinary list term of length <c>cnt</c>. Expects @@ -894,6 +912,10 @@ typedef enum { <fsummary>Create an unsigned integer term</fsummary> <desc><p>Create an integer term from an <c>unsigned int</c>.</p></desc> </func> + <func><name><ret>ERL_NIF_TERM</ret><nametext>enif_make_uint64(ErlNifEnv* env, ErlNifUInt64 i)</nametext></name> + <fsummary>Create an unsigned integer term</fsummary> + <desc><p>Create an integer term from an unsigned 64-bit integer.</p></desc> + </func> <func><name><ret>ERL_NIF_TERM</ret><nametext>enif_make_ulong(ErlNifEnv* env, unsigned long i)</nametext></name> <fsummary>Create an integer term from an unsigned long int</fsummary> <desc><p>Create an integer term from an <c>unsigned long int</c>.</p></desc> @@ -1108,7 +1130,7 @@ typedef enum { </funcs> <section> <title>SEE ALSO</title> - <p><seealso marker="erlang#load_nif-2">load_nif(3)</seealso></p> + <p><seealso marker="erlang#load_nif-2">erlang:load_nif/2</seealso></p> </section> </cref> diff --git a/erts/doc/src/erlang.xml b/erts/doc/src/erlang.xml index 54a0a80536..ce7fde05d9 100644 --- a/erts/doc/src/erlang.xml +++ b/erts/doc/src/erlang.xml @@ -499,7 +499,7 @@ iolist() = [char() | binary() | iolist()] <name>erlang:cancel_timer(TimerRef) -> Time | false</name> <fsummary>Cancel a timer</fsummary> <type> - <v>TimerRef = ref()</v> + <v>TimerRef = reference()</v> <v>Time = int()</v> </type> <desc> @@ -763,7 +763,7 @@ false</pre> <name>erlang:demonitor(MonitorRef) -> true</name> <fsummary>Stop monitoring</fsummary> <type> - <v>MonitorRef = ref()</v> + <v>MonitorRef = reference()</v> </type> <desc> <p>If <c>MonitorRef</c> is a reference which the calling process @@ -803,7 +803,7 @@ false</pre> <name>erlang:demonitor(MonitorRef, OptionList) -> true|false</name> <fsummary>Stop monitoring</fsummary> <type> - <v>MonitorRef = ref()</v> + <v>MonitorRef = reference()</v> <v>OptionList = [Option]</v> <v>Option = flush</v> <v>Option = info</v> @@ -2034,12 +2034,14 @@ os_prompt%</pre> <v>Text = string()</v> </type> <desc> - <warning> - <p>This BIF is still an experimental feature. The interface - may be changed in any way in future releases.</p><p>In - R13B03 the return value on failure was + <note> + <p>In releases older than OTP R14B, NIF's where an + experimental feature. Versions of OTP older than R14B might + have different and possibly incompatible NIF semanticts and + interfaces. For example, in R13B03 the return value on + failure was <c>{error,Reason,Text}</c>.</p> - </warning> + </note> <p>Loads and links a dynamic library containing native implemented functions (NIFs) for a module. <c>Path</c> is a file path to the sharable object/dynamic library file minus @@ -2160,7 +2162,7 @@ os_prompt%</pre> </desc> </func> <func> - <name>make_ref() -> ref()</name> + <name>make_ref() -> reference()</name> <fsummary>Return an almost unique reference</fsummary> <desc> <p>Returns an almost unique reference.</p> @@ -2690,7 +2692,7 @@ os_prompt%</pre> <name>node(Arg) -> Node</name> <fsummary>At which node is a pid, port or reference located</fsummary> <type> - <v>Arg = pid() | port() | ref()</v> + <v>Arg = pid() | port() | reference()</v> <v>Node = node()</v> </type> <desc> @@ -4098,7 +4100,7 @@ os_prompt%</pre> <name>erlang:read_timer(TimerRef) -> int() | false</name> <fsummary>Number of milliseconds remaining for a timer</fsummary> <type> - <v>TimerRef = ref()</v> + <v>TimerRef = reference()</v> </type> <desc> <p><c>TimerRef</c> is a timer reference returned by @@ -4121,7 +4123,7 @@ os_prompt%</pre> <name>erlang:ref_to_list(Ref) -> string()</name> <fsummary>Text representation of a reference</fsummary> <type> - <v>Ref = ref()</v> + <v>Ref = reference()</v> </type> <desc> <p>Returns a string which corresponds to the text @@ -4300,7 +4302,7 @@ true</pre> <v>Dest = pid() | RegName </v> <v> LocalPid = pid() (of a process, alive or dead, on the local node)</v> <v>Msg = term()</v> - <v>TimerRef = ref()</v> + <v>TimerRef = reference()</v> </type> <desc> <p>Starts a timer which will send the message <c>Msg</c> @@ -4513,7 +4515,7 @@ true</pre> </desc> </func> <func> - <name>spawn(Node, Module, Function, ArgumentList) -> pid()</name> + <name>spawn(Node, Module, Function, Args) -> pid()</name> <fsummary>Create a new process with a function as entry point on a given node</fsummary> <type> <v>Node = node()</v> @@ -4829,7 +4831,7 @@ true</pre> <v> LocalPid = pid() (of a process, alive or dead, on the local node)</v> <v> RegName = atom()</v> <v>Msg = term()</v> - <v>TimerRef = ref()</v> + <v>TimerRef = reference()</v> </type> <desc> <p>Starts a timer which will send the message @@ -5175,9 +5177,9 @@ true</pre> schedulers actually have bound as requested, call <seealso marker="#system_info_scheduler_bindings">erlang:system_info(scheduler_bindings)</seealso>. </p> - <p>Schedulers can currently only be bound on newer Linux - and Solaris systems, but more systems will be supported - in the future. + <p>Schedulers can currently only be bound on newer Linux, + Solaris, and Windows systems, but more systems will be + supported in the future. </p> <p>In order for the runtime system to be able to bind schedulers, the CPU topology needs to be known. If the runtime system fails @@ -5364,7 +5366,7 @@ true</pre> <p>Returns <c>{Allocator, Version, Features, Settings}.</c></p> <p>Types:</p> <list type="bulleted"> - <item><c>Allocator = undefined | elib_malloc | glibc</c></item> + <item><c>Allocator = undefined | glibc</c></item> <item><c>Version = [int()]</c></item> <item><c>Features = [atom()]</c></item> <item><c>Settings = [{Subsystem, [{Parameter, Value}]}]</c></item> @@ -5379,7 +5381,7 @@ true</pre> implementation used. If <c>Allocator</c> equals <c>undefined</c>, the <c>malloc()</c> implementation used could not be identified. Currently - <c>elib_malloc</c> and <c>glibc</c> can be identified.</p> + <c>glibc</c> can be identified.</p> </item> <item> <p><c>Version</c> is a list of integers (but not a @@ -5456,6 +5458,16 @@ true</pre> <seealso marker="#system_info_allocator_tuple">erlang:system_info({allocator, Alloc})</seealso>. </p> </item> + <tag><c>build_type</c></tag> + <item> + <p>Returns an atom describing the build type of the runtime + system. This is normally the atom <c>opt</c> for optimized. + Other possible return values are <c>debug</c>, <c>purify</c>, + <c>quantify</c>, <c>purecov</c>, <c>gcov</c>, <c>valgrind</c>, + <c>gprof</c>, and <c>lcnt</c>. Possible return values + may be added and/or removed at any time without prior notice. + </p> + </item> <tag><c>c_compiler_used</c></tag> <item> <p>Returns a two-tuple describing the C compiler used when @@ -5533,7 +5545,7 @@ true</pre> <c>CpuTopology</c> type to change. </p> </item> - <tag><c>{cpu_topology, defined}</c></tag> + <tag><marker id="system_info_cpu_topology_defined"><c>{cpu_topology, defined}</c></marker></tag> <item> <p>Returns the user defined <c>CpuTopology</c>. For more information see the documentation of @@ -5543,12 +5555,14 @@ true</pre> argument. </p> </item> - <tag><c>{cpu_topology, detected}</c></tag> + <tag><marker id="system_info_cpu_topology_detected"><c>{cpu_topology, detected}</c></marker></tag> <item> <p>Returns the automatically detected <c>CpuTopology</c>. The emulator currently only detects the CPU topology on some newer - linux and solaris systems. For more information see the - documentation of the + Linux, Solaris, and Windows systems. On Windows system with + more than 32 logical processors the CPU topology is not detected. + </p> + <p>For more information see the documentation of the <seealso marker="#system_info_cpu_topology">cpu_topology</seealso> argument. </p> @@ -5606,52 +5620,9 @@ true</pre> </item> <tag><c>elib_malloc</c></tag> <item> - <p>If the emulator uses the <c>elib_malloc</c> memory - allocator, a list of two-element tuples containing status - information is returned; otherwise, <c>false</c> is - returned. The list currently contains the following - two-element tuples (all sizes are presented in bytes):</p> - <taglist> - <tag><c>{heap_size, Size}</c></tag> - <item> - <p>Where <c>Size</c> is the current heap size.</p> - </item> - <tag><c>{max_alloced_size, Size}</c></tag> - <item> - <p>Where <c>Size</c> is the maximum amount of memory - allocated on the heap since the emulator started.</p> - </item> - <tag><c>{alloced_size, Size}</c></tag> - <item> - <p>Where <c>Size</c> is the current amount of memory - allocated on the heap.</p> - </item> - <tag><c>{free_size, Size}</c></tag> - <item> - <p>Where <c>Size</c> is the current amount of free - memory on the heap.</p> - </item> - <tag><c>{no_alloced_blocks, No}</c></tag> - <item> - <p>Where <c>No</c> is the current number of allocated - blocks on the heap.</p> - </item> - <tag><c>{no_free_blocks, No}</c></tag> - <item> - <p>Where <c>No</c> is the current number of free blocks - on the heap.</p> - </item> - <tag><c>{smallest_alloced_block, Size}</c></tag> - <item> - <p>Where <c>Size</c> is the size of the smallest - allocated block on the heap.</p> - </item> - <tag><c>{largest_free_block, Size}</c></tag> - <item> - <p>Where <c>Size</c> is the size of the largest free - block on the heap.</p> - </item> - </taglist> + <p>This option will be removed in a future release. + The return value will always be <c>false</c> since + the elib_malloc allocator has been removed.</p> </item> <tag><c>fullsweep_after</c></tag> <item> @@ -5727,11 +5698,34 @@ true</pre> 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><c>logical_processors</c></tag> + <tag><marker id="logical_processors"><c>logical_processors</c></marker></tag> <item> - <p>Returns the number of logical processors detected on the - system as an integer or the atom <c>unknown</c> if the - emulator wasn't able to detect any. + <p>Returns the detected number of logical processors configured + on the system. The return value is either an integer, or + the atom <c>unknown</c> if the emulator wasn't able to + detect logical processors configured. + </p> + </item> + <tag><marker id="logical_processors_available"><c>logical_processors_available</c></marker></tag> + <item> + <p>Returns the detected number of logical processors available to + the Erlang runtime system. The return value is either an + integer, or the atom <c>unknown</c> if the emulator wasn't + able to detect logical processors available. The number + of logical processors available is less than or equal to + the number of <seealso marker="#logical_processors_online">logical + processors online</seealso>. + </p> + </item> + <tag><marker id="logical_processors_online"><c>logical_processors_online</c></marker></tag> + <item> + <p>Returns the detected number of logical processors online on + the system. The return value is either an integer, + or the atom <c>unknown</c> if the emulator wasn't able to + detect logical processors online. The number of logical + processors online is less than or equal to the number of + <seealso marker="#logical_processors">logical processors + configured</seealso>. </p> </item> <tag><c>machine</c></tag> @@ -5936,6 +5930,26 @@ true</pre> <c>get_tcw</c> in "Match Specifications in Erlang", <seealso marker="erts:match_spec#get_tcw">ERTS User's Guide</seealso>.</p> </item> + <tag><marker id="update_cpu_info"><c>update_cpu_info</c></marker></tag> + <item> + <p>The runtime system rereads the CPU information available and + updates its internally stored information about the + <seealso marker="#system_info_cpu_topology_detected">detected CPU + topology</seealso> and the amount of logical processors + <seealso marker="#logical_processors">configured</seealso>, + <seealso marker="#logical_processors_online">online</seealso>, and + <seealso marker="#logical_processors_available">available</seealso>. + If the CPU information has changed since the last time it was read, + the atom <c>changed</c> is returned; otherwise, the atom + <c>unchanged</c> is returned. If the CPU information has changed + you probably want to + <seealso marker="#system_flag_schedulers_online">adjust the amount + of schedulers online</seealso>. You typically want to have as + many schedulers online as + <seealso marker="#logical_processors_available">logical processors + available</seealso>. + </p> + </item> <tag><marker id="system_info_version"><c>version</c></marker></tag> <item> <p>Returns a string containing the version number of the diff --git a/erts/emulator/Makefile.in b/erts/emulator/Makefile.in index 1ea43e38da..903abe6f5c 100644 --- a/erts/emulator/Makefile.in +++ b/erts/emulator/Makefile.in @@ -74,7 +74,7 @@ else ifeq ($(TYPE),gcov) PURIFY = TYPEMARKER = .gcov -TYPE_FLAGS = @DEBUG_CFLAGS@ -DNO_JUMP_TABLE -fprofile-arcs -ftest-coverage -O0 -DERTS_CAN_INLINE=0 -DERTS_INLINE= +TYPE_FLAGS = @DEBUG_CFLAGS@ -DERTS_GCOV -DNO_JUMP_TABLE -fprofile-arcs -ftest-coverage -O0 -DERTS_CAN_INLINE=0 -DERTS_INLINE= ifneq ($(findstring solaris,$(TARGET)),solaris) LIBS += -lgcov endif @@ -293,8 +293,6 @@ endif DEPLIBS += $(ERL_TOP)/erts/emulator/pcre/obj/$(TARGET)/$(TYPE)/$(LIB_PREFIX)epcre$(LIB_SUFFIX) -ELIB_FLAGS = -DENABLE_ELIB_MALLOC -DELIB_ALLOC_IS_CLIB -DELIB_HEAP_SBRK - PERFCTR_PATH=@PERFCTR_PATH@ USE_PERFCTR=@USE_PERFCTR@ ifdef PERFCTR_PATH @@ -653,9 +651,6 @@ $(BINDIR)/$(CS_EXECUTABLE): $(CS_SRC) $(CS_PURIFY) $(CC) $(CS_LDFLAGS) -o $(BINDIR)/$(CS_EXECUTABLE) \ $(CS_CFLAGS) $(COMMON_INCLUDES) $(CS_SRC) $(CS_LIBS) -$(OBJDIR)/%.elib.o: beam/%.c - $(CC) $(ELIB_FLAGS) $(subst -O2, $(GEN_OPT_FLGS), $(CFLAGS)) $(INCLUDES) -c $< -o $@ - $(OBJDIR)/%.kp.o: sys/common/%.c $(CC) -DERTS_KERNEL_POLL_VERSION $(subst -O2, $(GEN_OPT_FLGS), $(CFLAGS)) $(INCLUDES) -c $< -o $@ @@ -762,15 +757,13 @@ OS_OBJS = \ $(OBJDIR)/sys_time.o \ $(OBJDIR)/sys_interrupt.o \ $(OBJDIR)/sys_env.o \ - $(OBJDIR)/dosmap.o \ - $(OBJDIR)/elib_malloc.o + $(OBJDIR)/dosmap.o else OS_OBJS = \ $(OBJDIR)/sys.o \ $(OBJDIR)/driver_tab.o \ $(OBJDIR)/unix_efile.o \ $(OBJDIR)/gzio.o \ - $(OBJDIR)/elib_malloc.o \ $(OBJDIR)/elib_memmove.o ifeq ($(findstring vxworks,$(TARGET)),vxworks) @@ -834,16 +827,6 @@ BASE_OBJS = $(RUN_OBJS) $(EMU_OBJS) $(OS_OBJS) $(EXTRA_BASE_OBJS) OBJS = $(BASE_OBJS) $(DRV_OBJS) -ELIB_C_FILES = beam/elib_malloc.c \ - beam/elib_memmove.c \ - beam/erl_bif_info.c \ - beam/utils.c \ - beam/erl_alloc.c - -MOD_OBJS_ELIB = $(patsubst %.c,$(OBJDIR)/%.o,$(notdir $(ELIB_C_FILES))) -OBJS_ELIB = $(patsubst %.o,%.elib.o,$(MOD_OBJS_ELIB)) \ - $(filter-out $(MOD_OBJS_ELIB),$(OBJS)) - ######################################## # HiPE section @@ -935,10 +918,6 @@ $(BINDIR)/$(EMULATOR_EXECUTABLE): $(INIT_OBJS) $(OBJS) $(DEPLIBS) $(PURIFY) $(LD) -o $(BINDIR)/$(EMULATOR_EXECUTABLE) \ $(HIPEBEAMLDFLAGS) $(LDFLAGS) $(DEXPORT) $(INIT_OBJS) $(OBJS) $(LIBS) -$(BINDIR)/$(EMULATOR_EXECUTABLE_ELIB): $(INIT_OBJS) $(OBJS_ELIB) $(DEPLIBS) - $(PURIFY) $(LD) -o $(BINDIR)/$(EMULATOR_EXECUTABLE_ELIB) \ - $(LDFLAGS) $(DEXPORT) $(INIT_OBJS) $(OBJS_ELIB) $(LIBS) - endif # @@ -1033,7 +1012,7 @@ depend: $(DEP_CC) $(DEP_FLAGS) $(TARGET_SRC) \ | $(SED_DEPEND) >> $(TARGET)/depend.mk ifneq ($(TARGET),win32) - $(DEP_CC) $(DEP_FLAGS) $(ELIB_FLAGS) $(ELIB_C_FILES) \ + $(DEP_CC) $(DEP_FLAGS) $(ELIB_C_FILES) \ | $(SED_ELIB_DEPEND) >> $(TARGET)/depend.mk endif ifdef HIPE_ENABLED diff --git a/erts/emulator/beam/atom.names b/erts/emulator/beam/atom.names index 0815cdbc7f..327620772f 100644 --- a/erts/emulator/beam/atom.names +++ b/erts/emulator/beam/atom.names @@ -119,6 +119,7 @@ atom bsl atom bsr atom bsr_anycrlf atom bsr_unicode +atom build_type atom busy_dist_port atom busy_port atom call @@ -378,6 +379,7 @@ atom old_heap_size atom on_load atom open atom open_error +atom opt atom or atom ordered_set atom orelse diff --git a/erts/emulator/beam/beam_bif_load.c b/erts/emulator/beam/beam_bif_load.c index 4fc271d41c..6ae9736141 100644 --- a/erts/emulator/beam/beam_bif_load.c +++ b/erts/emulator/beam/beam_bif_load.c @@ -337,7 +337,6 @@ BIF_RETTYPE finish_after_on_load_2(BIF_ALIST_2) ep->code[0] == BIF_ARG_1 && ep->code[4] != 0) { ep->address = (void *) ep->code[4]; - ep->code[3] = 0; ep->code[4] = 0; } } diff --git a/erts/emulator/beam/beam_debug.c b/erts/emulator/beam/beam_debug.c index 23b267d5cd..b0bf14b94f 100644 --- a/erts/emulator/beam/beam_debug.c +++ b/erts/emulator/beam/beam_debug.c @@ -125,7 +125,7 @@ erts_debug_breakpoint_2(Process* p, Eterm MFA, Eterm bool) BIF_ERROR(p, BADARG); } -#if 0 /* XXX:PaN - not used */ +#if 0 /* Kept for conveninence when hard debugging. */ void debug_dump_code(BeamInstr *I, int num) { BeamInstr *code_ptr = I; diff --git a/erts/emulator/beam/beam_emu.c b/erts/emulator/beam/beam_emu.c index 260f349563..8a0e12dd4f 100644 --- a/erts/emulator/beam/beam_emu.c +++ b/erts/emulator/beam/beam_emu.c @@ -3390,7 +3390,7 @@ apply_bif_or_nif_epilogue: pb->val = bptr; pb->bytes = (byte*) bptr->orig_bytes; pb->flags = 0; - MSO(c_p).overhead += pb->size / sizeof(Eterm); + OH_OVERHEAD(&(MSO(c_p)), pb->size / sizeof(Eterm)); new_binary = make_binary(pb); goto do_bits_sub_bin; } @@ -3492,7 +3492,7 @@ apply_bif_or_nif_epilogue: pb->bytes = (byte*) bptr->orig_bytes; pb->flags = 0; - MSO(c_p).overhead += tmp_arg1 / sizeof(Eterm); + OH_OVERHEAD(&(MSO(c_p)), tmp_arg1 / sizeof(Eterm)); StoreBifResult(2, make_binary(pb)); } @@ -4373,7 +4373,7 @@ apply_bif_or_nif_epilogue: ASSERT(is_CP((BeamInstr)(ep->code))); ASSERT(is_internal_pid(c_p->tracer_proc) || is_internal_port(c_p->tracer_proc)); - E[2] = make_cp(c_p->cp); /* XXX:PaN - code in lower range on halfword */ + E[2] = make_cp(c_p->cp); /* Code in lower range on halfword */ E[1] = am_true; /* Process tracer */ E[0] = make_cp(ep->code); c_p->cp = (flags & MATCH_SET_EXCEPTION_TRACE) @@ -4889,7 +4889,7 @@ apply_bif_or_nif_epilogue: neg_o_reds = -c_p->def_arg_reg[4]; FCALLS = c_p->fcalls; SWAPIN; - switch( c_p->def_arg_reg[3] ) { /* XXX:PaN - Halfword wont work with hipe yet... */ + switch( c_p->def_arg_reg[3] ) { /* Halfword wont work with hipe yet! */ case HIPE_MODE_SWITCH_RES_RETURN: ASSERT(is_value(reg[0])); MoveReturn(reg[0], r(0)); diff --git a/erts/emulator/beam/beam_load.c b/erts/emulator/beam/beam_load.c index 30f276b95a..df5602b040 100644 --- a/erts/emulator/beam/beam_load.c +++ b/erts/emulator/beam/beam_load.c @@ -1379,8 +1379,10 @@ read_code_header(LoaderState* stp) stp->ci = MI_FUNCTIONS + stp->num_functions + 1; stp->code[MI_ATTR_PTR] = 0; + stp->code[MI_ATTR_SIZE] = 0; stp->code[MI_ATTR_SIZE_ON_HEAP] = 0; stp->code[MI_COMPILE_PTR] = 0; + stp->code[MI_COMPILE_SIZE] = 0; stp->code[MI_COMPILE_SIZE_ON_HEAP] = 0; stp->code[MI_NUM_BREAKPOINTS] = 0; @@ -1566,7 +1568,8 @@ load_code(LoaderState* stp) case 0: /* Floating point number */ { Eterm* hp; -#if !defined(ARCH_64) || HALFWORD_HEAP /* XXX:PaN - Should use ARCH_64 variant instead */ +/* XXX:PaN - Halfword should use ARCH_64 variant instead */ +#if !defined(ARCH_64) || HALFWORD_HEAP Uint high, low; # endif last_op->a[arg].val = new_literal(stp, &hp, @@ -1933,7 +1936,7 @@ load_code(LoaderState* stp) } code[ci++] = (BeamInstr) stp->import[i].bf; break; - case 'P': /* Byte offset into tuple */ /* XXX:PaN - * sizeof(Eterm or Eterm *) ? */ + case 'P': /* Byte offset into tuple */ VerifyTag(stp, tag, TAG_u); tmp = tmp_op->a[arg].val; code[ci++] = (BeamInstr) ((tmp_op->a[arg].val+1) * sizeof(Eterm)); @@ -5198,8 +5201,10 @@ erts_make_stub_module(Process* p, Eterm Mod, Eterm Beam, Eterm Info) code[MI_NUM_FUNCTIONS] = n; code[MI_ATTR_PTR] = 0; + code[MI_ATTR_SIZE] = 0; code[MI_ATTR_SIZE_ON_HEAP] = 0; code[MI_COMPILE_PTR] = 0; + code[MI_COMPILE_SIZE] = 0; code[MI_COMPILE_SIZE_ON_HEAP] = 0; code[MI_NUM_BREAKPOINTS] = 0; code[MI_ON_LOAD_FUNCTION_PTR] = 0; diff --git a/erts/emulator/beam/big.c b/erts/emulator/beam/big.c index 2d250f32cf..ff15d834ab 100644 --- a/erts/emulator/beam/big.c +++ b/erts/emulator/beam/big.c @@ -1881,6 +1881,9 @@ term_to_Uint(Eterm term, Uint *up) int term_to_UWord(Eterm term, UWord *up) { +#if SIZEOF_VOID_P == ERTS_SIZEOF_ETERM + return term_to_Uint(term,up); +#else if (is_small(term)) { Sint i = signed_val(term); if (i < 0) { @@ -1903,7 +1906,47 @@ term_to_UWord(Eterm term, UWord *up) return 0; } while (xl-- > 0) { - uval |= ((Uint)(*xr++)) << n; + uval |= ((UWord)(*xr++)) << n; + n += D_EXP; + } + *up = uval; + return 1; + } else { + *up = BADARG; + return 0; + } +#endif +} + +int +term_to_Uint64(Eterm term, Uint64 *up) +{ +#if SIZEOF_VOID_P == 8 + return term_to_UWord(term,up); +#else + if (is_small(term)) { + Sint i = signed_val(term); + if (i < 0) { + *up = BADARG; + return 0; + } + *up = (Uint64) i; + return 1; + } else if (is_big(term)) { + ErtsDigit* xr = big_v(term); + dsize_t xl = big_size(term); + Uint64 uval = 0; + int n = 0; + + if (big_sign(term)) { + *up = BADARG; + return 0; + } else if (xl*D_EXP > sizeof(Uint64)*8) { + *up = SYSTEM_LIMIT; + return 0; + } + while (xl-- > 0) { + uval |= ((Uint64)(*xr++)) << n; n += D_EXP; } *up = uval; @@ -1912,8 +1955,10 @@ term_to_UWord(Eterm term, UWord *up) *up = BADARG; return 0; } +#endif } + int term_to_Sint(Eterm term, Sint *sp) { if (is_small(term)) { @@ -1948,6 +1993,47 @@ int term_to_Sint(Eterm term, Sint *sp) } } +#if HAVE_INT64 +int term_to_Sint64(Eterm term, Sint64 *sp) +{ +#if ERTS_SIZEOF_ETERM == 8 + return term_to_Sint(term, sp); +#else + if (is_small(term)) { + *sp = signed_val(term); + return 1; + } else if (is_big(term)) { + ErtsDigit* xr = big_v(term); + dsize_t xl = big_size(term); + int sign = big_sign(term); + Uint64 uval = 0; + int n = 0; + + if (xl*D_EXP > sizeof(Uint64)*8) { + return 0; + } + while (xl-- > 0) { + uval |= ((Uint64)(*xr++)) << n; + n += D_EXP; + } + if (sign) { + uval = -uval; + if ((Sint64)uval > 0) + return 0; + } else { + if ((Sint64)uval < 0) + return 0; + } + *sp = uval; + return 1; + } else { + return 0; + } +#endif +} +#endif /* HAVE_INT64 */ + + /* ** Add and subtract */ diff --git a/erts/emulator/beam/big.h b/erts/emulator/beam/big.h index 56f3be372a..25466cd3c2 100644 --- a/erts/emulator/beam/big.h +++ b/erts/emulator/beam/big.h @@ -152,6 +152,10 @@ byte* big_to_bytes(Eterm, byte*); int term_to_Uint(Eterm, Uint*); int term_to_UWord(Eterm, UWord*); int term_to_Sint(Eterm, Sint*); +#if HAVE_INT64 +int term_to_Uint64(Eterm, Uint64*); +int term_to_Sint64(Eterm, Sint64*); +#endif Uint32 big_to_uint32(Eterm b); int term_equals_2pow32(Eterm); diff --git a/erts/emulator/beam/binary.c b/erts/emulator/beam/binary.c index 3fd714f9c2..8ee8fbcb29 100644 --- a/erts/emulator/beam/binary.c +++ b/erts/emulator/beam/binary.c @@ -97,7 +97,7 @@ new_binary(Process *p, byte *buf, int len) /* * Miscellanous updates. Return the tagged binary. */ - MSO(p).overhead += pb->size / sizeof(Eterm); + OH_OVERHEAD(&(MSO(p)), pb->size / sizeof(Eterm)); return make_binary(pb); } @@ -136,7 +136,7 @@ Eterm erts_new_mso_binary(Process *p, byte *buf, int len) /* * Miscellanous updates. Return the tagged binary. */ - MSO(p).overhead += pb->size / sizeof(Eterm); + OH_OVERHEAD(&(MSO(p)), pb->size / sizeof(Eterm)); return make_binary(pb); } diff --git a/erts/emulator/beam/copy.c b/erts/emulator/beam/copy.c index 57be0169ba..8bee47232e 100644 --- a/erts/emulator/beam/copy.c +++ b/erts/emulator/beam/copy.c @@ -317,7 +317,7 @@ copy_struct(Eterm obj, Uint sz, Eterm** hpp, ErlOffHeap* off_heap) pb->next = off_heap->first; pb->flags = 0; off_heap->first = (struct erl_off_heap_header*) pb; - off_heap->overhead += pb->size / sizeof(Eterm); + OH_OVERHEAD(off_heap, pb->size / sizeof(Eterm)); } break; case SUB_BINARY_SUBTAG: @@ -366,7 +366,7 @@ copy_struct(Eterm obj, Uint sz, Eterm** hpp, ErlOffHeap* off_heap) to->next = off_heap->first; to->flags = 0; off_heap->first = (struct erl_off_heap_header*) to; - off_heap->overhead += to->size / sizeof(Eterm); + OH_OVERHEAD(off_heap, to->size / sizeof(Eterm)); } *argp = make_binary(hbot); if (extra_bytes != 0) { @@ -652,7 +652,7 @@ Eterm copy_struct_lazy(Process *from, Eterm orig, Uint offs) erts_refc_inc(&pb->val->refc, 2); pb->next = erts_global_offheap.first; erts_global_offheap.first = pb; - erts_global_offheap.overhead += pb->size / sizeof(Eterm); + OH_OVERHEAD(off_heap, pb->size / sizeof(Eterm)); continue; } @@ -777,7 +777,7 @@ Eterm copy_struct_lazy(Process *from, Eterm orig, Uint offs) to_bin->bytes = from_bin->bytes + sub_offset; to_bin->next = erts_global_offheap.first; erts_global_offheap.first = to_bin; - erts_global_offheap.overhead += to_bin->size / sizeof(Eterm); + OH_OVERHEAD(&erts_global_offheap, to_bin->size / sizeof(Eterm)); res_binary=make_binary(to_bin); hp += PROC_BIN_SIZE; } @@ -912,7 +912,7 @@ copy_shallow(Eterm* ptr, Uint sz, Eterm** hpp, ErlOffHeap* off_heap) { ProcBin* pb = (ProcBin *) (tp-1); erts_refc_inc(&pb->val->refc, 2); - off_heap->overhead += pb->size / sizeof(Eterm); + OH_OVERHEAD(off_heap, pb->size / sizeof(Eterm)); } goto off_heap_common; @@ -977,7 +977,7 @@ void move_multi_frags(Eterm** hpp, ErlOffHeap* off_heap, ErlHeapFragment* first, for (bp=first; bp!=NULL; bp=bp->next) { move_one_frag(hpp, bp->mem, bp->used_size, off_heap); - off_heap->overhead += bp->off_heap.overhead; + OH_OVERHEAD(off_heap, bp->off_heap.overhead); } hp_end = *hpp; for (hp=hp_start; hp<hp_end; ++hp) { diff --git a/erts/emulator/beam/decl.h b/erts/emulator/beam/decl.h deleted file mode 100644 index da1be29d53..0000000000 --- a/erts/emulator/beam/decl.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * %CopyrightBegin% - * - * Copyright Ericsson AB 1996-2009. 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 __DECL_H__ -#define __DECL_H__ - -#if defined(__STDC__) || defined(_MSC_VER) -#define EXTERN_FUNCTION(t, f, x) extern t f x -#define FUNCTION(t, f, x) t f x -#define _DOTS_ ... -#define _VOID_ void -#elif defined(__cplusplus) -#define EXTERN_FUNCTION(f, x) extern "C" { f x } -#define FUNCTION(t, f, x) t f x -#define _DOTS_ ... -#define _VOID_ void -#else -#define EXTERN_FUNCTION(t, f, x) extern t f (/*x*/) -#define FUNCTION(t, f, x) t f (/*x*/) -#define _DOTS_ -#define _VOID_ -#endif - -/* -** Example of declarations -** -** EXTERN_FUNCTION(void, foo, (int, int, char)); -** FUNCTION(void, bar, (int, char)); -** -** struct funcs { -** FUNCTION(int*, (*f1), (int, int)); -** FUNCTION(void, (*f2), (int, char)); -** FUNCTION(void, (*f3), (_VOID_)); -** FUNCTION(int, (*f4), (char*, _DOTS_)); -** }; -** -*/ - -#endif diff --git a/erts/emulator/beam/elib_malloc.c b/erts/emulator/beam/elib_malloc.c deleted file mode 100644 index b18c48d8d6..0000000000 --- a/erts/emulator/beam/elib_malloc.c +++ /dev/null @@ -1,2334 +0,0 @@ -/* - * %CopyrightBegin% - * - * Copyright Ericsson AB 1997-2009. 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% - */ - -/* -** Description: Faster malloc(). -*/ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include "sys.h" - -#ifdef ENABLE_ELIB_MALLOC - -#undef THREAD_SAFE_ELIB_MALLOC -#ifdef USE_THREADS -#define THREAD_SAFE_ELIB_MALLOC 1 -#else -#define THREAD_SAFE_ELIB_MALLOC 0 -#endif - -#include "erl_driver.h" -#include "erl_threads.h" -#include "elib_stat.h" -#include <stdio.h> -#include <stdlib.h> - -/* To avoid clobbering of names becaure of reclaim on VxWorks, - we undefine all possible malloc, calloc etc. */ -#undef malloc -#undef calloc -#undef free -#undef realloc - -#define ELIB_INLINE /* inline all possible functions */ - -#ifndef ELIB_ALIGN -#define ELIB_ALIGN sizeof(double) -#endif - -#ifndef ELIB_HEAP_SIZE -#define ELIB_HEAP_SIZE (64*1024) /* Default 64K */ -#endif - -#ifndef ELIB_HEAP_INCREAMENT -#define ELIB_HEAP_INCREAMENT (32*1024) /* Default 32K */ -#endif - -#ifndef ELIB_FAILURE -#define ELIB_FAILURE abort() -#endif - -#undef ASSERT -#ifdef DEBUG -#define ASSERT(B) \ - ((void) ((B) ? 1 : (fprintf(stderr, "%s:%d: Assertion failed: %s\n", \ - __FILE__, __LINE__, #B), abort(), 0))) -#else -#define ASSERT(B) ((void) 1) -#endif - -#ifndef USE_RECURSIVE_MALLOC_MUTEX -#define USE_RECURSIVE_MALLOC_MUTEX 0 -#endif - -#if USE_RECURSIVE_MALLOC_MUTEX -static erts_mtx_t malloc_mutex = ERTS_REC_MTX_INITER; -#else /* #if USE_RECURSIVE_MALLOC_MUTEX */ -static erts_mtx_t malloc_mutex = ERTS_MTX_INITER; -#if THREAD_SAFE_ELIB_MALLOC -static erts_cnd_t malloc_cond = ERTS_CND_INITER; -#endif -#endif /* #if USE_RECURSIVE_MALLOC_MUTEX */ - -typedef unsigned long EWord; /* Assume 32-bit in this implementation */ -typedef unsigned short EHalfWord; /* Assume 16-bit in this implementation */ -typedef unsigned char EByte; /* Assume 8-bit byte */ - - -#define elib_printf fprintf -#define elib_putc fputc - - -#if defined(__STDC__) || defined(__WIN32__) -#define CONCAT(x,y) x##y -#else -#define CONCAT(x,y) x/**/y -#endif - - -#ifdef ELIB_DEBUG -#define ELIB_PREFIX(fun, args) CONCAT(elib__,fun) args -#else -#define ELIB_PREFIX(fun, args) CONCAT(elib_,fun) args -#endif - -#if defined(__STDC__) -void *ELIB_PREFIX(malloc, (size_t)); -void *ELIB_PREFIX(calloc, (size_t, size_t)); -void ELIB_PREFIX(cfree, (EWord *)); -void ELIB_PREFIX(free, (EWord *)); -void *ELIB_PREFIX(realloc, (EWord *, size_t)); -void* ELIB_PREFIX(memresize, (EWord *, int)); -void* ELIB_PREFIX(memalign, (int, int)); -void* ELIB_PREFIX(valloc, (int)); -void* ELIB_PREFIX(pvalloc, (int)); -int ELIB_PREFIX(memsize, (EWord *)); -/* Extern interfaces used by VxWorks */ -size_t elib_sizeof(void *); -void elib_init(EWord *, EWord); -void elib_force_init(EWord *, EWord); -#endif - -#if defined(__STDC__) -/* define prototypes for missing */ -void* memalign(size_t a, size_t s); -void* pvalloc(size_t nb); -void* memresize(void *p, int nb); -int memsize(void *p); -#endif - -/* bytes to pages */ -#define PAGES(x) (((x)+page_size-1) / page_size) -#define PAGE_ALIGN(p) ((char*)((((EWord)(p))+page_size-1)&~(page_size-1))) - -/* bytes to words */ -#define WORDS(x) (((x)+sizeof(EWord)-1) / sizeof(EWord)) - -/* Align an address */ -#define ALIGN(p) ((EWord*)((((EWord)(p)+ELIB_ALIGN-1)&~(ELIB_ALIGN-1)))) - -/* Calculate the size needed to keep alignment */ - -#define ALIGN_BSZ(nb) ((nb+sizeof(EWord)+ELIB_ALIGN-1) & ~(ELIB_ALIGN-1)) - -#define ALIGN_WSZ(nb) WORDS(ALIGN_BSZ(nb)) - -#define ALIGN_SIZE(nb) (ALIGN_WSZ(nb) - 1) - - -/* PARAMETERS */ - -#if defined(ELIB_HEAP_SBRK) - -#undef PAGE_SIZE - -/* Get the system page size (NEED MORE DEFINES HERE) */ -#ifdef _SC_PAGESIZE -#define PAGE_SIZE sysconf(_SC_PAGESIZE) -#elif defined(_MSC_VER) -# ifdef _M_ALPHA -# define PAGE_SIZE 0x2000 -# else -# define PAGE_SIZE 0x1000 -# endif -#else -#define PAGE_SIZE getpagesize() -#endif - -#define ELIB_EXPAND(need) expand_sbrk(need) -static FUNCTION(int, expand_sbrk, (EWord)); - -#elif defined(ELIB_HEAP_FIXED) - -#define PAGE_SIZE 1024 -#define ELIB_EXPAND(need) -1 -static EWord fix_heap[WORDS(ELIB_HEAP_SIZE)]; - -#elif defined(ELIB_HEAP_USER) - -#define PAGE_SIZE 1024 -#define ELIB_EXPAND(need) -1 - -#else - -#error "ELIB HEAP TYPE NOT SET" - -#endif - - -#define STAT_ALLOCED_BLOCK(SZ) \ -do { \ - tot_allocated += (SZ); \ - if (max_allocated < tot_allocated) \ - max_allocated = tot_allocated; \ -} while (0) - -#define STAT_FREED_BLOCK(SZ) \ -do { \ - tot_allocated -= (SZ); \ -} while (0) - -static int max_allocated = 0; -static int tot_allocated = 0; -static EWord* eheap; /* Align heap start */ -static EWord* eheap_top; /* Point to end of heap */ -EWord page_size = 0; /* Set by elib_init */ - -#if defined(ELIB_DEBUG) || defined(DEBUG) -#define ALIGN_CHECK(a, p) \ - do { \ - if ((EWord)(p) & (a-1)) { \ - elib_printf(stderr, \ - "RUNTIME ERROR: bad alignment (0x%lx:%d:%d)\n", \ - (unsigned long) (p), (int) a, __LINE__); \ - ELIB_FAILURE; \ - } \ - } while(0) -#define ELIB_ALIGN_CHECK(p) ALIGN_CHECK(ELIB_ALIGN, p) -#else -#define ALIGN_CHECK(a, p) -#define ELIB_ALIGN_CHECK(p) -#endif - -#define DYNAMIC 32 - -/* -** Free block layout -** 1 1 30 -** +--------------------------+ -** |F|P| Size | -** +--------------------------+ -** -** Where F is the free bit -** P is the free above bit -** Size is messured in words and does not include the hdr word -** -** If block is on the free list the size is also stored last in the block. -** -*/ -typedef struct _free_block FreeBlock; -struct _free_block { - EWord hdr; - Uint flags; - FreeBlock* parent; - FreeBlock* left; - FreeBlock* right; - EWord v[1]; -}; - -typedef struct _allocated_block { - EWord hdr; - EWord v[5]; -} AllocatedBlock; - - -/* - * Interface to tree routines. - */ -typedef Uint Block_t; - -static Block_t* get_free_block(Uint); -static void link_free_block(Block_t *); -static void unlink_free_block(Block_t *del); - -#define FREE_BIT 0x80000000 -#define FREE_ABOVE_BIT 0x40000000 -#define SIZE_MASK 0x3fffffff /* 2^30 words = 2^32 bytes */ - -/* Work on both FreeBlock and AllocatedBlock */ -#define SIZEOF(p) ((p)->hdr & SIZE_MASK) -#define IS_FREE(p) (((p)->hdr & FREE_BIT) != 0) -#define IS_FREE_ABOVE(p) (((p)->hdr & FREE_ABOVE_BIT) != 0) - -/* Given that we have a free block above find its size */ -#define SIZEOF_ABOVE(p) *(((EWord*) (p)) - 1) - -#define MIN_BLOCK_SIZE (sizeof(FreeBlock)/sizeof(EWord)) -#define MIN_WORD_SIZE (MIN_BLOCK_SIZE-1) -#define MIN_BYTE_SIZE (sizeof(FreeBlock)-sizeof(EWord)) - -#define MIN_ALIGN_SIZE ALIGN_SIZE(MIN_BYTE_SIZE) - - -static AllocatedBlock* heap_head = 0; -static AllocatedBlock* heap_tail = 0; -static EWord eheap_size = 0; - -static int heap_locked; - -static int elib_need_init = 1; -#if THREAD_SAFE_ELIB_MALLOC -static int elib_is_initing = 0; -#endif - -typedef FreeBlock RBTree_t; - -static RBTree_t* root = NULL; - - -static FUNCTION(void, deallocate, (AllocatedBlock*, int)); - -/* - * Unlink a free block - */ - -#define mark_allocated(p, szp) do { \ - (p)->hdr = ((p)->hdr & FREE_ABOVE_BIT) | (szp); \ - (p)->v[szp] &= ~FREE_ABOVE_BIT; \ - } while(0) - -#define mark_free(p, szp) do { \ - (p)->hdr = FREE_BIT | (szp); \ - ((FreeBlock *)p)->v[szp-sizeof(FreeBlock)/sizeof(EWord)+1] = (szp); \ - } while(0) - -#if 0 -/* Help macros to log2 */ -#define LOG_1(x) (((x) > 1) ? 1 : 0) -#define LOG_2(x) (((x) > 3) ? 2+LOG_1((x) >> 2) : LOG_1(x)) -#define LOG_4(x) (((x) > 15) ? 4+LOG_2((x) >> 4) : LOG_2(x)) -#define LOG_8(x) (((x) > 255) ? 8+LOG_4((x)>>8) : LOG_4(x)) -#define LOG_16(x) (((x) > 65535) ? 16+LOG_8((x)>>16) : LOG_8(x)) - -#define log2(x) LOG_16(x) -#endif - -/* - * Split a block to be allocated. - * Mark block as ALLOCATED and clear - * FREE_ABOVE_BIT on next block - * - * nw is SIZE aligned and szp is SIZE aligned + 1 - */ -static void -split_block(FreeBlock* p, EWord nw, EWord szp) -{ - EWord szq; - FreeBlock* q; - - szq = szp - nw; - /* Preserve FREE_ABOVE bit in p->hdr !!! */ - - if (szq >= MIN_ALIGN_SIZE+1) { - szq--; - p->hdr = (p->hdr & FREE_ABOVE_BIT) | nw; - - q = (FreeBlock*) (((EWord*) p) + nw + 1); - mark_free(q, szq); - link_free_block((Block_t *) q); - - q = (FreeBlock*) (((EWord*) q) + szq + 1); - q->hdr |= FREE_ABOVE_BIT; - } - else { - mark_allocated((AllocatedBlock*)p, szp); - } -} - -/* - * Find a free block - */ -static FreeBlock* -alloc_block(EWord nw) -{ - for (;;) { - FreeBlock* p = (FreeBlock *) get_free_block(nw); - - if (p != NULL) { - return p; - } else if (ELIB_EXPAND(nw+MIN_WORD_SIZE)) { - return 0; - } - } -} - - -size_t elib_sizeof(void *p) -{ - AllocatedBlock* pp; - - if (p != 0) { - pp = (AllocatedBlock*) (((char *)p)-1); - return SIZEOF(pp); - } - return 0; -} - -static void locked_elib_init(EWord*, EWord); -static void init_elib_malloc(EWord*, EWord); - -/* -** Initialize the elib -** The addr and sz is only used when compiled with EXPAND_ADDR -*/ -/* Not static, this is used by VxWorks */ -void elib_init(EWord* addr, EWord sz) -{ - if (!elib_need_init) - return; - erts_mtx_lock(&malloc_mutex); - locked_elib_init(addr, sz); - erts_mtx_unlock(&malloc_mutex); -} - -static void locked_elib_init(EWord* addr, EWord sz) -{ - if (!elib_need_init) - return; - -#if THREAD_SAFE_ELIB_MALLOC - -#if !USE_RECURSIVE_MALLOC_MUTEX - { - static erts_tid_t initer_tid; - - if(elib_is_initing) { - - if(erts_equal_tids(initer_tid, erts_thr_self())) - return; - - /* Wait until initializing thread is done with initialization */ - - while(elib_need_init) - erts_cnd_wait(&malloc_cond, &malloc_mutex); - - return; - } - else { - initer_tid = erts_thr_self(); - elib_is_initing = 1; - } - } -#else - if(elib_is_initing) - return; - elib_is_initing = 1; -#endif - -#endif /* #if THREAD_SAFE_ELIB_MALLOC */ - - /* Do the actual initialization of the malloc implementation */ - init_elib_malloc(addr, sz); - -#if THREAD_SAFE_ELIB_MALLOC - -#if !USE_RECURSIVE_MALLOC_MUTEX - erts_mtx_unlock(&malloc_mutex); -#endif - - /* Recursive calls to malloc are allowed here... */ - erts_mtx_set_forksafe(&malloc_mutex); - -#if !USE_RECURSIVE_MALLOC_MUTEX - erts_mtx_lock(&malloc_mutex); - elib_is_initing = 0; -#endif - -#endif /* #if THREAD_SAFE_ELIB_MALLOC */ - - elib_need_init = 0; - -#if THREAD_SAFE_ELIB_MALLOC && !USE_RECURSIVE_MALLOC_MUTEX - erts_cnd_broadcast(&malloc_cond); -#endif - -} - -static void init_elib_malloc(EWord* addr, EWord sz) -{ - int i; - FreeBlock* freep; - EWord tmp_sz; -#ifdef ELIB_HEAP_SBRK - char* top; - EWord n; -#endif - - max_allocated = 0; - tot_allocated = 0; - root = NULL; - - /* Get the page size (may involve system call!!!) */ - page_size = PAGE_SIZE; - -#if defined(ELIB_HEAP_SBRK) - sz = PAGES(ELIB_HEAP_SIZE)*page_size; - - if ((top = (char*) sbrk(0)) == (char*)-1) { - elib_printf(stderr, "could not initialize elib, sbrk(0)"); - ELIB_FAILURE; - } - n = PAGE_ALIGN(top) - top; - if ((top = (char*) sbrk(n)) == (char*)-1) { - elib_printf(stderr, "could not initialize elib, sbrk(n)"); - ELIB_FAILURE; - } - if ((eheap = (EWord*) sbrk(sz)) == (EWord*)-1) { - elib_printf(stderr, "could not initialize elib, sbrk(SIZE)"); - ELIB_FAILURE; - } - sz = WORDS(ELIB_HEAP_SIZE); -#elif defined(ELIB_HEAP_FIXED) - eheap = fix_heap; - sz = WORDS(ELIB_HEAP_SIZE); -#elif defined(ELIB_HEAP_USER) - eheap = addr; - sz = WORDS(sz); -#else - return -1; -#endif - eheap_size = 0; - - /* Make sure that the first word of the heap_head is aligned */ - addr = ALIGN(eheap+1); - sz -= ((addr - 1) - eheap); /* Subtract unusable size */ - eheap_top = eheap = addr - 1; /* Set new aligned heap start */ - - eheap_top[sz-1] = 0; /* Heap stop mark */ - - addr = eheap; - heap_head = (AllocatedBlock*) addr; - heap_head->hdr = MIN_ALIGN_SIZE; - for (i = 0; i < MIN_ALIGN_SIZE; i++) - heap_head->v[i] = 0; - - addr += (MIN_ALIGN_SIZE+1); - freep = (FreeBlock*) addr; - tmp_sz = sz - (((MIN_ALIGN_SIZE+1) + MIN_BLOCK_SIZE) + 1 + 1); - mark_free(freep, tmp_sz); - link_free_block((Block_t *) freep); - - /* No need to align heap tail */ - heap_tail = (AllocatedBlock*) &eheap_top[sz-MIN_BLOCK_SIZE-1]; - heap_tail->hdr = FREE_ABOVE_BIT | MIN_WORD_SIZE; - heap_tail->v[0] = 0; - heap_tail->v[1] = 0; - heap_tail->v[2] = 0; - - eheap_top += sz; - eheap_size += sz; - - heap_locked = 0; -} - -#ifdef ELIB_HEAP_USER -void elib_force_init(EWord* addr, EWord sz) -{ - elib_need_init = 1; - elib_init(addr,sz); -} -#endif - -#ifdef ELIB_HEAP_SBRK - -/* -** need in number of words (should include head and tail words) -*/ -static int expand_sbrk(EWord sz) -{ - EWord* p; - EWord bytes = sz * sizeof(EWord); - EWord size; - AllocatedBlock* tail; - - if (bytes < ELIB_HEAP_SIZE) - size = PAGES(ELIB_HEAP_INCREAMENT)*page_size; - else - size = PAGES(bytes)*page_size; - - if ((p = (EWord*) sbrk(size)) == ((EWord*) -1)) - return -1; - - if (p != eheap_top) { - elib_printf(stderr, "panic: sbrk moved\n"); - ELIB_FAILURE; - } - - sz = WORDS(size); - - /* Set new endof heap marker and a new heap tail */ - eheap_top[sz-1] = 0; - - tail = (AllocatedBlock*) &eheap_top[sz-MIN_BLOCK_SIZE-1]; - tail->hdr = FREE_ABOVE_BIT | MIN_WORD_SIZE; - tail->v[0] = 0; - tail->v[1] = 0; - tail->v[2] = 0; - - /* Patch old tail with new appended size */ - heap_tail->hdr = (heap_tail->hdr & FREE_ABOVE_BIT) | - (MIN_WORD_SIZE+1+(sz-MIN_BLOCK_SIZE-1)); - deallocate(heap_tail, 0); - - heap_tail = tail; - - eheap_size += sz; - eheap_top += sz; - - return 0; -} - -#endif /* ELIB_HEAP_SBRK */ - - -/* -** Scan heap and check for corrupted heap -*/ -int elib_check_heap(void) -{ - AllocatedBlock* p = heap_head; - EWord sz; - - if (heap_locked) { - elib_printf(stderr, "heap is locked no info avaiable\n"); - return 0; - } - - while((sz = SIZEOF(p)) != 0) { - if (IS_FREE(p)) { - if (p->v[sz-1] != sz) { - elib_printf(stderr, "panic: heap corrupted\r\n"); - ELIB_FAILURE; - } - p = (AllocatedBlock*) (p->v + sz); - if (!IS_FREE_ABOVE(p)) { - elib_printf(stderr, "panic: heap corrupted\r\n"); - ELIB_FAILURE; - } - } - else - p = (AllocatedBlock*) (p->v + sz); - } - return 1; -} - -/* -** Load the byte vector pointed to by v of length vsz -** with a heap image -** The scale is defined by vsz and the current heap size -** free = 0, full = 255 -** -** -*/ -int elib_heap_map(EByte* v, int vsz) -{ - AllocatedBlock* p = heap_head; - EWord sz; - int gsz = eheap_size / vsz; /* The granuality used */ - int fsz = 0; - int usz = 0; - - if (gsz == 0) - return -1; /* too good reolution */ - - while((sz = SIZEOF(p)) != 0) { - if (IS_FREE(p)) { - fsz += sz; - if ((fsz + usz) > gsz) { - *v++ = (255*usz)/gsz; - fsz -= (gsz - usz); - usz = 0; - while(fsz >= gsz) { - *v++ = 0; - fsz -= gsz; - } - } - } - else { - usz += sz; - if ((fsz + usz) > gsz) { - *v++ = 255 - (255*fsz)/gsz; - usz -= (gsz - fsz); - fsz = 0; - while(usz >= gsz) { - *v++ = 255; - usz -= gsz; - } - } - } - p = (AllocatedBlock*) (p->v + sz); - } - return 0; -} - -/* -** Generate a histogram of free/allocated blocks -** Count granuality of 10 gives -** (0-10],(10-100],(100-1000],(1000-10000] ... -** (0-2], (2-4], (4-8], (8-16], .... -*/ -static int i_logb(EWord size, int base) -{ - int lg = 0; - while(size >= base) { - size /= base; - lg++; - } - return lg; -} - -int elib_histo(EWord* vf, EWord* va, int vsz, int base) -{ - AllocatedBlock* p = heap_head; - EWord sz; - int i; - int linear; - - if ((vsz <= 1) || (vf == 0 && va == 0)) - return -1; - - if (base < 0) { - linear = 1; - base = -base; - } - else - linear = 0; - - if (base <= 1) - return -1; - - if (vf != 0) { - for (i = 0; i < vsz; i++) - vf[i] = 0; - } - if (va != 0) { - for (i = 0; i < vsz; i++) - va[i] = 0; - } - - while((sz = SIZEOF(p)) != 0) { - if (IS_FREE(p)) { - if (vf != 0) { - int val; - if (linear) - val = sz / base; - else - val = i_logb(sz, base); - if (val >= vsz) - vf[vsz-1]++; - else - vf[val]++; - } - } - else { - if (va != 0) { - int val; - if (linear) - val = sz / base; - else - val = i_logb(sz, base); - if (val >= vsz) - va[vsz-1]++; - else - va[val]++; - } - } - p = (AllocatedBlock*) (p->v + sz); - } - return 0; -} - -/* -** Fill the info structure with actual values -** Total -** Allocated -** Free -** maxMaxFree -*/ -void elib_stat(struct elib_stat* info) -{ - EWord blks = 0; - EWord sz_free = 0; - EWord sz_alloc = 0; - EWord sz_max_free = 0; - EWord sz_min_used = 0x7fffffff; - EWord sz; - EWord num_free = 0; - AllocatedBlock* p = heap_head; - - info->mem_total = eheap_size; - - p = (AllocatedBlock*) (p->v + SIZEOF(p)); - - while((sz = SIZEOF(p)) != 0) { - blks++; - if (IS_FREE(p)) { - if (sz > sz_max_free) - sz_max_free = sz; - sz_free += sz; - ++num_free; - } - else { - if (sz < sz_min_used) - sz_min_used = sz; - sz_alloc += sz; - } - p = (AllocatedBlock*) (p->v + sz); - } - info->mem_blocks = blks; - info->free_blocks = num_free; - info->mem_alloc = sz_alloc; - info->mem_free = sz_free; - info->min_used = sz_min_used; - info->max_free = sz_max_free; - info->mem_max_alloc = max_allocated; - ASSERT(sz_alloc == tot_allocated); -} - -/* -** Dump the heap -*/ -void elib_heap_dump(char* label) -{ - AllocatedBlock* p = heap_head; - EWord sz; - - elib_printf(stderr, "HEAP DUMP (%s)\n", label); - if (!elib_check_heap()) - return; - - while((sz = SIZEOF(p)) != 0) { - if (IS_FREE(p)) { - elib_printf(stderr, "%p: FREE, size = %d\n", p, (int) sz); - } - else { - elib_printf(stderr, "%p: USED, size = %d %s\n", p, (int) sz, - IS_FREE_ABOVE(p)?"(FREE ABOVE)":""); - } - p = (AllocatedBlock*) (p->v + sz); - } -} - -/* -** Scan heaps and count: -** free_size, allocated_size, max_free_block -*/ -void elib_statistics(void* to) -{ - struct elib_stat info; - EWord frag; - - if (!elib_check_heap()) - return; - - elib_stat(&info); - - frag = 1000 - ((1000 * info.max_free) / info.mem_free); - - elib_printf(to, "Heap Statistics: total(%d), blocks(%d), frag(%d.%d%%)\n", - info.mem_total, info.mem_blocks, - (int) frag/10, (int) frag % 10); - - elib_printf(to, " allocated(%d), free(%d), " - "free_blocks(%d)\n", - info.mem_alloc, info.mem_free,info.free_blocks); - elib_printf(to, " max_free(%d), min_used(%d)\n", - info.max_free, info.min_used); -} - -/* -** Allocate a least nb bytes with alignment a -** Algorithm: -** 1) Try locate a block which match exacly among the by direct index. -** 2) Try using a fix block of greater size -** 3) Try locate a block by searching in lists where block sizes -** X may vary between 2^i < X <= 2^(i+1) -** -** Reset memory to zero if clear is true -*/ -static AllocatedBlock* allocate(EWord nb, EWord a, int clear) -{ - FreeBlock* p; - EWord nw; - - if (a == ELIB_ALIGN) { - /* - * Common case: Called by malloc(), realloc(), calloc(). - */ - nw = nb < MIN_BYTE_SIZE ? MIN_ALIGN_SIZE : ALIGN_SIZE(nb); - - if ((p = alloc_block(nw)) == 0) - return NULL; - } else { - /* - * Special case: Called by memalign(). - */ - EWord asz, szp, szq, tmpsz; - FreeBlock *q; - - if ((p = alloc_block((1+MIN_ALIGN_SIZE)*sizeof(EWord)+a-1+nb)) == 0) - return NULL; - - asz = a - ((EWord) ((AllocatedBlock *)p)->v) % a; - - if (asz != a) { - /* Enforce the alignment requirement by cutting of a free - block at the beginning of the block. */ - - if (asz < (1+MIN_ALIGN_SIZE)*sizeof(EWord) && !IS_FREE_ABOVE(p)) { - /* Not enough room to cut of a free block; - increase align size */ - asz += (((1+MIN_ALIGN_SIZE)*sizeof(EWord) + a - 1)/a)*a; - } - - szq = ALIGN_SIZE(asz - sizeof(EWord)); - szp = SIZEOF(p) - szq - 1; - - q = p; - p = (FreeBlock*) (((EWord*) q) + szq + 1); - p->hdr = FREE_ABOVE_BIT | FREE_BIT | szp; - - if (IS_FREE_ABOVE(q)) { /* This should not be possible I think, - but just in case... */ - tmpsz = SIZEOF_ABOVE(q) + 1; - szq += tmpsz; - q = (FreeBlock*) (((EWord*) q) - tmpsz); - unlink_free_block((Block_t *) q); - q->hdr = (q->hdr & FREE_ABOVE_BIT) | FREE_BIT | szq; - } - mark_free(q, szq); - link_free_block((Block_t *) q); - - } /* else already had the correct alignment */ - - nw = nb < MIN_BYTE_SIZE ? MIN_ALIGN_SIZE : ALIGN_SIZE(nb); - } - - split_block(p, nw, SIZEOF(p)); - - STAT_ALLOCED_BLOCK(SIZEOF(p)); - - if (clear) { - EWord* pp = ((AllocatedBlock*)p)->v; - - while(nw--) - *pp++ = 0; - } - - return (AllocatedBlock*) p; -} - - -/* -** Deallocate memory pointed to by p -** 1. Merge with block above if this block is free -** 2. Merge with block below if this block is free -** Link the block to the correct free list -** -** p points to the block header! -** -*/ -static void deallocate(AllocatedBlock* p, int stat_count) -{ - FreeBlock* q; - EWord szq; - EWord szp; - - szp = SIZEOF(p); - - if (stat_count) - STAT_FREED_BLOCK(SIZEOF(p)); - - if (IS_FREE_ABOVE(p)) { - szq = SIZEOF_ABOVE(p); - q = (FreeBlock*) ( ((EWord*) p) - szq - 1); - unlink_free_block((Block_t *) q); - - p = (AllocatedBlock*) q; - szp += (szq + 1); - } - q = (FreeBlock*) (p->v + szp); - if (IS_FREE(q)) { - szq = SIZEOF(q); - unlink_free_block((Block_t *) q); - szp += (szq + 1); - } - else - q->hdr |= FREE_ABOVE_BIT; - - /* The block above p can NEVER be free !!! */ - p->hdr = FREE_BIT | szp; - p->v[szp-1] = szp; - - link_free_block((Block_t *) p); -} - -/* -** Reallocate memory -** If preserve is true then data is moved if neccesary -*/ -static AllocatedBlock* reallocate(AllocatedBlock* p, EWord nb, int preserve) -{ - EWord szp; - EWord szq; - EWord sz; - EWord nw; - FreeBlock* q; - - if (nb < MIN_BYTE_SIZE) - nw = MIN_ALIGN_SIZE; - else - nw = ALIGN_SIZE(nb); - - sz = szp = SIZEOF(p); - - STAT_FREED_BLOCK(szp); - - /* Merge with block below */ - q = (FreeBlock*) (p->v + szp); - if (IS_FREE(q)) { - szq = SIZEOF(q); - unlink_free_block((Block_t *) q); - szp += (szq + 1); - } - - if (nw <= szp) { - split_block((FreeBlock *) p, nw, szp); - STAT_ALLOCED_BLOCK(SIZEOF(p)); - return p; - } - else { - EWord* dp = p->v; - AllocatedBlock* npp; - - if (IS_FREE_ABOVE(p)) { - szq = SIZEOF_ABOVE(p); - if (szq + szp + 1 >= nw) { - q = (FreeBlock*) (((EWord*) p) - szq - 1); - unlink_free_block((Block_t * )q); - szp += (szq + 1); - p = (AllocatedBlock*) q; - - if (preserve) { - EWord* pp = p->v; - while(sz--) - *pp++ = *dp++; - } - split_block((FreeBlock *) p, nw, szp); - STAT_ALLOCED_BLOCK(SIZEOF(p)); - return p; - } - } - - /* - * Update p so that allocate() and deallocate() works. - * (Note that allocate() may call expand_sbrk(), which in - * in turn calls deallocate().) - */ - - p->hdr = (p->hdr & FREE_ABOVE_BIT) | szp; - p->v[szp] &= ~FREE_ABOVE_BIT; - - npp = allocate(nb, ELIB_ALIGN, 0); - if(npp == NULL) - return NULL; - if (preserve) { - EWord* pp = npp->v; - while(sz--) - *pp++ = *dp++; - } - deallocate(p, 0); - return npp; - } -} - -/* -** What malloc() and friends should do (and return) when the heap is -** exhausted. [sverkerw] -*/ -static void* heap_exhausted(void) -{ - /* Choose behaviour */ -#if 0 - /* Crash-and-burn --- leave a usable corpse (hopefully) */ - abort(); -#endif - /* The usual ANSI-compliant behaviour */ - return NULL; -} - -/* -** Allocate size bytes of memory -*/ -void* ELIB_PREFIX(malloc, (size_t nb)) -{ - void *res; - AllocatedBlock* p; - - erts_mtx_lock(&malloc_mutex); - if (elib_need_init) - locked_elib_init(NULL,(EWord)0); - - if (nb == 0) - res = NULL; - else if ((p = allocate(nb, ELIB_ALIGN, 0)) != 0) { - ELIB_ALIGN_CHECK(p->v); - res = p->v; - } - else - res = heap_exhausted(); - - erts_mtx_unlock(&malloc_mutex); - - return res; -} - - -void* ELIB_PREFIX(calloc, (size_t nelem, size_t size)) -{ - void *res; - int nb; - AllocatedBlock* p; - - erts_mtx_lock(&malloc_mutex); - if (elib_need_init) - locked_elib_init(NULL,(EWord)0); - - if ((nb = nelem * size) == 0) - res = NULL; - else if ((p = allocate(nb, ELIB_ALIGN, 1)) != 0) { - ELIB_ALIGN_CHECK(p->v); - res = p->v; - } - else - res = heap_exhausted(); - - erts_mtx_unlock(&malloc_mutex); - - return res; -} - -/* -** Free memory allocated by malloc -*/ - -void ELIB_PREFIX(free, (EWord* p)) -{ - erts_mtx_lock(&malloc_mutex); - if (elib_need_init) - locked_elib_init(NULL,(EWord)0); - - if (p != 0) - deallocate((AllocatedBlock*)(p-1), 1); - - erts_mtx_unlock(&malloc_mutex); -} - -void ELIB_PREFIX(cfree, (EWord* p)) -{ - ELIB_PREFIX(free, (p)); -} - - -/* -** Realloc the memory allocated in p to nb number of bytes -** -*/ - -void* ELIB_PREFIX(realloc, (EWord* p, size_t nb)) -{ - void *res = NULL; - AllocatedBlock* pp; - - erts_mtx_lock(&malloc_mutex); - if (elib_need_init) - locked_elib_init(NULL,(EWord)0); - - if (p != 0) { - pp = (AllocatedBlock*) (p-1); - if (nb > 0) { - if ((pp = reallocate(pp, nb, 1)) != 0) { - ELIB_ALIGN_CHECK(pp->v); - res = pp->v; - } - } - else - deallocate(pp, 1); - } - else if (nb > 0) { - if ((pp = allocate(nb, ELIB_ALIGN, 0)) != 0) { - ELIB_ALIGN_CHECK(pp->v); - res = pp->v; - } - else - res = heap_exhausted(); - } - - erts_mtx_unlock(&malloc_mutex); - - return res; -} - -/* -** Resize the memory area pointed to by p with nb number of bytes -*/ -void* ELIB_PREFIX(memresize, (EWord* p, int nb)) -{ - void *res = NULL; - AllocatedBlock* pp; - - erts_mtx_lock(&malloc_mutex); - if (elib_need_init) - locked_elib_init(NULL,(EWord)0); - - if (p != 0) { - pp = (AllocatedBlock*) (p-1); - if (nb > 0) { - if ((pp = reallocate(pp, nb, 0)) != 0) { - ELIB_ALIGN_CHECK(pp->v); - res = pp->v; - } - } - else - deallocate(pp, 1); - } - else if (nb > 0) { - if ((pp = allocate(nb, ELIB_ALIGN, 0)) != 0) { - ELIB_ALIGN_CHECK(pp->v); - res = pp->v; - } - else - res = heap_exhausted(); - } - - erts_mtx_unlock(&malloc_mutex); - - return res; -} - - -/* Create aligned memory a must be a power of 2 !!! */ - -void* ELIB_PREFIX(memalign, (int a, int nb)) -{ - void *res; - AllocatedBlock* p; - - erts_mtx_lock(&malloc_mutex); - if (elib_need_init) - locked_elib_init(NULL,(EWord)0); - - if (nb == 0 || a <= 0) - res = NULL; - else if ((p = allocate(nb, a, 0)) != 0) { - ALIGN_CHECK(a, p->v); - res = p->v; - } - else - res = heap_exhausted(); - - erts_mtx_unlock(&malloc_mutex); - - return res; -} - -void* ELIB_PREFIX(valloc, (int nb)) -{ - return ELIB_PREFIX(memalign, (page_size, nb)); -} - - -void* ELIB_PREFIX(pvalloc, (int nb)) -{ - return ELIB_PREFIX(memalign, (page_size, PAGES(nb)*page_size)); -} -/* Return memory size for pointer p in bytes */ - -int ELIB_PREFIX(memsize, (p)) -EWord* p; -{ - return SIZEOF((AllocatedBlock*)(p-1))*4; -} - - -/* -** -------------------------------------------------------------------------- -** DEBUG LIBRARY -** -------------------------------------------------------------------------- -*/ - -#ifdef ELIB_DEBUG - -#define IN_HEAP(p) (((p) >= (char*) eheap) && (p) < (char*) eheap_top) -/* -** ptr_to_block: return the pointer to heap block pointed into by ptr -** Returns 0 if not pointing into a block -*/ - -static EWord* ptr_to_block(char* ptr) -{ - AllocatedBlock* p = heap_head; - EWord sz; - - while((sz = SIZEOF(p)) != 0) { - if ((ptr >= (char*) p->v) && (ptr < (char*)(p->v+sz))) - return p->v; - p = (AllocatedBlock*) (p->v + sz); - } - return 0; -} - -/* -** Validate a pointer -** returns: -** 0 - if points to start of a block -** 1 - if points outsize heap -** -1 - if points inside block -** -*/ -static int check_pointer(char* ptr) -{ - if (IN_HEAP(ptr)) { - if (ptr_to_block(ptr) == 0) - return 1; - return 0; - } - return -1; -} - -/* -** Validate a memory area -** returns: -** 0 - if area is included in a block -** -1 - if area overlap a heap block -** 1 - if area is outside heap -*/ -static int check_area(char* ptr, int n) -{ - if (IN_HEAP(ptr)) { - if (IN_HEAP(ptr+n-1)) { - EWord* p1 = ptr_to_block(ptr); - EWord* p2 = ptr_to_block(ptr+n-1); - - if (p1 == p2) - return (p1 == 0) ? -1 : 0; - return -1; - } - } - else if (IN_HEAP(ptr+n-1)) - return -1; - return 1; -} - -/* -** Check if a block write will overwrite heap block -*/ -static void check_write(char* ptr, int n, char* file, int line, char* fun) -{ - if (check_area(ptr, n) == -1) { - elib_printf(stderr, "RUNTIME ERROR: %s heap overwrite\n", fun); - elib_printf(stderr, "File: %s Line: %d\n", file, line); - ELIB_FAILURE; - } -} - -/* -** Check if a pointer is an allocated object -*/ -static void check_allocated_block(char* ptr, char* file, int line, char* fun) -{ - EWord* q; - - if (!IN_HEAP(ptr) || ((q=ptr_to_block(ptr)) == 0) || (ptr != (char*) q)) { - elib_printf(stderr, "RUNTIME ERROR: %s non heap pointer\n", fun); - elib_printf(stderr, "File: %s Line: %d\n", file, line); - ELIB_FAILURE; - } - - if (IS_FREE((AllocatedBlock*)(q-1))) { - elib_printf(stderr, "RUNTIME ERROR: %s free pointer\n", fun); - elib_printf(stderr, "File: %s Line: %d\n", file, line); - ELIB_FAILURE; - } - -} - -/* -** -------------------------------------------------------------------------- -** DEBUG VERSIONS (COMPILED WITH THE ELIB.H) -** -------------------------------------------------------------------------- -*/ - -void* elib_dbg_malloc(int n, char* file, int line) -{ - return elib__malloc(n); -} - -void* elib_dbg_calloc(int n, int s, char* file, int line) -{ - return elib__calloc(n, s); -} - -void* elib_dbg_realloc(EWord* p, int n, char* file, int line) -{ - if (p == 0) - return elib__malloc(n); - check_allocated_block(p, file, line, "elib_realloc"); - return elib__realloc(p, n); -} - -void elib_dbg_free(EWord* p, char* file, int line) -{ - if (p == 0) - return; - check_allocated_block(p, file, line, "elib_free"); - elib__free(p); -} - -void elib_dbg_cfree(EWord* p, char* file, int line) -{ - if (p == 0) - return; - check_allocated_block(p, file, line, "elib_free"); - elib__cfree(p); -} - -void* elib_dbg_memalign(int a, int n, char* file, int line) -{ - return elib__memalign(a, n); -} - -void* elib_dbg_valloc(int n, char* file, int line) -{ - return elib__valloc(n); -} - -void* elib_dbg_pvalloc(int n, char* file, int line) -{ - return elib__pvalloc(n); -} - -void* elib_dbg_memresize(EWord* p, int n, char* file, int line) -{ - if (p == 0) - return elib__malloc(n); - check_allocated_block(p, file, line, "elib_memresize"); - return elib__memresize(p, n); -} - -int elib_dbg_memsize(void* p, char* file, int line) -{ - check_allocated_block(p, file, line, "elib_memsize"); - return elib__memsize(p); -} - -/* -** -------------------------------------------------------------------------- -** LINK TIME FUNCTIONS (NOT COMPILED CALLS) -** -------------------------------------------------------------------------- -*/ - -void* elib_malloc(int n) -{ - return elib_dbg_malloc(n, "", -1); -} - -void* elib_calloc(int n, int s) -{ - return elib_dbg_calloc(n, s, "", -1); -} - -void* elib_realloc(EWord* p, int n) -{ - return elib_dbg_realloc(p, n, "", -1); -} - -void elib_free(EWord* p) -{ - elib_dbg_free(p, "", -1); -} - -void elib_cfree(EWord* p) -{ - elib_dbg_cfree(p, "", -1); -} - -void* elib_memalign(int a, int n) -{ - return elib_dbg_memalign(a, n, "", -1); -} - -void* elib_valloc(int n) -{ - return elib_dbg_valloc(n, "", -1); -} - -void* elib_pvalloc(int n) -{ - return elib_dbg_pvalloc(n, "", -1); -} - -void* elib_memresize(EWord* p, int n) -{ - return elib_dbg_memresize(p, n, "", -1); -} - - -int elib_memsize(EWord* p) -{ - return elib_dbg_memsize(p, "", -1); -} - -#endif /* ELIB_DEBUG */ - -/* -** -------------------------------------------------------------------------- -** Map c library functions to elib -** -------------------------------------------------------------------------- -*/ - -#if defined(ELIB_ALLOC_IS_CLIB) -void* malloc(size_t nb) -{ - return elib_malloc(nb); -} - -void* calloc(size_t nelem, size_t size) -{ - return elib_calloc(nelem, size); -} - - -void free(void *p) -{ - elib_free(p); -} - -void cfree(void *p) -{ - elib_cfree(p); -} - -void* realloc(void* p, size_t nb) -{ - return elib_realloc(p, nb); -} - - -void* memalign(size_t a, size_t s) -{ - return elib_memalign(a, s); -} - -void* valloc(size_t nb) -{ - return elib_valloc(nb); -} - -void* pvalloc(size_t nb) -{ - return elib_pvalloc(nb); -} - -#if 0 -void* memresize(void* p, int nb) -{ - return elib_memresize(p, nb); -} - -int memsize(void* p) -{ - return elib_memsize(p); -} -#endif -#endif /* ELIB_ALLOC_IS_CLIB */ - -#endif /* ENABLE_ELIB_MALLOC */ - -void elib_ensure_initialized(void) -{ -#ifdef ENABLE_ELIB_MALLOC -#ifndef ELIB_DONT_INITIALIZE - elib_init(NULL, 0); -#endif -#endif -} - -#ifdef ENABLE_ELIB_MALLOC -/** - ** A Slightly modified version of the "address order best fit" algorithm - ** used in erl_bestfit_alloc.c. Comments refer to that implementation. - **/ - -/* - * Description: A combined "address order best fit"/"best fit" allocator - * based on a Red-Black (binary search) Tree. The search, - * insert, and delete operations are all O(log n) operations - * on a Red-Black Tree. In the "address order best fit" case - * n equals number of free blocks, and in the "best fit" case - * n equals number of distinct sizes of free blocks. Red-Black - * Trees are described in "Introduction to Algorithms", by - * Thomas H. Cormen, Charles E. Leiserson, and - * Ronald L. Riverest. - * - * This module is a callback-module for erl_alloc_util.c - * - * Author: Rickard Green - */ - -#ifdef DEBUG -#if 0 -#define HARD_DEBUG -#endif -#else -#undef HARD_DEBUG -#endif - -#define SZ_MASK SIZE_MASK -#define FLG_MASK (~(SZ_MASK)) - -#define BLK_SZ(B) (*((Block_t *) (B)) & SZ_MASK) - -#define TREE_NODE_FLG (((Uint) 1) << 0) -#define RED_FLG (((Uint) 1) << 1) -#ifdef HARD_DEBUG -# define LEFT_VISITED_FLG (((Uint) 1) << 2) -# define RIGHT_VISITED_FLG (((Uint) 1) << 3) -#endif - -#define IS_TREE_NODE(N) (((RBTree_t *) (N))->flags & TREE_NODE_FLG) -#define IS_LIST_ELEM(N) (!IS_TREE_NODE(((RBTree_t *) (N)))) - -#define SET_TREE_NODE(N) (((RBTree_t *) (N))->flags |= TREE_NODE_FLG) -#define SET_LIST_ELEM(N) (((RBTree_t *) (N))->flags &= ~TREE_NODE_FLG) - -#define IS_RED(N) (((RBTree_t *) (N)) \ - && ((RBTree_t *) (N))->flags & RED_FLG) -#define IS_BLACK(N) (!IS_RED(((RBTree_t *) (N)))) - -#define SET_RED(N) (((RBTree_t *) (N))->flags |= RED_FLG) -#define SET_BLACK(N) (((RBTree_t *) (N))->flags &= ~RED_FLG) - -#undef ASSERT -#define ASSERT ASSERT_EXPR - -#if 1 -#define RBT_ASSERT ASSERT -#else -#define RBT_ASSERT(x) -#endif - - -#ifdef HARD_DEBUG -static RBTree_t * check_tree(Uint); -#endif - -#ifdef ERTS_INLINE -# ifndef ERTS_CAN_INLINE -# define ERTS_CAN_INLINE 1 -# endif -#else -# if defined(__GNUC__) -# define ERTS_CAN_INLINE 1 -# define ERTS_INLINE __inline__ -# elif defined(__WIN32__) -# define ERTS_CAN_INLINE 1 -# define ERTS_INLINE __inline -# else -# define ERTS_CAN_INLINE 0 -# define ERTS_INLINE -# endif -#endif - -/* Types... */ -#if 0 -typedef struct RBTree_t_ RBTree_t; - -struct RBTree_t_ { - Block_t hdr; - Uint flags; - RBTree_t *parent; - RBTree_t *left; - RBTree_t *right; -}; -#endif - -#if 0 -typedef struct { - RBTree_t t; - RBTree_t *next; -} RBTreeList_t; - -#define LIST_NEXT(N) (((RBTreeList_t *) (N))->next) -#define LIST_PREV(N) (((RBTreeList_t *) (N))->t.parent) -#endif - -#ifdef DEBUG - -/* Destroy all tree fields */ -#define DESTROY_TREE_NODE(N) \ - sys_memset((void *) (((Block_t *) (N)) + 1), \ - 0xff, \ - (sizeof(RBTree_t) - sizeof(Block_t))) - -/* Destroy all tree and list fields */ -#define DESTROY_LIST_ELEM(N) \ - sys_memset((void *) (((Block_t *) (N)) + 1), \ - 0xff, \ - (sizeof(RBTreeList_t) - sizeof(Block_t))) - -#else - -#define DESTROY_TREE_NODE(N) -#define DESTROY_LIST_ELEM(N) - -#endif - - -/* - * Red-Black Tree operations needed - */ - -static ERTS_INLINE void -left_rotate(RBTree_t **root, RBTree_t *x) -{ - RBTree_t *y = x->right; - x->right = y->left; - if (y->left) - y->left->parent = x; - y->parent = x->parent; - if (!y->parent) { - RBT_ASSERT(*root == x); - *root = y; - } - else if (x == x->parent->left) - x->parent->left = y; - else { - RBT_ASSERT(x == x->parent->right); - x->parent->right = y; - } - y->left = x; - x->parent = y; -} - -static ERTS_INLINE void -right_rotate(RBTree_t **root, RBTree_t *x) -{ - RBTree_t *y = x->left; - x->left = y->right; - if (y->right) - y->right->parent = x; - y->parent = x->parent; - if (!y->parent) { - RBT_ASSERT(*root == x); - *root = y; - } - else if (x == x->parent->right) - x->parent->right = y; - else { - RBT_ASSERT(x == x->parent->left); - x->parent->left = y; - } - y->right = x; - x->parent = y; -} - - -/* - * Replace node x with node y - * NOTE: block header of y is not changed - */ -static ERTS_INLINE void -replace(RBTree_t **root, RBTree_t *x, RBTree_t *y) -{ - - if (!x->parent) { - RBT_ASSERT(*root == x); - *root = y; - } - else if (x == x->parent->left) - x->parent->left = y; - else { - RBT_ASSERT(x == x->parent->right); - x->parent->right = y; - } - if (x->left) { - RBT_ASSERT(x->left->parent == x); - x->left->parent = y; - } - if (x->right) { - RBT_ASSERT(x->right->parent == x); - x->right->parent = y; - } - - y->flags = x->flags; - y->parent = x->parent; - y->right = x->right; - y->left = x->left; - - DESTROY_TREE_NODE(x); - -} - -static void -tree_insert_fixup(RBTree_t *blk) -{ - RBTree_t *x = blk, *y; - - /* - * Rearrange the tree so that it satisfies the Red-Black Tree properties - */ - - RBT_ASSERT(x != root && IS_RED(x->parent)); - 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. - */ - - RBT_ASSERT(IS_RED(x)); - RBT_ASSERT(IS_BLACK(x->parent->parent)); - RBT_ASSERT(x->parent->parent); - - if (x->parent == x->parent->parent->left) { - y = x->parent->parent->right; - if (IS_RED(y)) { - SET_BLACK(y); - x = x->parent; - SET_BLACK(x); - x = x->parent; - SET_RED(x); - } - else { - - if (x == x->parent->right) { - x = x->parent; - left_rotate(&root, x); - } - - RBT_ASSERT(x == x->parent->parent->left->left); - RBT_ASSERT(IS_RED(x)); - RBT_ASSERT(IS_RED(x->parent)); - RBT_ASSERT(IS_BLACK(x->parent->parent)); - RBT_ASSERT(IS_BLACK(y)); - - SET_BLACK(x->parent); - SET_RED(x->parent->parent); - right_rotate(&root, x->parent->parent); - - RBT_ASSERT(x == x->parent->left); - RBT_ASSERT(IS_RED(x)); - RBT_ASSERT(IS_RED(x->parent->right)); - RBT_ASSERT(IS_BLACK(x->parent)); - break; - } - } - else { - RBT_ASSERT(x->parent == x->parent->parent->right); - y = x->parent->parent->left; - if (IS_RED(y)) { - SET_BLACK(y); - x = x->parent; - SET_BLACK(x); - x = x->parent; - SET_RED(x); - } - else { - - if (x == x->parent->left) { - x = x->parent; - right_rotate(&root, x); - } - - RBT_ASSERT(x == x->parent->parent->right->right); - RBT_ASSERT(IS_RED(x)); - RBT_ASSERT(IS_RED(x->parent)); - RBT_ASSERT(IS_BLACK(x->parent->parent)); - RBT_ASSERT(IS_BLACK(y)); - - SET_BLACK(x->parent); - SET_RED(x->parent->parent); - left_rotate(&root, x->parent->parent); - - RBT_ASSERT(x == x->parent->right); - RBT_ASSERT(IS_RED(x)); - RBT_ASSERT(IS_RED(x->parent->left)); - RBT_ASSERT(IS_BLACK(x->parent)); - break; - } - } - } while (x != root && IS_RED(x->parent)); - - SET_BLACK(root); -} - -static void -unlink_free_block(Block_t *del) -{ - Uint spliced_is_black; - RBTree_t *x, *y, *z = (RBTree_t *) del; - RBTree_t null_x; /* null_x is used to get the fixup started when we - splice out a node without children. */ - - null_x.parent = NULL; - -#ifdef HARD_DEBUG - check_tree(0); -#endif - - /* 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); - if (x) { - x->parent = y->parent; - } - else if (!x && spliced_is_black) { - x = &null_x; - x->flags = 0; - SET_BLACK(x); - x->right = x->left = NULL; - x->parent = y->parent; - y->left = x; - } - - if (!y->parent) { - RBT_ASSERT(root == y); - root = x; - } - else if (y == y->parent->left) - y->parent->left = x; - else { - RBT_ASSERT(y == y->parent->right); - y->parent->right = x; - } - if (y != z) { - /* We spliced out the successor of z; replace z by the successor */ - replace(&root, z, y); - } - - if (spliced_is_black) { - /* We removed a black node which makes the resulting tree - violate the Red-Black Tree properties. Fixup tree... */ - - while (IS_BLACK(x) && x->parent) { - - /* - * 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 == x->parent->left) { - y = x->parent->right; - RBT_ASSERT(y); - if (IS_RED(y)) { - RBT_ASSERT(y->right); - RBT_ASSERT(y->left); - SET_BLACK(y); - RBT_ASSERT(IS_BLACK(x->parent)); - SET_RED(x->parent); - left_rotate(&root, x->parent); - y = x->parent->right; - } - RBT_ASSERT(y); - RBT_ASSERT(IS_BLACK(y)); - if (IS_BLACK(y->left) && IS_BLACK(y->right)) { - SET_RED(y); - x = x->parent; - } - else { - if (IS_BLACK(y->right)) { - SET_BLACK(y->left); - SET_RED(y); - right_rotate(&root, y); - y = x->parent->right; - } - RBT_ASSERT(y); - if (IS_RED(x->parent)) { - - SET_BLACK(x->parent); - SET_RED(y); - } - RBT_ASSERT(y->right); - SET_BLACK(y->right); - left_rotate(&root, x->parent); - x = root; - break; - } - } - else { - RBT_ASSERT(x == x->parent->right); - y = x->parent->left; - RBT_ASSERT(y); - if (IS_RED(y)) { - RBT_ASSERT(y->right); - RBT_ASSERT(y->left); - SET_BLACK(y); - RBT_ASSERT(IS_BLACK(x->parent)); - SET_RED(x->parent); - right_rotate(&root, x->parent); - y = x->parent->left; - } - RBT_ASSERT(y); - RBT_ASSERT(IS_BLACK(y)); - if (IS_BLACK(y->right) && IS_BLACK(y->left)) { - SET_RED(y); - x = x->parent; - } - else { - if (IS_BLACK(y->left)) { - SET_BLACK(y->right); - SET_RED(y); - left_rotate(&root, y); - y = x->parent->left; - } - RBT_ASSERT(y); - if (IS_RED(x->parent)) { - SET_BLACK(x->parent); - SET_RED(y); - } - RBT_ASSERT(y->left); - SET_BLACK(y->left); - right_rotate(&root, x->parent); - x = root; - break; - } - } - } - SET_BLACK(x); - - if (null_x.parent) { - if (null_x.parent->left == &null_x) - null_x.parent->left = NULL; - else { - RBT_ASSERT(null_x.parent->right == &null_x); - null_x.parent->right = NULL; - } - RBT_ASSERT(!null_x.left); - RBT_ASSERT(!null_x.right); - } - else if (root == &null_x) { - root = NULL; - RBT_ASSERT(!null_x.left); - RBT_ASSERT(!null_x.right); - } - } - - - DESTROY_TREE_NODE(del); - -#ifdef HARD_DEBUG - check_tree(0); -#endif - -} - -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\ - * "Address order best fit" specific callbacks. * -\* */ - -static void -link_free_block(Block_t *block) -{ - RBTree_t *blk = (RBTree_t *) block; - Uint blk_sz = BLK_SZ(blk); - - blk->flags = 0; - blk->left = NULL; - blk->right = NULL; - - if (!root) { - blk->parent = NULL; - SET_BLACK(blk); - root = blk; - } else { - RBTree_t *x = root; - while (1) { - Uint size; - - size = BLK_SZ(x); - - if (blk_sz < size || (blk_sz == size && blk < x)) { - if (!x->left) { - blk->parent = x; - x->left = blk; - break; - } - x = x->left; - } - else { - if (!x->right) { - blk->parent = x; - x->right = blk; - break; - } - x = x->right; - } - - } - - /* Insert block into size tree */ - RBT_ASSERT(blk->parent); - - SET_RED(blk); - if (IS_RED(blk->parent)) { - tree_insert_fixup(blk); - } - } - -#ifdef HARD_DEBUG - check_tree(0); -#endif -} - - -static Block_t * -get_free_block(Uint size) -{ - RBTree_t *x = root; - RBTree_t *blk = NULL; - Uint blk_sz; - - while (x) { - blk_sz = BLK_SZ(x); - if (blk_sz < size) { - x = x->right; - } - else { - blk = x; - x = x->left; - } - } - - if (!blk) - return NULL; - -#ifdef HARD_DEBUG - ASSERT(blk == check_tree(size)); -#endif - - unlink_free_block((Block_t *) blk); - - return (Block_t *) blk; -} - - -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\ - * Debug functions * -\* */ - - -#ifdef HARD_DEBUG - -#define IS_LEFT_VISITED(FB) ((FB)->flags & LEFT_VISITED_FLG) -#define IS_RIGHT_VISITED(FB) ((FB)->flags & RIGHT_VISITED_FLG) - -#define SET_LEFT_VISITED(FB) ((FB)->flags |= LEFT_VISITED_FLG) -#define SET_RIGHT_VISITED(FB) ((FB)->flags |= RIGHT_VISITED_FLG) - -#define UNSET_LEFT_VISITED(FB) ((FB)->flags &= ~LEFT_VISITED_FLG) -#define UNSET_RIGHT_VISITED(FB) ((FB)->flags &= ~RIGHT_VISITED_FLG) - - -#if 0 -# define PRINT_TREE -#else -# undef PRINT_TREE -#endif - -#ifdef PRINT_TREE -static void print_tree(void); -#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 a node that satisfies "best fit" resp. - * "address order best 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. - */ - -static RBTree_t * -check_tree(Uint size) -{ - RBTree_t *res = NULL; - Sint blacks; - Sint curr_blacks; - RBTree_t *x; - -#ifdef PRINT_TREE - print_tree(); -#endif - - if (!root) - return res; - - x = root; - ASSERT(IS_BLACK(x)); - ASSERT(!x->parent); - curr_blacks = 1; - blacks = -1; - - while (x) { - if (!IS_LEFT_VISITED(x)) { - SET_LEFT_VISITED(x); - if (x->left) { - x = x->left; - if (IS_BLACK(x)) - curr_blacks++; - continue; - } - else { - if (blacks < 0) - blacks = curr_blacks; - ASSERT(blacks == curr_blacks); - } - } - - if (!IS_RIGHT_VISITED(x)) { - SET_RIGHT_VISITED(x); - if (x->right) { - x = x->right; - if (IS_BLACK(x)) - curr_blacks++; - continue; - } - else { - if (blacks < 0) - blacks = curr_blacks; - ASSERT(blacks == curr_blacks); - } - } - - - if (IS_RED(x)) { - ASSERT(IS_BLACK(x->right)); - ASSERT(IS_BLACK(x->left)); - } - - ASSERT(x->parent || x == root); - - if (x->left) { - ASSERT(x->left->parent == x); - ASSERT(BLK_SZ(x->left) < BLK_SZ(x) - || (BLK_SZ(x->left) == BLK_SZ(x) && x->left < x)); - } - - if (x->right) { - ASSERT(x->right->parent == x); - ASSERT(BLK_SZ(x->right) > BLK_SZ(x) - || (BLK_SZ(x->right) == BLK_SZ(x) && x->right > x)); - } - - if (size && BLK_SZ(x) >= size) { - if (!res - || BLK_SZ(x) < BLK_SZ(res) - || (BLK_SZ(x) == BLK_SZ(res) && x < res)) - res = x; - } - - UNSET_LEFT_VISITED(x); - UNSET_RIGHT_VISITED(x); - if (IS_BLACK(x)) - curr_blacks--; - x = x->parent; - - } - - ASSERT(curr_blacks == 0); - - UNSET_LEFT_VISITED(root); - UNSET_RIGHT_VISITED(root); - - return res; - -} - - -#ifdef PRINT_TREE -#define INDENT_STEP 2 - -#include <stdio.h> - -static void -print_tree_aux(RBTree_t *x, int indent) -{ - int i; - - if (!x) { - for (i = 0; i < indent; i++) { - putc(' ', stderr); - } - fprintf(stderr, "BLACK: nil\r\n"); - } - else { - print_tree_aux(x->right, indent + INDENT_STEP); - for (i = 0; i < indent; i++) { - putc(' ', stderr); - } - fprintf(stderr, "%s: sz=%lu addr=0x%lx\r\n", - IS_BLACK(x) ? "BLACK" : "RED", - BLK_SZ(x), - (Uint) x); - print_tree_aux(x->left, indent + INDENT_STEP); - } -} - - -static void -print_tree(void) -{ - fprintf(stderr, " --- Size-Adress tree begin ---\r\n"); - print_tree_aux(root, 0); - fprintf(stderr, " --- Size-Adress tree end ---\r\n"); -} - -#endif - -#endif - -#endif /* ENABLE_ELIB_MALLOC */ diff --git a/erts/emulator/beam/elib_stat.h b/erts/emulator/beam/elib_stat.h deleted file mode 100644 index d8c7f31737..0000000000 --- a/erts/emulator/beam/elib_stat.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * %CopyrightBegin% - * - * Copyright Ericsson AB 1996-2009. 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% - */ - -/* -** Interface to elib statistics -** -*/ -#ifndef __ELIB_STAT_H__ -#define __ELIB_STAT_H__ - -struct elib_stat { - int mem_total; /* Number of heap words */ - int mem_blocks; /* Number of block */ - int mem_alloc; /* Number of words in use */ - int mem_free; /* Number of words free */ - int min_used; /* Size of the smallest block used */ - int max_free; /* Size of the largest free block */ - int free_blocks; /* Number of fragments in free list */ - int mem_max_alloc;/* Max number of words in use */ -}; - -EXTERN_FUNCTION(void, elib_statistics, (void*)); -EXTERN_FUNCTION(int, elib_check_heap, (_VOID_)); -EXTERN_FUNCTION(void, elib_heap_dump, (char*)); -EXTERN_FUNCTION(void, elib_stat, (struct elib_stat*)); -EXTERN_FUNCTION(int, elib_heap_map, (unsigned char*, int)); -EXTERN_FUNCTION(int, elib_histo, (unsigned long*, unsigned long*, int, int)); - -#endif diff --git a/erts/emulator/beam/erl_alloc.c b/erts/emulator/beam/erl_alloc.c index 87503af7d5..07b4167b27 100644 --- a/erts/emulator/beam/erl_alloc.c +++ b/erts/emulator/beam/erl_alloc.c @@ -38,9 +38,6 @@ #include "erl_bits.h" #include "erl_instrument.h" #include "erl_mseg.h" -#ifdef ELIB_ALLOC_IS_CLIB -#include "erl_version.h" -#endif #include "erl_monitors.h" #include "erl_bif_timer.h" #if defined(ERTS_ALC_T_DRV_SEL_D_STATE) || defined(ERTS_ALC_T_DRV_EV_D_STATE) @@ -73,7 +70,6 @@ static Uint install_debug_functions(void); #endif #endif #endif -extern void elib_ensure_initialized(void); ErtsAllocatorFunctions_t erts_allctrs[ERTS_ALC_A_MAX+1]; ErtsAllocatorInfo_t erts_allctrs_info[ERTS_ALC_A_MAX+1]; @@ -2321,13 +2317,8 @@ erts_allocator_info_term(void *proc, Eterm which_alloc, int only_sz) l = 0; as[l] = am_atom_put("e", 1); ts[l++] = am_true; -#ifdef ELIB_ALLOC_IS_CLIB - as[l] = am_atom_put("m", 1); - ts[l++] = am_atom_put("elib", 4); -#else as[l] = am_atom_put("m", 1); ts[l++] = am_atom_put("libc", 4); -#endif if(sas.trim_threshold >= 0) { as[l] = am_atom_put("tt", 2); ts[l++] = erts_bld_uint(hpp, szp, @@ -2481,11 +2472,7 @@ erts_allocator_info(int to, void *arg) case ERTS_ALC_A_SYSTEM: { SysAllocStat sas; erts_print(to, arg, "option e: true\n"); -#ifdef ELIB_ALLOC_IS_CLIB - erts_print(to, arg, "option m: elib\n"); -#else erts_print(to, arg, "option m: libc\n"); -#endif sys_alloc_stat(&sas); if(sas.trim_threshold >= 0) erts_print(to, arg, "option tt: %d\n", sas.trim_threshold); @@ -2589,13 +2576,8 @@ erts_allocator_options(void *proc) switch (a) { case ERTS_ALC_A_SYSTEM: -#ifdef ELIB_ALLOC_IS_CLIB - as[l] = am_atom_put("m", 1); - ts[l++] = am_atom_put("elib", 4); -#else as[l] = am_atom_put("m", 1); ts[l++] = am_atom_put("libc", 4); -#endif if(sas.trim_threshold >= 0) { as[l] = am_atom_put("tt", 2); ts[l++] = erts_bld_uint(hpp, szp, @@ -2666,23 +2648,7 @@ erts_allocator_options(void *proc) features = length ? erts_bld_list(hpp, szp, length, terms) : NIL; -#if defined(ELIB_ALLOC_IS_CLIB) - { - Eterm version; - int i; - int ver[5]; - i = sscanf(ERLANG_VERSION, - "%d.%d.%d.%d.%d", - &ver[0], &ver[1], &ver[2], &ver[3], &ver[4]); - - version = NIL; - for(i--; i >= 0; i--) - version = erts_bld_cons(hpp, szp, make_small(ver[i]), version); - - res = erts_bld_tuple(hpp, szp, 4, - am_elib_malloc, version, features, settings); - } -#elif defined(__GLIBC__) +#if defined(__GLIBC__) { Eterm AM_glibc = am_atom_put("glibc", 5); Eterm version; diff --git a/erts/emulator/beam/erl_async.c b/erts/emulator/beam/erl_async.c index be691317ee..12c7631448 100644 --- a/erts/emulator/beam/erl_async.c +++ b/erts/emulator/beam/erl_async.c @@ -70,7 +70,6 @@ static ErlAsync* async_ready_list = NULL; /* Detach from driver */ static void async_detach(DE_Handle* dh) { - /* XXX:PaN what should happen here? we want to unload the driver or??? */ return; } @@ -176,7 +175,6 @@ int exit_async() static void async_add(ErlAsync* a, AsyncQueue* q) { - /* XXX:PaN Is this still necessary when ports lock drivers? */ if (is_internal_port(a->port)) { ERTS_LC_ASSERT(erts_drvportid2port(a->port)); /* make sure the driver will stay around */ diff --git a/erts/emulator/beam/erl_bif_binary.c b/erts/emulator/beam/erl_bif_binary.c index 1d8fd11b7b..024ff2a684 100644 --- a/erts/emulator/beam/erl_bif_binary.c +++ b/erts/emulator/beam/erl_bif_binary.c @@ -2517,7 +2517,7 @@ BIF_RETTYPE binary_copy_trap(BIF_ALIST_2) pb->bytes = t; pb->flags = 0; - MSO(BIF_P).overhead += target_size / sizeof(Eterm); + OH_OVERHEAD(&(MSO(BIF_P)), target_size / sizeof(Eterm)); BUMP_REDS(BIF_P,(pos - opos) / BINARY_COPY_LOOP_FACTOR); BIF_RET(make_binary(pb)); @@ -2551,7 +2551,8 @@ BIF_RETTYPE binary_referenced_byte_size_1(BIF_ALIST_1) } pb = (ProcBin *) binary_val(bin); if (pb->thing_word == HEADER_PROC_BIN) { - res = erts_make_integer((Uint) pb->val->orig_size, BIF_P); /* XXX:PaN Halfword? orig_size is a long */ + /* XXX:PaN - Halfword - orig_size is a long, we should handle that */ + res = erts_make_integer((Uint) pb->val->orig_size, BIF_P); } else { /* heap binary */ res = erts_make_integer((Uint) ((ErlHeapBin *) pb)->size, BIF_P); } diff --git a/erts/emulator/beam/erl_bif_ddll.c b/erts/emulator/beam/erl_bif_ddll.c index 9d5f0d9c02..2c2e283f65 100644 --- a/erts/emulator/beam/erl_bif_ddll.c +++ b/erts/emulator/beam/erl_bif_ddll.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2006-2009. All Rights Reserved. + * Copyright Ericsson AB 2006-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 @@ -1646,7 +1646,8 @@ static int do_unload_driver_entry(DE_Handle *dh, Eterm *save_name) if (save_name != NULL) { *save_name = mkatom(q->name); } - /* XXX:PaN Future locking problems? Don't dare to let go of the diver_list lock here!*/ + /* Future locking problems? Don't dare to let go of the + diver_list lock here!*/ if (q->finish) { int fpe_was_unmasked = erts_block_fpe(); (*(q->finish))(); diff --git a/erts/emulator/beam/erl_bif_info.c b/erts/emulator/beam/erl_bif_info.c index 5128776c47..40d8dc097c 100644 --- a/erts/emulator/beam/erl_bif_info.c +++ b/erts/emulator/beam/erl_bif_info.c @@ -38,9 +38,6 @@ #include "erl_instrument.h" #include "dist.h" #include "erl_gc.h" -#ifdef ELIB_ALLOC_IS_CLIB -#include "elib_stat.h" -#endif #ifdef HIPE #include "hipe_arch.h" #endif @@ -1958,6 +1955,35 @@ BIF_RETTYPE system_info_1(BIF_ALIST_1) : am_enabled); } #endif + } else if (BIF_ARG_1 == am_build_type) { +#if defined(DEBUG) + ERTS_DECL_AM(debug); + BIF_RET(AM_debug); +#elif defined(PURIFY) + ERTS_DECL_AM(purify); + BIF_RET(AM_purify); +#elif defined(QUANTIFY) + ERTS_DECL_AM(quantify); + BIF_RET(AM_quantify); +#elif defined(PURECOV) + ERTS_DECL_AM(purecov); + BIF_RET(AM_purecov); +#elif defined(ERTS_GCOV) + ERTS_DECL_AM(gcov); + BIF_RET(AM_gcov); +#elif defined(VALGRIND) + ERTS_DECL_AM(valgrind); + BIF_RET(AM_valgrind); +#elif defined(GPROF) + ERTS_DECL_AM(gprof); + BIF_RET(AM_gprof); +#elif defined(ERTS_ENABLE_LOCK_COUNT) + ERTS_DECL_AM(lcnt); + BIF_RET(AM_lcnt); +#else + BIF_RET(am_opt); +#endif + BIF_RET(res); } else if (BIF_ARG_1 == am_allocated_areas) { res = erts_allocated_areas(NULL, NULL, BIF_P); BIF_RET(res); @@ -2126,86 +2152,8 @@ BIF_RETTYPE system_info_1(BIF_ALIST_1) BIF_RET(erts_alloc_util_allocators((void *) BIF_P)); } else if (BIF_ARG_1 == am_elib_malloc) { -#ifdef ELIB_ALLOC_IS_CLIB - struct elib_stat stat; - DECL_AM(heap_size); - DECL_AM(max_alloced_size); - DECL_AM(alloced_size); - DECL_AM(free_size); - DECL_AM(no_alloced_blocks); - DECL_AM(no_free_blocks); - DECL_AM(smallest_alloced_block); - DECL_AM(largest_free_block); - Eterm atoms[8]; - Eterm ints[8]; - Uint **hpp; - Uint sz; - Uint *szp; - int length; -#ifdef DEBUG - Uint *endp; -#endif - - elib_stat(&stat); - - /* First find out the heap size needed ... */ - hpp = NULL; - szp = &sz; - sz = 0; - - build_elib_malloc_term: - length = 0; - atoms[length] = AM_heap_size; - ints[length++] = erts_bld_uint(hpp, szp, - (Uint) stat.mem_total*sizeof(Uint)); - atoms[length] = AM_max_alloced_size; - ints[length++] = erts_bld_uint(hpp, szp, - (Uint) stat.mem_max_alloc*sizeof(Uint)); - atoms[length] = AM_alloced_size; - ints[length++] = erts_bld_uint(hpp, szp, - (Uint) stat.mem_alloc*sizeof(Uint)); - atoms[length] = AM_free_size; - ints[length++] = erts_bld_uint(hpp, szp, - (Uint) stat.mem_free*sizeof(Uint)); - atoms[length] = AM_no_alloced_blocks; - ints[length++] = erts_bld_uint(hpp, szp, (Uint) stat.mem_blocks); - atoms[length] = AM_no_free_blocks; - ints[length++] = erts_bld_uint(hpp, szp, (Uint) stat.free_blocks); - atoms[length] = AM_smallest_alloced_block; - ints[length++] = erts_bld_uint(hpp, szp, - (Uint) stat.min_used*sizeof(Uint)); - atoms[length] = AM_largest_free_block; - ints[length++] = erts_bld_uint(hpp, szp, - (Uint) stat.max_free*sizeof(Uint)); - - - - ASSERT(length <= sizeof(atoms)/sizeof(Eterm)); - ASSERT(length <= sizeof(ints)/sizeof(Eterm)); - - res = erts_bld_2tup_list(hpp, szp, length, atoms, ints); - - if (szp) { - /* ... and then build the term */ - hp = HAlloc(BIF_P, sz); -#ifdef DEBUG - endp = hp + sz; -#endif - - szp = NULL; - hpp = &hp; - goto build_elib_malloc_term; - } - -#ifdef DEBUG - ASSERT(endp == hp); -#endif - -#else /* #ifdef ELIB_ALLOC_IS_CLIB */ - res = am_false; -#endif /* #ifdef ELIB_ALLOC_IS_CLIB */ - - BIF_RET(res); + /* To be removed in R15 */ + BIF_RET(am_false); } else if (BIF_ARG_1 == am_os_version) { int major, minor, build; @@ -2316,6 +2264,15 @@ BIF_RETTYPE system_info_1(BIF_ALIST_1) } else if (ERTS_IS_ATOM_STR("cpu_topology", BIF_ARG_1)) { res = erts_get_cpu_topology_term(BIF_P, am_used); BIF_TRAP1(erts_format_cpu_topology_trap, BIF_P, res); + } else if (ERTS_IS_ATOM_STR("update_cpu_info", BIF_ARG_1)) { + if (erts_update_cpu_info()) { + ERTS_DECL_AM(changed); + BIF_RET(AM_changed); + } + else { + ERTS_DECL_AM(unchanged); + BIF_RET(AM_unchanged); + } #if defined(__GNUC__) && defined(HAVE_SOLARIS_SPARC_PERFMON) } else if (ERTS_IS_ATOM_STR("ultrasparc_read_tick1", BIF_ARG_1)) { register unsigned high asm("%l0"); @@ -2387,7 +2344,10 @@ BIF_RETTYPE system_info_1(BIF_ALIST_1) } /* Arguments that are unusual follow ... */ else if (ERTS_IS_ATOM_STR("logical_processors", BIF_ARG_1)) { - int no = erts_get_cpu_configured(erts_cpuinfo); + int no; + erts_smp_rwmtx_rlock(&erts_cpu_bind_rwmtx); + no = erts_get_cpu_configured(erts_cpuinfo); + erts_smp_rwmtx_runlock(&erts_cpu_bind_rwmtx); if (no > 0) BIF_RET(make_small((Uint) no)); else { @@ -2396,7 +2356,10 @@ BIF_RETTYPE system_info_1(BIF_ALIST_1) } } else if (ERTS_IS_ATOM_STR("logical_processors_online", BIF_ARG_1)) { - int no = erts_get_cpu_online(erts_cpuinfo); + int no; + erts_smp_rwmtx_rlock(&erts_cpu_bind_rwmtx); + no = erts_get_cpu_online(erts_cpuinfo); + erts_smp_rwmtx_runlock(&erts_cpu_bind_rwmtx); if (no > 0) BIF_RET(make_small((Uint) no)); else { @@ -2405,7 +2368,10 @@ BIF_RETTYPE system_info_1(BIF_ALIST_1) } } else if (ERTS_IS_ATOM_STR("logical_processors_available", BIF_ARG_1)) { - int no = erts_get_cpu_available(erts_cpuinfo); + int no; + erts_smp_rwmtx_rlock(&erts_cpu_bind_rwmtx); + no = erts_get_cpu_available(erts_cpuinfo); + erts_smp_rwmtx_runlock(&erts_cpu_bind_rwmtx); if (no > 0) BIF_RET(make_small((Uint) no)); else { diff --git a/erts/emulator/beam/erl_bits.c b/erts/emulator/beam/erl_bits.c index 96faa673f6..88d2c06246 100644 --- a/erts/emulator/beam/erl_bits.c +++ b/erts/emulator/beam/erl_bits.c @@ -1340,7 +1340,7 @@ erts_bs_append(Process* c_p, Eterm* reg, Uint live, Eterm build_size_term, pb->val = bptr; pb->bytes = (byte*) bptr->orig_bytes; pb->flags = PB_IS_WRITABLE | PB_ACTIVE_WRITER; - MSO(c_p).overhead += pb->size / sizeof(Eterm); + OH_OVERHEAD(&(MSO(c_p)), pb->size / sizeof(Eterm)); /* * Now allocate the sub binary and set its size to include the @@ -1511,7 +1511,7 @@ erts_bs_init_writable(Process* p, Eterm sz) pb->val = bptr; pb->bytes = (byte*) bptr->orig_bytes; pb->flags = PB_IS_WRITABLE | PB_ACTIVE_WRITER; - MSO(p).overhead += pb->size / sizeof(Eterm); + OH_OVERHEAD(&(MSO(p)), pb->size / sizeof(Eterm)); /* * Now allocate the sub binary. diff --git a/erts/emulator/beam/erl_db_hash.c b/erts/emulator/beam/erl_db_hash.c index 08117bb6e5..5abd2e50fa 100644 --- a/erts/emulator/beam/erl_db_hash.c +++ b/erts/emulator/beam/erl_db_hash.c @@ -2745,6 +2745,7 @@ static void db_finalize_dbterm_hash(DbUpdateHandle* handle) ASSERT(&oldp->dbterm == handle->dbterm); if (handle->mustResize) { + ErlOffHeap tmp_offheap; Eterm* top; Eterm copy; DbTerm* newDbTerm; @@ -2755,14 +2756,15 @@ static void db_finalize_dbterm_hash(DbUpdateHandle* handle) newDbTerm = &newp->dbterm; newDbTerm->size = handle->new_size; - newDbTerm->off_heap.first = NULL; - newDbTerm->off_heap.overhead = 0; + tmp_offheap.first = NULL; + tmp_offheap.overhead = 0; /* make a flat copy */ top = DBTERM_BUF(newDbTerm); copy = copy_struct(make_tuple(handle->dbterm->tpl), handle->new_size, - &top, &newDbTerm->off_heap); + &top, &tmp_offheap); + newDbTerm->first_oh = tmp_offheap.first; DBTERM_SET_TPL(newDbTerm,tuple_val(copy)); WUNLOCK_HASH(lck); @@ -2805,7 +2807,11 @@ void db_foreach_offheap_hash(DbTable *tbl, for (i = 0; i < nactive; i++) { list = BUCKET(tb,i); while(list != 0) { - (*func)(&(list->dbterm.off_heap), arg); + ErlOffHeap tmp_offheap; + tmp_offheap.first = list->dbterm.first_oh; + tmp_offheap.overhead = 0; + (*func)(&tmp_offheap, arg); + list->dbterm.first_oh = tmp_offheap.first; list = list->next; } } diff --git a/erts/emulator/beam/erl_db_tree.c b/erts/emulator/beam/erl_db_tree.c index da2696163a..5644e85f97 100644 --- a/erts/emulator/beam/erl_db_tree.c +++ b/erts/emulator/beam/erl_db_tree.c @@ -1818,10 +1818,14 @@ do_db_tree_foreach_offheap(TreeDbTerm *tdbt, void (*func)(ErlOffHeap *, void *), void * arg) { + ErlOffHeap tmp_offheap; if(!tdbt) return; do_db_tree_foreach_offheap(tdbt->left, func, arg); - (*func)(&(tdbt->dbterm.off_heap), arg); + tmp_offheap.first = tdbt->dbterm.first_oh; + tmp_offheap.overhead = 0; + (*func)(&tmp_offheap, arg); + tdbt->dbterm.first_oh = tmp_offheap.first; do_db_tree_foreach_offheap(tdbt->right, func, arg); } @@ -2575,6 +2579,7 @@ static int db_lookup_dbterm_tree(DbTable *tbl, Eterm key, DbUpdateHandle* handle static void db_finalize_dbterm_tree(DbUpdateHandle* handle) { if (handle->mustResize) { + ErlOffHeap tmp_offheap; Eterm* top; Eterm copy; DbTerm* newDbTerm; @@ -2589,14 +2594,15 @@ static void db_finalize_dbterm_tree(DbUpdateHandle* handle) newDbTerm = &newp->dbterm; newDbTerm->size = handle->new_size; - newDbTerm->off_heap.first = NULL; - newDbTerm->off_heap.overhead = 0; + tmp_offheap.first = NULL; + tmp_offheap.overhead = 0; /* make a flat copy */ top = DBTERM_BUF(newDbTerm); copy = copy_struct(make_tuple(handle->dbterm->tpl), handle->new_size, - &top, &newDbTerm->off_heap); + &top, &tmp_offheap); + newDbTerm->first_oh = tmp_offheap.first; DBTERM_SET_TPL(newDbTerm,tuple_val(copy)); db_free_term_data(handle->dbterm); diff --git a/erts/emulator/beam/erl_db_util.c b/erts/emulator/beam/erl_db_util.c index 48e0080525..2f34561234 100644 --- a/erts/emulator/beam/erl_db_util.c +++ b/erts/emulator/beam/erl_db_util.c @@ -1733,8 +1733,7 @@ restart: FAIL(); ep = termp; break; - case matchArrayBind: /* When the array size is unknown. */ /* XXX:PaN - where does - this array come from? */ + case matchArrayBind: /* When the array size is unknown. */ n = *pc++; hp[n] = dpm_array_to_list(psp, termp, arity); break; @@ -2452,9 +2451,13 @@ void* db_get_term(DbTableCommon *tb, DbTerm* old, Uint offset, Eterm obj) DbTerm* p; Eterm copy; Eterm *top; + ErlOffHeap tmp_offheap; if (old != 0) { - erts_cleanup_offheap(&old->off_heap); + tmp_offheap.first = old->first_oh; + tmp_offheap.overhead = 0; + erts_cleanup_offheap(&tmp_offheap); + old->first_oh = tmp_offheap.first; if (size == old->size) { p = old; } else { @@ -2490,11 +2493,12 @@ void* db_get_term(DbTableCommon *tb, DbTerm* old, Uint offset, Eterm obj) p = (DbTerm*) ((void *)(((char *) structp) + offset)); } p->size = size; - p->off_heap.first = NULL; - p->off_heap.overhead = 0; + tmp_offheap.first = NULL; + tmp_offheap.overhead = 0; top = DBTERM_BUF(p); - copy = copy_struct(obj, size, &top, &p->off_heap); + copy = copy_struct(obj, size, &top, &tmp_offheap); + p->first_oh = tmp_offheap.first; DBTERM_SET_TPL(p,tuple_val(copy)); return structp; @@ -2503,7 +2507,10 @@ void* db_get_term(DbTableCommon *tb, DbTerm* old, Uint offset, Eterm obj) void db_free_term_data(DbTerm* p) { - erts_cleanup_offheap(&p->off_heap); + ErlOffHeap tmp_offheap; + tmp_offheap.first = p->first_oh; + tmp_offheap.overhead = 0; + erts_cleanup_offheap(&tmp_offheap); } diff --git a/erts/emulator/beam/erl_db_util.h b/erts/emulator/beam/erl_db_util.h index 672c5f2cd1..0f333e8b34 100644 --- a/erts/emulator/beam/erl_db_util.h +++ b/erts/emulator/beam/erl_db_util.h @@ -57,7 +57,7 @@ * A datatype for a database entry stored out of a process heap */ typedef struct db_term { - ErlOffHeap off_heap; /* Off heap data for term. */ + struct erl_off_heap_header* first_oh; /* Off heap data for term. */ Uint size; /* Size of term in "words" */ Eterm tpl[1]; /* Untagged "constant pointer" to top tuple */ /* (assumed to be first in buffer) */ diff --git a/erts/emulator/beam/erl_gc.c b/erts/emulator/beam/erl_gc.c index adc50675bf..0f4d2a2ef9 100644 --- a/erts/emulator/beam/erl_gc.c +++ b/erts/emulator/beam/erl_gc.c @@ -743,7 +743,10 @@ minor_collection(Process* p, int need, Eterm* objv, int nobj, Uint *recl) * is large enough. */ - if (OLD_HEAP(p) && mature <= OLD_HEND(p) - OLD_HTOP(p)) { + if (OLD_HEAP(p) && + ((mature <= OLD_HEND(p) - OLD_HTOP(p)) && + ((BIN_VHEAP_MATURE(p) < ( BIN_OLD_VHEAP_SZ(p) - BIN_OLD_VHEAP(p)))) && + ((BIN_OLD_VHEAP_SZ(p) > BIN_OLD_VHEAP(p))) ) ) { ErlMessage *msgp; Uint size_after; Uint need_after; @@ -1982,8 +1985,8 @@ shrink_new_heap(Process *p, Uint new_sz, Eterm *objv, int nobj) HEAP_SIZE(p) = new_sz; } -static Uint -do_next_vheap_size(Uint vheap, Uint vheap_sz) { +static Uint64 +do_next_vheap_size(Uint64 vheap, Uint64 vheap_sz) { /* grow * @@ -2000,27 +2003,33 @@ do_next_vheap_size(Uint vheap, Uint vheap_sz) { * ---------------------- */ - if (vheap > (Uint) (vheap_sz*3/4)) { + if ((Uint64) vheap/3 > (Uint64) (vheap_sz/4)) { + Uint64 new_vheap_sz = vheap_sz; - while(vheap > (Uint) (vheap_sz*3/4)) { - vheap_sz = vheap_sz*2; + while((Uint64) vheap/3 > (Uint64) (vheap_sz/4)) { + /* the golden ratio = 1.618 */ + new_vheap_sz = (Uint64) vheap_sz * 1.618; + if (new_vheap_sz < vheap_sz ) { + return vheap_sz; + } + vheap_sz = new_vheap_sz; } - return erts_next_heap_size(vheap_sz, 0); + return vheap_sz; } - if (vheap < (Uint) (vheap_sz/4)) { - return erts_next_heap_size((Uint) (vheap_sz / 2), 0); + if (vheap < (Uint64) (vheap_sz/4)) { + return (vheap_sz >> 1); } return vheap_sz; } -static Uint -next_vheap_size(Process* p, Uint vheap, Uint vheap_sz) { - vheap_sz = do_next_vheap_size(vheap, vheap_sz); - return vheap_sz < p->min_vheap_size ? p->min_vheap_size : vheap_sz; +static Uint64 +next_vheap_size(Process* p, Uint64 vheap, Uint64 vheap_sz) { + Uint64 new_vheap_sz = do_next_vheap_size(vheap, vheap_sz); + return new_vheap_sz < p->min_vheap_size ? p->min_vheap_size : new_vheap_sz; } struct shrink_cand_data { @@ -2079,7 +2088,7 @@ link_live_proc_bin(struct shrink_cand_data *shrink, } -static void +static void sweep_off_heap(Process *p, int fullsweep) { struct shrink_cand_data shrink = {0}; @@ -2087,7 +2096,7 @@ sweep_off_heap(Process *p, int fullsweep) struct erl_off_heap_header** prev; char* oheap = NULL; Uint oheap_sz = 0; - Uint bin_vheap = 0; + Uint64 bin_vheap = 0; #ifdef DEBUG int seen_mature = 0; #endif @@ -2171,13 +2180,12 @@ sweep_off_heap(Process *p, int fullsweep) } } - if (BIN_OLD_VHEAP(p) >= BIN_OLD_VHEAP_SZ(p)) { - FLAGS(p) |= F_NEED_FULLSWEEP; + if (fullsweep) { + BIN_OLD_VHEAP_SZ(p) = next_vheap_size(p, BIN_OLD_VHEAP(p) + MSO(p).overhead, BIN_OLD_VHEAP_SZ(p)); } - - BIN_VHEAP_SZ(p) = next_vheap_size(p, bin_vheap, BIN_VHEAP_SZ(p)); - BIN_OLD_VHEAP_SZ(p) = next_vheap_size(p, BIN_OLD_VHEAP(p), BIN_OLD_VHEAP_SZ(p)); - MSO(p).overhead = bin_vheap; + BIN_VHEAP_SZ(p) = next_vheap_size(p, bin_vheap, BIN_VHEAP_SZ(p)); + MSO(p).overhead = bin_vheap; + BIN_VHEAP_MATURE(p) = bin_vheap; /* * If we got any shrink candidates, check them out. diff --git a/erts/emulator/beam/erl_init.c b/erts/emulator/beam/erl_init.c index 14bd10b42c..4ae656a3ad 100644 --- a/erts/emulator/beam/erl_init.c +++ b/erts/emulator/beam/erl_init.c @@ -512,6 +512,8 @@ void erts_usage(void) erts_fprintf(stderr, " u|ns|ts|ps|s|nnts|nnps|tnnps|db\n"); erts_fprintf(stderr, "-sct cput set cpu topology,\n"); erts_fprintf(stderr, " see the erl(1) documentation for more info.\n"); + erts_fprintf(stderr, "-swt val set scheduler wakeup threshold, valid values are:\n"); + erts_fprintf(stderr, " very_low|low|medium|high|very_high.\n"); erts_fprintf(stderr, "-sss size suggested stack size in kilo words for scheduler threads,\n"); erts_fprintf(stderr, " valid range is [%d-%d]\n", ERTS_SCHED_THREAD_MIN_STACK_SIZE, @@ -1176,10 +1178,20 @@ erl_start(int argc, char **argv) } else if (sys_strcmp("mrq", sub_param) == 0) use_multi_run_queue = 1; - else if (sys_strcmp("srq", sub_param) == 0) - use_multi_run_queue = 0; else if (sys_strcmp("nsp", sub_param) == 0) erts_use_sender_punish = 0; + else if (sys_strcmp("srq", sub_param) == 0) + use_multi_run_queue = 0; + else if (sys_strcmp("wt", sub_param) == 0) { + arg = get_arg(sub_param+2, argv[i+1], &i); + if (erts_sched_set_wakeup_limit(arg) != 0) { + erts_fprintf(stderr, "scheduler wakeup threshold: %s\n", + arg); + erts_usage(); + } + VERBOSE(DEBUG_SYSTEM, + ("scheduler wakup threshold: %s\n", arg)); + } else if (has_prefix("ss", sub_param)) { /* suggested stack size (Kilo Words) for scheduler threads */ arg = get_arg(sub_param+2, argv[i+1], &i); diff --git a/erts/emulator/beam/erl_lock_check.c b/erts/emulator/beam/erl_lock_check.c index 99cc80e259..d6138fa4e4 100644 --- a/erts/emulator/beam/erl_lock_check.c +++ b/erts/emulator/beam/erl_lock_check.c @@ -1258,7 +1258,6 @@ erts_lc_init_lock(erts_lc_lock_t *lck, char *name, Uint16 flags) { lck->id = erts_lc_get_lock_order_id(name); - /* XXX:PaN What to do with the extra information? */ lck->extra = make_boxed(&lck->extra); lck->flags = flags; lck->inited = ERTS_LC_INITITALIZED; diff --git a/erts/emulator/beam/erl_message.c b/erts/emulator/beam/erl_message.c index 1f61dca230..82f272d28a 100644 --- a/erts/emulator/beam/erl_message.c +++ b/erts/emulator/beam/erl_message.c @@ -220,7 +220,7 @@ link_mbuf_to_proc(Process *proc, ErlHeapFragment *bp) *next_p = MSO(proc).first; MSO(proc).first = bp->off_heap.first; bp->off_heap.first = NULL; - MSO(proc).overhead += bp->off_heap.overhead; + OH_OVERHEAD(&(MSO(proc)), bp->off_heap.overhead); } } } @@ -535,7 +535,7 @@ erts_move_msg_mbuf_to_heap(Eterm** hpp, ErlOffHeap* off_heap, ErlMessage *msg) goto copy_done; } - off_heap->overhead += bp->off_heap.overhead; + OH_OVERHEAD(off_heap, bp->off_heap.overhead); sz = bp->used_size; ASSERT(is_immed(term) || in_heapfrag(ptr_val(term),bp)); diff --git a/erts/emulator/beam/erl_message.h b/erts/emulator/beam/erl_message.h index 55ea92860a..5aca0db6fe 100644 --- a/erts/emulator/beam/erl_message.h +++ b/erts/emulator/beam/erl_message.h @@ -37,9 +37,13 @@ struct erl_off_heap_header { struct erl_off_heap_header* next; }; +#define OH_OVERHEAD(oh, size) do { \ + (oh)->overhead += size; \ +} while(0) + typedef struct erl_off_heap { struct erl_off_heap_header* first; - int overhead; /* Administrative overhead (used to force GC). */ + Uint64 overhead; /* Administrative overhead (used to force GC). */ } ErlOffHeap; #include "external.h" diff --git a/erts/emulator/beam/erl_nif.c b/erts/emulator/beam/erl_nif.c index e95d9c4f75..1dd9c8bd4a 100644 --- a/erts/emulator/beam/erl_nif.c +++ b/erts/emulator/beam/erl_nif.c @@ -631,7 +631,7 @@ Eterm enif_make_binary(ErlNifEnv* env, ErlNifBinary* bin) pb->bytes = (byte*) bptr->orig_bytes; pb->flags = 0; - MSO(env->proc).overhead += pb->size / sizeof(Eterm); + OH_OVERHEAD(&(MSO(env->proc)), pb->size / sizeof(Eterm)); bin_term = make_binary(pb); if (erts_refc_read(&bptr->refc, 1) == 1) { /* Total ownership transfer */ @@ -750,7 +750,19 @@ int enif_get_ulong(ErlNifEnv* env, Eterm term, unsigned long* ip) #endif } -int enif_get_double(ErlNifEnv* env, Eterm term, double* dp) +#if HAVE_INT64 && SIZEOF_LONG != 8 +int enif_get_int64(ErlNifEnv* env, ERL_NIF_TERM term, ErlNifSInt64* ip) +{ + return term_to_Sint64(term, ip); +} + +int enif_get_uint64(ErlNifEnv* env, ERL_NIF_TERM term, ErlNifUInt64* ip) +{ + return term_to_Uint64(term, ip); +} +#endif /* HAVE_INT64 && SIZEOF_LONG != 8 */ + +int enif_get_double(ErlNifEnv* env, ERL_NIF_TERM term, double* dp) { FloatDef f; if (is_not_float(term)) { @@ -817,6 +829,26 @@ ERL_NIF_TERM enif_make_ulong(ErlNifEnv* env, unsigned long i) return IS_USMALL(0,i) ? make_small(i) : uint_to_big(i,alloc_heap(env,2)); } +#if HAVE_INT64 && SIZEOF_LONG != 8 +ERL_NIF_TERM enif_make_int64(ErlNifEnv* env, ErlNifSInt64 i) +{ + Uint* hp; + Uint need = 0; + erts_bld_sint64(NULL, &need, i); + hp = alloc_heap(env, need); + return erts_bld_sint64(&hp, NULL, i); +} + +ERL_NIF_TERM enif_make_uint64(ErlNifEnv* env, ErlNifUInt64 i) +{ + Uint* hp; + Uint need = 0; + erts_bld_uint64(NULL, &need, i); + hp = alloc_heap(env, need); + return erts_bld_uint64(&hp, NULL, i); +} +#endif /* HAVE_INT64 && SIZEOF_LONG != 8 */ + ERL_NIF_TERM enif_make_double(ErlNifEnv* env, double d) { Eterm* hp = alloc_heap(env,FLOAT_SIZE_OBJECT); diff --git a/erts/emulator/beam/erl_nif.h b/erts/emulator/beam/erl_nif.h index 936f03bce1..ee3a7cd5f4 100644 --- a/erts/emulator/beam/erl_nif.h +++ b/erts/emulator/beam/erl_nif.h @@ -66,6 +66,19 @@ extern "C" { #endif +#if (defined(__WIN32__) || defined(_WIN32) || defined(_WIN32_)) +typedef unsigned __int64 ErlNifUInt64; +typedef __int64 ErlNifSInt64; +#elif SIZEOF_LONG == 8 +typedef unsigned long ErlNifUInt64; +typedef long ErlNifSInt64; +#elif SIZEOF_LONG_LONG == 8 +typedef unsigned long long ErlNifUInt64; +typedef long long ErlNifSInt64; +#else +#error No 64-bit integer type +#endif + #ifdef HALFWORD_HEAP_EMULATOR typedef unsigned int ERL_NIF_TERM; #else diff --git a/erts/emulator/beam/erl_nif_api_funcs.h b/erts/emulator/beam/erl_nif_api_funcs.h index ef4e9580b0..eca506593d 100644 --- a/erts/emulator/beam/erl_nif_api_funcs.h +++ b/erts/emulator/beam/erl_nif_api_funcs.h @@ -122,6 +122,12 @@ ERL_NIF_API_FUNC_DECL(ErlNifPid*,enif_self,(ErlNifEnv* caller_env, ErlNifPid* pi ERL_NIF_API_FUNC_DECL(int,enif_get_local_pid,(ErlNifEnv* env, ERL_NIF_TERM, ErlNifPid* pid)); ERL_NIF_API_FUNC_DECL(void,enif_keep_resource,(void* obj)); ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_resource_binary,(ErlNifEnv*,void* obj,const void* data, size_t size)); +#if SIZEOF_LONG != 8 +ERL_NIF_API_FUNC_DECL(int,enif_get_int64,(ErlNifEnv*, ERL_NIF_TERM term, ErlNifSInt64* ip)); +ERL_NIF_API_FUNC_DECL(int,enif_get_uint64,(ErlNifEnv*, ERL_NIF_TERM term, ErlNifUInt64* ip)); +ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_int64,(ErlNifEnv*, ErlNifSInt64)); +ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_uint64,(ErlNifEnv*, ErlNifUInt64)); +#endif /* ** Add last to keep compatibility on Windows!!! @@ -230,6 +236,13 @@ ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_resource_binary,(ErlNifEnv*,void* o # define enif_get_local_pid ERL_NIF_API_FUNC_MACRO(enif_get_local_pid) # define enif_keep_resource ERL_NIF_API_FUNC_MACRO(enif_keep_resource) # define enif_make_resource_binary ERL_NIF_API_FUNC_MACRO(enif_make_resource_binary) +#if SIZEOF_LONG != 8 +# define enif_get_int64 ERL_NIF_API_FUNC_MACRO(enif_get_int64) +# define enif_get_uint64 ERL_NIF_API_FUNC_MACRO(enif_get_uint64) +# define enif_make_int64 ERL_NIF_API_FUNC_MACRO(enif_make_int64) +# define enif_make_uint64 ERL_NIF_API_FUNC_MACRO(enif_make_uint64) +#endif + #endif #ifndef enif_make_list1 @@ -253,5 +266,13 @@ ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_resource_binary,(ErlNifEnv*,void* o # define enif_make_tuple9(ENV,E1,E2,E3,E4,E5,E6,E7,E8,E9) enif_make_tuple(ENV,9,E1,E2,E3,E4,E5,E6,E7,E8,E9) # define enif_make_pid(ENV, PID) ((const ERL_NIF_TERM)((PID)->pid)) + +#if SIZEOF_LONG == 8 +# define enif_get_int64 enif_get_long +# define enif_get_uint64 enif_get_ulong +# define enif_make_int64 enif_make_long +# define enif_make_uint64 enif_make_ulong +#endif + #endif diff --git a/erts/emulator/beam/erl_process.c b/erts/emulator/beam/erl_process.c index a644520442..901167a315 100644 --- a/erts/emulator/beam/erl_process.c +++ b/erts/emulator/beam/erl_process.c @@ -54,7 +54,12 @@ (ERTS_SCHED_SYS_SLEEP_SPINCOUNT*ERTS_SCHED_TSE_SLEEP_SPINCOUNT_FACT) #define ERTS_SCHED_SUSPEND_SLEEP_SPINCOUNT 0 -#define ERTS_WAKEUP_OTHER_LIMIT (100*CONTEXT_REDS/2) +#define ERTS_WAKEUP_OTHER_LIMIT_VERY_HIGH (200*CONTEXT_REDS) +#define ERTS_WAKEUP_OTHER_LIMIT_HIGH (50*CONTEXT_REDS) +#define ERTS_WAKEUP_OTHER_LIMIT_MEDIUM (10*CONTEXT_REDS) +#define ERTS_WAKEUP_OTHER_LIMIT_LOW (CONTEXT_REDS) +#define ERTS_WAKEUP_OTHER_LIMIT_VERY_LOW (CONTEXT_REDS/10) + #define ERTS_WAKEUP_OTHER_DEC 10 #define ERTS_WAKEUP_OTHER_FIXED_INC (CONTEXT_REDS/10) @@ -112,6 +117,8 @@ Uint erts_no_schedulers; Uint erts_max_processes = ERTS_DEFAULT_MAX_PROCESSES; Uint erts_process_tab_index_mask; +static int wakeup_other_limit; + #ifdef ERTS_SMP Uint erts_max_main_threads; #endif @@ -821,7 +828,11 @@ empty_runq(ErtsRunQueue *rq) if (oifls & ERTS_RUNQ_IFLG_NONEMPTY) { #ifdef DEBUG long empty = erts_smp_atomic_read(&no_empty_run_queues); - ASSERT(0 <= empty && empty < erts_no_run_queues); + /* + * For a short period of time no_empty_run_queues may have + * been increased twice for a specific run queue. + */ + ASSERT(0 <= empty && empty < 2*erts_no_run_queues); #endif erts_smp_atomic_inc(&no_empty_run_queues); } @@ -834,7 +845,11 @@ non_empty_runq(ErtsRunQueue *rq) if (!(oifls & ERTS_RUNQ_IFLG_NONEMPTY)) { #ifdef DEBUG long empty = erts_smp_atomic_read(&no_empty_run_queues); - ASSERT(0 < empty && empty <= erts_no_run_queues); + /* + * For a short period of time no_empty_run_queues may have + * been increased twice for a specific run queue. + */ + ASSERT(0 < empty && empty <= 2*erts_no_run_queues); #endif erts_smp_atomic_dec(&no_empty_run_queues); } @@ -2365,8 +2380,28 @@ void erts_early_init_scheduling(void) { early_cpu_bind_init(); + wakeup_other_limit = ERTS_WAKEUP_OTHER_LIMIT_MEDIUM; } +int +erts_sched_set_wakeup_limit(char *str) +{ + if (sys_strcmp(str, "very_high") == 0) + wakeup_other_limit = ERTS_WAKEUP_OTHER_LIMIT_VERY_HIGH; + else if (sys_strcmp(str, "high") == 0) + wakeup_other_limit = ERTS_WAKEUP_OTHER_LIMIT_HIGH; + else if (sys_strcmp(str, "medium") == 0) + wakeup_other_limit = ERTS_WAKEUP_OTHER_LIMIT_MEDIUM; + else if (sys_strcmp(str, "low") == 0) + wakeup_other_limit = ERTS_WAKEUP_OTHER_LIMIT_LOW; + else if (sys_strcmp(str, "very_low") == 0) + wakeup_other_limit = ERTS_WAKEUP_OTHER_LIMIT_VERY_LOW; + else + return EINVAL; + return 0; +} + + void erts_init_scheduling(int mrq, int no_schedulers, int no_schedulers_online) { @@ -3962,13 +3997,13 @@ check_cpu_bind(ErtsSchedulerData *esdp) goto unbind; } } - else if (cpu_id < 0 && scheduler2cpu_map[esdp->no].bound_id >= 0) { + else if (cpu_id < 0) { unbind: /* Get rid of old binding */ res = erts_unbind_from_cpu(erts_cpuinfo); if (res == 0) esdp->cpu_id = scheduler2cpu_map[esdp->no].bound_id = -1; - else { + else if (res != -ENOTSUP) { erts_dsprintf_buf_t *dsbufp = erts_create_logger_dsbuf(); erts_dsprintf(dsbufp, "Scheduler %d failed to unbind from cpu %d: %s\n", (int) esdp->no, cpu_id, erl_errno_id(-res)); @@ -4001,7 +4036,7 @@ signal_schedulers_bind_change(erts_cpu_topology_t *cpudata, int size) int s_ix = 1; int cpu_ix; - if (cpu_bind_order != ERTS_CPU_BIND_NONE) { + if (cpu_bind_order != ERTS_CPU_BIND_NONE && size) { cpu_bind_order_sort(cpudata, size, cpu_bind_order, 1); @@ -5515,12 +5550,50 @@ late_cpu_bind_init(void) erts_cpu_topology_t *cpudata; int cpudata_size; create_tmp_cpu_topology_copy(&cpudata, &cpudata_size); - ASSERT(cpudata); signal_schedulers_bind_change(cpudata, cpudata_size); destroy_tmp_cpu_topology_copy(cpudata); } } +int +erts_update_cpu_info(void) +{ + int changed; + erts_smp_rwmtx_rwlock(&erts_cpu_bind_rwmtx); + changed = erts_cpu_info_update(erts_cpuinfo); + if (changed) { + erts_cpu_topology_t *cpudata; + int cpudata_size; + + if (system_cpudata) + erts_free(ERTS_ALC_T_CPUDATA, system_cpudata); + + system_cpudata_size = erts_get_cpu_topology_size(erts_cpuinfo); + if (!system_cpudata_size) + system_cpudata = NULL; + else { + system_cpudata = erts_alloc(ERTS_ALC_T_CPUDATA, + (sizeof(erts_cpu_topology_t) + * system_cpudata_size)); + + if (!erts_get_cpu_topology(erts_cpuinfo, system_cpudata) + || (ERTS_INIT_CPU_TOPOLOGY_OK + != verify_topology(system_cpudata, + system_cpudata_size))) { + erts_free(ERTS_ALC_T_CPUDATA, system_cpudata); + system_cpudata = NULL; + system_cpudata_size = 0; + } + } + + create_tmp_cpu_topology_copy(&cpudata, &cpudata_size); + signal_schedulers_bind_change(cpudata, cpudata_size); + destroy_tmp_cpu_topology_copy(cpudata); + } + erts_smp_rwmtx_rwunlock(&erts_cpu_bind_rwmtx); + return changed; +} + #ifdef ERTS_SMP static void @@ -7123,7 +7196,7 @@ Process *schedule(Process *p, int calls) if (rq->wakeup_other < 0) rq->wakeup_other = 0; } - else if (rq->wakeup_other < ERTS_WAKEUP_OTHER_LIMIT) + else if (rq->wakeup_other < wakeup_other_limit) rq->wakeup_other += rq->len*wo_reds + ERTS_WAKEUP_OTHER_FIXED_INC; else { if (erts_common_run_queue) { @@ -7799,6 +7872,7 @@ erl_create_process(Process* parent, /* Parent of process (default group leader). p->bin_vheap_sz = p->min_vheap_size; p->bin_old_vheap_sz = p->min_vheap_size; p->bin_old_vheap = 0; + p->bin_vheap_mature = 0; /* No need to initialize p->fcalls. */ @@ -8051,6 +8125,7 @@ void erts_init_empty_process(Process *p) p->bin_vheap_sz = BIN_VH_MIN_SIZE; p->bin_old_vheap_sz = BIN_VH_MIN_SIZE; p->bin_old_vheap = 0; + p->bin_vheap_mature = 0; #ifdef ERTS_SMP p->u.ptimer = NULL; p->bound_runq = NULL; diff --git a/erts/emulator/beam/erl_process.h b/erts/emulator/beam/erl_process.h index c3fef6d38e..4365e409e5 100644 --- a/erts/emulator/beam/erl_process.h +++ b/erts/emulator/beam/erl_process.h @@ -537,6 +537,7 @@ struct ErtsPendingSuspend_ { # define MIN_VHEAP_SIZE(p) (p)->min_vheap_size # define BIN_VHEAP_SZ(p) (p)->bin_vheap_sz +# define BIN_VHEAP_MATURE(p) (p)->bin_vheap_mature # define BIN_OLD_VHEAP_SZ(p) (p)->bin_old_vheap_sz # define BIN_OLD_VHEAP(p) (p)->bin_old_vheap @@ -654,9 +655,10 @@ struct process { Uint mbuf_sz; /* Size of all message buffers */ ErtsPSD *psd; /* Rarely used process specific data */ - Uint bin_vheap_sz; /* Virtual heap block size for binaries */ - Uint bin_old_vheap_sz; /* Virtual old heap block size for binaries */ - Uint bin_old_vheap; /* Virtual old heap size for binaries */ + Uint64 bin_vheap_sz; /* Virtual heap block size for binaries */ + Uint64 bin_vheap_mature; /* Virtual heap block size for binaries */ + Uint64 bin_old_vheap_sz; /* Virtual old heap block size for binaries */ + Uint64 bin_old_vheap; /* Virtual old heap size for binaries */ union { #ifdef ERTS_SMP @@ -1025,6 +1027,7 @@ int erts_init_scheduler_bind_type(char *how); #define ERTS_INIT_CPU_TOPOLOGY_MISSING 9 int erts_init_cpu_topology(char *topology_str); +int erts_update_cpu_info(void); void erts_pre_init_process(void); void erts_late_init_process(void); @@ -1035,6 +1038,8 @@ ErtsProcList *erts_proclist_create(Process *); void erts_proclist_destroy(ErtsProcList *); int erts_proclist_same(ErtsProcList *, Process *); +int erts_sched_set_wakeup_limit(char *str); + #ifdef DEBUG void erts_dbg_multi_scheduling_return_trap(Process *, Eterm); #endif diff --git a/erts/emulator/beam/erl_time_sup.c b/erts/emulator/beam/erl_time_sup.c index c15f85f8f1..7b8706ea13 100644 --- a/erts/emulator/beam/erl_time_sup.c +++ b/erts/emulator/beam/erl_time_sup.c @@ -650,6 +650,22 @@ local_to_univ(Sint *year, Sint *month, Sint *day, t.tm_sec = *second; t.tm_isdst = isdst; the_clock = mktime(&t); + if (the_clock == -1) { + if (isdst) { + /* If this is a timezone without DST and the OS (correctly) + refuses to give us a DST time, we simulate the Linux/Solaris + behaviour of giving the same data as if is_dst was not set. */ + t.tm_isdst = 0; + the_clock = mktime(&t); + if (the_clock == -1) { + /* Failed anyway, something else is bad - will be a badarg */ + return 0; + } + } else { + /* Something else is the matter, badarg. */ + return 0; + } + } #ifdef HAVE_GMTIME_R gmtime_r(&the_clock, (tm = &tmbuf)); #else @@ -663,6 +679,10 @@ local_to_univ(Sint *year, Sint *month, Sint *day, *second = tm->tm_sec; return 1; } +#if defined(HAVE_POSIX2TIME) && defined(HAVE_DECL_POSIX2TIME) && \ + !HAVE_DECL_POSIX2TIME +extern time_t posix2time(time_t); +#endif int univ_to_local(Sint *year, Sint *month, Sint *day, diff --git a/erts/emulator/beam/global.h b/erts/emulator/beam/global.h index 064dc69da8..280421952e 100644 --- a/erts/emulator/beam/global.h +++ b/erts/emulator/beam/global.h @@ -1026,7 +1026,7 @@ void print_pass_through(int, byte*, int); /* beam_emu.c */ int catchlevel(Process*); -void init_emulator(_VOID_); +void init_emulator(void); void process_main(void); Eterm build_stacktrace(Process* c_p, Eterm exc); Eterm expand_error_value(Process* c_p, Uint freason, Eterm Value); @@ -1686,7 +1686,7 @@ int io_list_to_buf(Eterm, char*, int); int io_list_to_buf2(Eterm, char*, int); int io_list_len(Eterm); int is_string(Eterm); -void erl_at_exit(FUNCTION(void,(*),(void*)), void*); +void erl_at_exit(void (*) (void*), void*); Eterm collect_memory(Process *); void dump_memory_to_fd(int); int dump_memory_data(const char *); diff --git a/erts/emulator/beam/io.c b/erts/emulator/beam/io.c index b840f65cdd..79022d5dd7 100644 --- a/erts/emulator/beam/io.c +++ b/erts/emulator/beam/io.c @@ -1582,7 +1582,7 @@ static void deliver_read_message(Port* prt, Eterm to, pb->flags = 0; hp += PROC_BIN_SIZE; - ohp->overhead += pb->size / sizeof(Eterm); + OH_OVERHEAD(ohp, pb->size / sizeof(Eterm)); listp = make_binary(pb); } @@ -1732,7 +1732,7 @@ deliver_vec_message(Port* prt, /* Port */ pb->flags = 0; hp += PROC_BIN_SIZE; - ohp->overhead += iov->iov_len / sizeof(Eterm); + OH_OVERHEAD(ohp, iov->iov_len / sizeof(Eterm)); if (listp == NIL) { /* compatible with deliver_bin_message */ listp = make_binary(pb); @@ -2264,7 +2264,7 @@ erts_port_control(Process* p, Port* prt, Uint command, Eterm iolist) pb->val = ErlDrvBinary2Binary(dbin); pb->bytes = (byte*) dbin->orig_bytes; pb->flags = 0; - MSO(p).overhead += dbin->orig_size / sizeof(Eterm); + OH_OVERHEAD(&(MSO(p)), dbin->orig_size / sizeof(Eterm)); return make_binary(pb); } port_resp = dbin->orig_bytes; @@ -3040,7 +3040,7 @@ driver_deliver_term(ErlDrvPort port, pb->flags = 0; mess = make_binary(pb); hp += PROC_BIN_SIZE; - ohp->overhead += pb->size / sizeof(Eterm); + OH_OVERHEAD(ohp, pb->size / sizeof(Eterm)); } ptr += 3; break; @@ -3077,7 +3077,7 @@ driver_deliver_term(ErlDrvPort port, pbp->val = bp; pbp->bytes = (byte*) bp->orig_bytes; pbp->flags = 0; - ohp->overhead += (pbp->size / sizeof(Eterm)); + OH_OVERHEAD(ohp, pbp->size / sizeof(Eterm)); mess = make_binary(pbp); } ptr += 2; diff --git a/erts/emulator/beam/sys.h b/erts/emulator/beam/sys.h index eac38674e7..0031568af6 100644 --- a/erts/emulator/beam/sys.h +++ b/erts/emulator/beam/sys.h @@ -25,14 +25,6 @@ # define NO_FPE_SIGNALS #endif -/* Never use elib-malloc when purify-memory-tracing */ -#if defined(PURIFY) -#undef ENABLE_ELIB_MALLOC -#undef ELIB_HEAP_SBRK -#undef ELIB_ALLOC_IS_CLIB -#endif - - /* xxxP __VXWORKS__ */ #ifdef VXWORKS #include <vxWorks.h> @@ -171,23 +163,6 @@ void erl_assert_error(char* expr, char* file, int line); #include <stdarg.h> -#if defined(__STDC__) || defined(_MSC_VER) -# define EXTERN_FUNCTION(t, f, x) extern t f x -# define FUNCTION(t, f, x) t f x -# define _DOTS_ ... -# define _VOID_ void -#elif defined(__cplusplus) -# define EXTERN_FUNCTION(f, x) extern "C" { f x } -# define FUNCTION(t, f, x) t f x -# define _DOTS_ ... -# define _VOID_ void -#else -# define EXTERN_FUNCTION(t, f, x) extern t f (/*x*/) -# define FUNCTION(t, f, x) t f (/*x*/) -# define _DOTS_ -# define _VOID_ -#endif - /* This isn't sys-dependent, but putting it here benefits sys.c and drivers - allow use of 'const' regardless of compiler */ @@ -197,7 +172,7 @@ void erl_assert_error(char* expr, char* file, int line); #ifdef VXWORKS /* Replace VxWorks' printf with a real one that does fprintf(stdout, ...) */ -EXTERN_FUNCTION(int, real_printf, (const char *fmt, ...)); +int real_printf(const char *fmt, ...); # define printf real_printf #endif @@ -660,12 +635,12 @@ extern void erl_sys_args(int *argc, char **argv); extern void erl_sys_schedule(int); void sys_tty_reset(int); -EXTERN_FUNCTION(int, sys_max_files, (_VOID_)); +int sys_max_files(void); void sys_init_io(void); Preload* sys_preloaded(void); -EXTERN_FUNCTION(unsigned char*, sys_preload_begin, (Preload*)); -EXTERN_FUNCTION(void, sys_preload_end, (Preload*)); -EXTERN_FUNCTION(int, sys_get_key, (int)); +unsigned char* sys_preload_begin(Preload*); +void sys_preload_end(Preload*); +int sys_get_key(int); void elapsed_time_both(unsigned long *ms_user, unsigned long *ms_sys, unsigned long *ms_user_diff, unsigned long *ms_sys_diff); void wall_clock_elapsed_time_both(unsigned long *ms_total, @@ -682,7 +657,7 @@ int local_to_univ(Sint *year, Sint *month, Sint *day, Sint *hour, Sint *minute, Sint *second, int isdst); void get_now(Uint*, Uint*, Uint*); void get_sys_now(Uint*, Uint*, Uint*); -EXTERN_FUNCTION(void, set_break_quit, (void (*)(void), void (*)(void))); +void set_break_quit(void (*)(void), void (*)(void)); void os_flavor(char*, unsigned); void os_version(int*, int*, int*); @@ -722,7 +697,7 @@ int erts_write_env(char *key, char *value); #define ERTS_DEFAULT_MMAP_THRESHOLD (128 * 1024) #define ERTS_DEFAULT_MMAP_MAX 64 -EXTERN_FUNCTION(int, sys_alloc_opt, (int, int)); +int sys_alloc_opt(int, int); typedef struct { Sint trim_threshold; @@ -731,7 +706,7 @@ typedef struct { Sint mmap_max; } SysAllocStat; -EXTERN_FUNCTION(void, sys_alloc_stat, (SysAllocStat *)); +void sys_alloc_stat(SysAllocStat *); /* Block the whole system... */ @@ -1120,13 +1095,10 @@ erts_refc_read(erts_refc_t *refcp, long min_val) extern int erts_use_kernel_poll; #endif -void elib_ensure_initialized(void); - - #if defined(VXWORKS) /* NOTE! sys_calloc2 does not exist on other platforms than VxWorks and OSE */ -EXTERN_FUNCTION(void*, sys_calloc2, (Uint, Uint)); +void* sys_calloc2(Uint, Uint); #endif /* VXWORKS || OSE */ @@ -1218,8 +1190,8 @@ EXTERN_FUNCTION(void*, sys_calloc2, (Uint, Uint)); */ #ifdef DEBUG -EXTERN_FUNCTION(void, erl_debug, (char* format, ...)); -EXTERN_FUNCTION(void, erl_bin_write, (unsigned char *, int, int)); +void erl_debug(char* format, ...); +void erl_bin_write(unsigned char *, int, int); # define DEBUGF(x) erl_debug x #else diff --git a/erts/emulator/beam/utils.c b/erts/emulator/beam/utils.c index 25472ef47a..ab5e8b5d4a 100644 --- a/erts/emulator/beam/utils.c +++ b/erts/emulator/beam/utils.c @@ -48,11 +48,11 @@ #undef M_MMAP_THRESHOLD #undef M_MMAP_MAX -#if !defined(ELIB_ALLOC_IS_CLIB) && defined(__GLIBC__) && defined(HAVE_MALLOC_H) +#if defined(__GLIBC__) && defined(HAVE_MALLOC_H) #include <malloc.h> #endif -#if defined(ELIB_ALLOC_IS_CLIB) || !defined(HAVE_MALLOPT) +#if !defined(HAVE_MALLOPT) #undef HAVE_MALLOPT #define HAVE_MALLOPT 0 #endif diff --git a/erts/emulator/drivers/common/efile_drv.c b/erts/emulator/drivers/common/efile_drv.c index 60ae4cb108..c450f10f48 100644 --- a/erts/emulator/drivers/common/efile_drv.c +++ b/erts/emulator/drivers/common/efile_drv.c @@ -104,7 +104,7 @@ #include <ctype.h> #include <sys/types.h> -extern void erl_exit(int n, char *fmt, _DOTS_); +void erl_exit(int n, char *fmt, ...); static ErlDrvSysInfo sys_info; diff --git a/erts/emulator/drivers/common/inet_drv.c b/erts/emulator/drivers/common/inet_drv.c index 0ea54930ba..3f761eeb19 100644 --- a/erts/emulator/drivers/common/inet_drv.c +++ b/erts/emulator/drivers/common/inet_drv.c @@ -48,6 +48,12 @@ #include <sys/uio.h> #endif +#ifdef HAVE_NET_IF_DL_H +#include <net/if_dl.h> +#endif +#ifdef HAVE_IFADDRS_H +#include <ifaddrs.h> +#endif /* All platforms fail on malloc errors. */ #define FATAL_MALLOC @@ -1045,7 +1051,7 @@ struct erl_drv_entry inet_driver_entry = }; /* XXX: is this a driver interface function ??? */ -extern void erl_exit(int n, char*, _DOTS_); +void erl_exit(int n, char*, ...); /* * Malloc wrapper, @@ -3905,7 +3911,7 @@ static int inet_ctl_ifget(inet_descriptor* desc, char* buf, int len, INTERFACE_INFO* ifp; long namaddr; - if ((len == 0) || ((namlen = buf[0]) > len)) + if ((len == 0) || ((namlen = get_int8(buf)) > len)) goto error; if (parse_addr(buf+1, namlen, &namaddr) < 0) goto error; @@ -4089,6 +4095,10 @@ static int inet_ctl_getiflist(inet_descriptor* desc, char** rbuf, int rsize) } +/* FIXME: temporary hack */ +#ifndef IFHWADDRLEN +#define IFHWADDRLEN 6 +#endif static int inet_ctl_ifget(inet_descriptor* desc, char* buf, int len, char** rbuf, int rsize) @@ -4099,11 +4109,11 @@ static int inet_ctl_ifget(inet_descriptor* desc, char* buf, int len, struct ifreq ifreq; int namlen; - if ((len == 0) || ((namlen = buf[0]) > len)) + if ((len == 0) || ((namlen = get_int8(buf)) > len)) goto error; sys_memset(ifreq.ifr_name, '\0', IFNAMSIZ); sys_memcpy(ifreq.ifr_name, buf+1, - (namlen > IFNAMSIZ) ? IFNAMSIZ : namlen); + (namlen >= IFNAMSIZ) ? IFNAMSIZ-1 : namlen); buf += (namlen+1); len -= (namlen+1); sptr = sbuf; @@ -4128,6 +4138,32 @@ static int inet_ctl_ifget(inet_descriptor* desc, char* buf, int len, /* raw memcpy (fix include autoconf later) */ sys_memcpy(sptr, (char*)(&ifreq.ifr_hwaddr.sa_data), IFHWADDRLEN); sptr += IFHWADDRLEN; +#elif defined(HAVE_GETIFADDRS) + struct ifaddrs *ifa, *ifp; + int found = 0; + + if (getifaddrs(&ifa) == -1) + goto error; + + for (ifp = ifa; ifp; ifp = ifp->ifa_next) { + if ((ifp->ifa_addr->sa_family == AF_LINK) && + (sys_strcmp(ifp->ifa_name, ifreq.ifr_name) == 0)) { + found = 1; + break; + } + } + + if (found == 0) { + freeifaddrs(ifa); + break; + } + + buf_check(sptr, s_end, 1+IFHWADDRLEN); + *sptr++ = INET_IFOPT_HWADDR; + sys_memcpy(sptr, ((struct sockaddr_dl *)ifp->ifa_addr)->sdl_data + + ((struct sockaddr_dl *)ifp->ifa_addr)->sdl_nlen, IFHWADDRLEN); + freeifaddrs(ifa); + sptr += IFHWADDRLEN; #endif break; } @@ -4240,10 +4276,6 @@ static int inet_ctl_ifget(inet_descriptor* desc, char* buf, int len, return ctl_error(EINVAL, rbuf, rsize); } -/* FIXME: temporary hack */ -#ifndef IFHWADDRLEN -#define IFHWADDRLEN 6 -#endif static int inet_ctl_ifset(inet_descriptor* desc, char* buf, int len, char** rbuf, int rsize) @@ -4252,11 +4284,11 @@ static int inet_ctl_ifset(inet_descriptor* desc, char* buf, int len, int namlen; char* b_end = buf + len; - if ((len == 0) || ((namlen = buf[0]) > len)) + if ((len == 0) || ((namlen = get_int8(buf)) > len)) goto error; sys_memset(ifreq.ifr_name, '\0', IFNAMSIZ); sys_memcpy(ifreq.ifr_name, buf+1, - (namlen > IFNAMSIZ) ? IFNAMSIZ : namlen); + (namlen >= IFNAMSIZ) ? IFNAMSIZ-1 : namlen); buf += (namlen+1); len -= (namlen+1); @@ -5032,8 +5064,8 @@ static int sctp_set_opts(inet_descriptor* desc, char* ptr, int len) } case INET_OPT_LINGER: { - CHKLEN(curr, ASSOC_ID_LEN + 2 + 4); - arg.lin.l_onoff = get_int16 (curr); curr += 2; + CHKLEN(curr, 2*4); + arg.lin.l_onoff = get_int32 (curr); curr += 4; arg.lin.l_linger = get_int32 (curr); curr += 4; proto = SOL_SOCKET; @@ -6193,6 +6225,10 @@ static int sctp_fill_opts(inet_descriptor* desc, char* buf, int buflen, struct sctp_sndrcvinfo sri; unsigned int sz = sizeof(sri); + if (buflen < ASSOC_ID_LEN) RETURN_ERROR(spec, -EINVAL); + sri.sinfo_assoc_id = GET_ASSOC_ID(buf); + buf += ASSOC_ID_LEN; + buflen -= ASSOC_ID_LEN; if (sock_getopt(desc->s, IPPROTO_SCTP, SCTP_DEFAULT_SEND_PARAM, &sri, &sz) < 0) continue; /* Fill in the response: */ @@ -6847,13 +6883,13 @@ static int inet_ctl(inet_descriptor* desc, int cmd, char* buf, int len, if (len < 2) return ctl_error(EINVAL, rbuf, rsize); - n = buf[0]; buf++; len--; + n = get_int8(buf); buf++; len--; if (n >= len) /* the = sign makes the test inklude next length byte */ return ctl_error(EINVAL, rbuf, rsize); memcpy(namebuf, buf, n); namebuf[n] = '\0'; len -= n; buf += n; - n = buf[0]; buf++; len--; + n = get_int8(buf); buf++; len--; if (n > len) return ctl_error(EINVAL, rbuf, rsize); memcpy(protobuf, buf, n); @@ -6876,7 +6912,7 @@ static int inet_ctl(inet_descriptor* desc, int cmd, char* buf, int len, port = get_int16(buf); port = sock_htons(port); buf += 2; - n = buf[0]; buf++; len -= 3; + n = get_int8(buf); buf++; len -= 3; if (n > len) return ctl_error(EINVAL, rbuf, rsize); memcpy(protobuf, buf, n); diff --git a/erts/emulator/drivers/unix/mem_drv.c b/erts/emulator/drivers/unix/mem_drv.c deleted file mode 100644 index 1417ca1121..0000000000 --- a/erts/emulator/drivers/unix/mem_drv.c +++ /dev/null @@ -1,145 +0,0 @@ -/* - * %CopyrightBegin% - * - * Copyright Ericsson AB 1996-2009. 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: Access to elib memory statistics */ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include "sys.h" -#include "erl_driver.h" -#include "elib_stat.h" - -#define MAP_BUF_SIZE 1000 /* Max map size */ -#define HISTO_BUF_SIZE 100 /* Max histogram buckets */ - -static ErlDrvData mem_start(ErlDrvPort); -static int mem_init(void); -static void mem_stop(ErlDrvData); -static void mem_command(ErlDrvData, char*, int); - -const struct driver_entry mem_driver_entry = { - mem_init, - mem_start, - mem_stop, - mem_command, - NULL, - NULL, - "mem_drv" -}; - -static int mem_init(void) -{ - return 0; -} - -static ErlDrvData mem_start(ErlDrvPort port, char* buf) -{ - return (ErlDrvData)port; -} - -static void mem_stop(ErlDrvData port) -{ -} - -void putint32(p, v) -byte* p; int v; -{ - p[0] = (v >> 24) & 0xff; - p[1] = (v >> 16) & 0xff; - p[2] = (v >> 8) & 0xff; - p[3] = (v) & 0xff; -} - -int getint16(p) -byte* p; -{ - return (p[0] << 8) | p[1]; -} - -/* -** Command: -** m L1 L0 -> a heap map of length L1*256 + L0 is returned -** s -> X3 X2 X1 X0 Y3 Y2 Y1 Y0 Z3 Z2 Z1 Z0 -** X == Total heap size bytes -** Y == Total free bytes -** Z == Size of largest free block in bytes -** -** h L1 L0 B0 -> Generate a logarithm historgram base B with L buckets -** l L1 L0 S0 -> Generate a linear histogram with step S with L buckets -*/ -unsigned char outbuf[HISTO_BUF_SIZE*2*4]; - -static void mem_command(ErlDrvData port, char* buf, int count) -{ - if ((count == 1) && buf[0] == 's') { - struct elib_stat info; - char v[3*4]; - - elib_stat(&info); - - putint32(v, info.mem_total*4); - putint32(v+4, info.mem_free*4); - putint32(v+8, info.max_free*4); - driver_output((ErlDrvPort)port, v, 12); - return; - } - else if ((count == 3) && buf[0] == 'm') { - char w[MAP_BUF_SIZE]; - int n = getint16(buf+1); - - if (n > MAP_BUF_SIZE) - n = MAP_BUF_SIZE; - elib_heap_map(w, n); - driver_output((ErlDrvPort)port, w, n); - return; - } - else if ((count == 4) && (buf[0] == 'h' || buf[0] == 'l')) { - unsigned long vf[HISTO_BUF_SIZE]; - unsigned long va[HISTO_BUF_SIZE]; - int n = getint16(buf+1); - int base = (unsigned char) buf[3]; - - if (n >= HISTO_BUF_SIZE) - n = HISTO_BUF_SIZE; - if (buf[0] == 'l') - base = -base; - if (elib_histo(vf, va, n, base) < 0) { - driver_failure((ErlDrvPort)port, -1); - return; - } - else { - char* p = outbuf; - int i; - - for (i = 0; i < n; i++) { - putint32(p, vf[i]); - p += 4; - } - for (i = 0; i < n; i++) { - putint32(p, va[i]); - p += 4; - } - driver_output((ErlDrvPort)port, outbuf, n*8); - } - return; - } - driver_failure((ErlDrvPort)port, -1); -} diff --git a/erts/emulator/drivers/unix/unix_efile.c b/erts/emulator/drivers/unix/unix_efile.c index 0052ac0739..b19f632f52 100644 --- a/erts/emulator/drivers/unix/unix_efile.c +++ b/erts/emulator/drivers/unix/unix_efile.c @@ -98,7 +98,7 @@ extern STATUS copy(char *, char *); #define EF_SAFE_REALLOC(P, S) ef_safe_realloc((P), (S)) #define EF_FREE(P) do { if((P)) driver_free((P)); } while(0) -extern void erl_exit(int n, char *fmt, _DOTS_); +void erl_exit(int n, char *fmt, ...); static void *ef_safe_alloc(Uint s) { @@ -127,7 +127,7 @@ static void *ef_safe_realloc(void *op, Uint s) (s[0] == '.' && (s[1] == '\0' || (s[1] == '.' && s[2] == '\0'))) #ifdef VXWORKS -static FUNCTION(int, vxworks_to_posix, (int vx_errno)); +static int vxworks_to_posix(int vx_errno); #endif /* @@ -146,7 +146,7 @@ static FUNCTION(int, vxworks_to_posix, (int vx_errno)); #define CHECK_PATHLEN(X,Y) /* Nothing */ #endif -static FUNCTION(int, check_error, (int result, Efile_error* errInfo)); +static int check_error(int result, Efile_error* errInfo); static int check_error(int result, Efile_error *errInfo) diff --git a/erts/emulator/drivers/win32/mem_drv.c b/erts/emulator/drivers/win32/mem_drv.c deleted file mode 100644 index fa7c46eca8..0000000000 --- a/erts/emulator/drivers/win32/mem_drv.c +++ /dev/null @@ -1,141 +0,0 @@ -/* - * %CopyrightBegin% - * - * Copyright Ericsson AB 1997-2009. 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: Access to elib memory statistics */ - -#include "sys.h" -#include "erl_driver.h" -#include "elib_stat.h" - -#define MAP_BUF_SIZE 1000 /* Max map size */ -#define HISTO_BUF_SIZE 100 /* Max histogram buckets */ - -static ErlDrvData mem_start(ErlDrvPort, char*); -static int mem_init(void); -static void mem_stop(ErlDrvData); -static void mem_command(ErlDrvData); - -ErlDrvEntry mem_driver_entry = { - mem_init, - mem_start, - mem_stop, - mem_command, - NULL, - NULL, - "mem_drv" -}; - -static int mem_init(void) -{ - return 0; -} - -static ErlDrvData mem_start(ErlDrvPort port, char* buf) -{ - return (ErlDrvData)port; -} - -static void mem_stop(ErlDrvData port) -{ -} - -void putint32(p, v) -byte* p; int v; -{ - p[0] = (v >> 24) & 0xff; - p[1] = (v >> 16) & 0xff; - p[2] = (v >> 8) & 0xff; - p[3] = (v) & 0xff; -} - -int getint16(p) -byte* p; -{ - return (p[0] << 8) | p[1]; -} - -/* -** Command: -** m L1 L0 -> a heap map of length L1*256 + L0 is returned -** s -> X3 X2 X1 X0 Y3 Y2 Y1 Y0 Z3 Z2 Z1 Z0 -** X == Total heap size bytes -** Y == Total free bytes -** Z == Size of largest free block in bytes -** -** h L1 L0 B0 -> Generate a logarithm histogram base B with L buckets -** l L1 L0 S0 -> Generate a linear histogram with step S with L buckets -*/ -unsigned char outbuf[HISTO_BUF_SIZE*2*4]; - -static void mem_command(ErlDrvData port, char* buf, int count) -{ - if ((count == 1) && buf[0] == 's') { - struct elib_stat info; - char v[3*4]; - - elib_stat(&info); - - putint32(v, info.mem_total*4); - putint32(v+4, info.mem_free*4); - putint32(v+8, info.max_free*4); - driver_output((ErlDrvPort)port, v, 12); - return; - } - else if ((count == 3) && buf[0] == 'm') { - char w[MAP_BUF_SIZE]; - int n = getint16(buf+1); - - if (n > MAP_BUF_SIZE) - n = MAP_BUF_SIZE; - elib_heap_map(w, n); - driver_output((ErlDrvPort)port, w, n); - return; - } - else if ((count == 4) && (buf[0] == 'h' || buf[0] == 'l')) { - unsigned long vf[HISTO_BUF_SIZE]; - unsigned long va[HISTO_BUF_SIZE]; - int n = getint16(buf+1); - int base = (unsigned char) buf[3]; - - if (n >= HISTO_BUF_SIZE) - n = HISTO_BUF_SIZE; - if (buf[0] == 'l') - base = -base; - if (elib_histo(vf, va, n, base) < 0) { - driver_failure((ErlDrvPort)port, -1); - return; - } - else { - char* p = outbuf; - int i; - - for (i = 0; i < n; i++) { - putint32(p, vf[i]); - p += 4; - } - for (i = 0; i < n; i++) { - putint32(p, va[i]); - p += 4; - } - driver_output((ErlDrvPort)port, outbuf, n*8); - } - return; - } - driver_failure((ErlDrvPort)port, -1); -} - diff --git a/erts/emulator/hipe/hipe_bif0.c b/erts/emulator/hipe/hipe_bif0.c index b0abfd2310..2a877d8ace 100644 --- a/erts/emulator/hipe/hipe_bif0.c +++ b/erts/emulator/hipe/hipe_bif0.c @@ -440,9 +440,12 @@ BIF_RETTYPE hipe_bifs_alloc_data_2(BIF_ALIST_2) align != sizeof(long) && align != sizeof(double))) BIF_ERROR(BIF_P, BADARG); nrbytes = unsigned_val(BIF_ARG_2); + if (nrbytes == 0) + BIF_RET(make_small(0)); block = erts_alloc(ERTS_ALC_T_HIPE, nrbytes); if ((unsigned long)block & (align-1)) - fprintf(stderr, "Yikes! erts_alloc() returned misaligned address %p\r\n", block); + fprintf(stderr, "%s: erts_alloc(%lu) returned %p which is not %lu-byte aligned\r\n", + __FUNCTION__, (unsigned long)nrbytes, block, (unsigned long)align); BIF_RET(address_to_term(block, BIF_P)); } diff --git a/erts/emulator/hipe/hipe_bif1.c b/erts/emulator/hipe/hipe_bif1.c index 5188950e17..8f43811537 100644 --- a/erts/emulator/hipe/hipe_bif1.c +++ b/erts/emulator/hipe/hipe_bif1.c @@ -876,22 +876,44 @@ BIF_RETTYPE hipe_bifs_misc_timer_clear_0(BIF_ALIST_0) * + The fallback, which is the same as {X,_} = runtime(statistics). */ +static double fallback_get_hrvtime(void) +{ + unsigned long ms_user; + + elapsed_time_both(&ms_user, NULL, NULL, NULL); + return (double)ms_user; +} + #if USE_PERFCTR #include "hipe_perfctr.h" -static int hrvtime_is_open; -#define hrvtime_is_started() hrvtime_is_open +static int hrvtime_started; /* 0: closed, +1: perfctr, -1: fallback */ +#define hrvtime_is_started() (hrvtime_started != 0) static void start_hrvtime(void) { if (hipe_perfctr_hrvtime_open() >= 0) - hrvtime_is_open = 1; + hrvtime_started = 1; + else + hrvtime_started = -1; } -#define get_hrvtime() hipe_perfctr_hrvtime_get() -#define stop_hrvtime() hipe_perfctr_hrvtime_close() +static void stop_hrvtime(void) +{ + if (hrvtime_started > 0) + hipe_perfctr_hrvtime_close(); + hrvtime_started = 0; +} -#else +static double get_hrvtime(void) +{ + if (hrvtime_started > 0) + return hipe_perfctr_hrvtime_get(); + else + return fallback_get_hrvtime(); +} + +#else /* !USE_PERFCTR */ /* * Fallback, if nothing better exists. @@ -902,15 +924,9 @@ static void start_hrvtime(void) #define hrvtime_is_started() 1 #define start_hrvtime() do{}while(0) #define stop_hrvtime() do{}while(0) +#define get_hrvtime() fallback_get_hrvtime() -static double get_hrvtime(void) -{ - unsigned long ms_user; - elapsed_time_both(&ms_user, NULL, NULL, NULL); - return (double)ms_user; -} - -#endif /* hrvtime support */ +#endif /* !USE_PERFCTR */ BIF_RETTYPE hipe_bifs_get_hrvtime_0(BIF_ALIST_0) { @@ -918,11 +934,8 @@ BIF_RETTYPE hipe_bifs_get_hrvtime_0(BIF_ALIST_0) Eterm res; FloatDef f; - if (!hrvtime_is_started()) { + if (!hrvtime_is_started()) start_hrvtime(); - if (!hrvtime_is_started()) - BIF_RET(NIL); /* arity 0 BIFs may not fail */ - } f.fd = get_hrvtime(); hp = HAlloc(BIF_P, FLOAT_SIZE_OBJECT); res = make_float(hp); diff --git a/erts/emulator/sys/common/erl_poll.c b/erts/emulator/sys/common/erl_poll.c index 09fb6337f7..c17806d96c 100644 --- a/erts/emulator/sys/common/erl_poll.c +++ b/erts/emulator/sys/common/erl_poll.c @@ -286,7 +286,7 @@ struct ErtsPollSet_ { ErtsPollSet next; int internal_fd_limit; ErtsFdStatus *fds_status; - int no_of_user_fds; + erts_smp_atomic_t no_of_user_fds; int fds_status_len; #if ERTS_POLL_USE_KERNEL_POLL int kp_fd; @@ -852,7 +852,7 @@ write_batch_buf(ErtsPollSet ps, ErtsPollBatchBuf *bbp) ps->fds_status[fd].flags |= ERTS_POLL_FD_FLG_USEFLBCK; ASSERT(ps->fds_status[fd].used_events); ps->fds_status[fd].used_events = 0; - ps->no_of_user_fds--; + erts_smp_atomic_dec(&ps->no_of_user_fds); update_fallback_pollset(ps, fd); ASSERT(ps->fds_status[fd].flags & ERTS_POLL_FD_FLG_INFLBCK); break; @@ -902,11 +902,11 @@ batch_update_pollset(ErtsPollSet ps, int fd, ErtsPollBatchBuf *bbp) events = ERTS_POLL_EV_E2N(ps->fds_status[fd].events); if (!events) { buf[buf_len].events = POLLREMOVE; - ps->no_of_user_fds--; + erts_smp_atomic_dec(&ps->no_of_user_fds); } else if (!ps->fds_status[fd].used_events) { buf[buf_len].events = events; - ps->no_of_user_fds++; + erts_smp_atomic_inc(&ps->no_of_user_fds); } else { if ((ps->fds_status[fd].flags & ERTS_POLL_FD_FLG_RST) @@ -996,12 +996,12 @@ batch_update_pollset(ErtsPollSet ps, int fd, ErtsPollBatchBuf *bbp) } if (used_events) { if (!events) { - ps->no_of_user_fds--; + erts_smp_atomic_dec(&ps->no_of_user_fds); } } else { if (events) - ps->no_of_user_fds++; + erts_smp_atomic_inc(&ps->no_of_user_fds); } ASSERT((events & ~(ERTS_POLL_EV_IN|ERTS_POLL_EV_OUT)) == 0); ASSERT((used_events & ~(ERTS_POLL_EV_IN|ERTS_POLL_EV_OUT)) == 0); @@ -1075,7 +1075,7 @@ update_pollset(ErtsPollSet ps, int fd) epe.data.fd = epe_templ.data.fd; res = epoll_ctl(ps->kp_fd, EPOLL_CTL_DEL, fd, &epe); } while (res != 0 && errno == EINTR); - ps->no_of_user_fds--; + erts_smp_atomic_dec(&ps->no_of_user_fds); ps->fds_status[fd].used_events = 0; } @@ -1083,11 +1083,11 @@ update_pollset(ErtsPollSet ps, int fd) /* A note on EPOLL_CTL_DEL: linux kernel versions before 2.6.9 need a non-NULL event pointer even though it is ignored... */ op = EPOLL_CTL_DEL; - ps->no_of_user_fds--; + erts_smp_atomic_dec(&ps->no_of_user_fds); } else if (!ps->fds_status[fd].used_events) { op = EPOLL_CTL_ADD; - ps->no_of_user_fds++; + erts_smp_atomic_inc(&ps->no_of_user_fds); } else { op = EPOLL_CTL_MOD; @@ -1137,7 +1137,7 @@ update_pollset(ErtsPollSet ps, int fd) /* Fall through ... */ case EPOLL_CTL_ADD: { ps->fds_status[fd].flags |= ERTS_POLL_FD_FLG_USEFLBCK; - ps->no_of_user_fds--; + erts_smp_atomic_dec(&ps->no_of_user_fds); #if ERTS_POLL_USE_CONCURRENT_UPDATE if (!*update_fallback) { *update_fallback = 1; @@ -1225,7 +1225,7 @@ static int update_pollset(ErtsPollSet ps, int fd) #if ERTS_POLL_USE_FALLBACK ASSERT(ps->fds_status[fd].flags & ERTS_POLL_FD_FLG_INFLBCK); #endif - ps->no_of_user_fds--; + erts_smp_atomic_dec(&ps->no_of_user_fds); last_pix = --ps->no_poll_fds; if (pix != last_pix) { /* Move last pix to this pix */ @@ -1252,7 +1252,7 @@ static int update_pollset(ErtsPollSet ps, int fd) ASSERT(!(ps->fds_status[fd].flags & ERTS_POLL_FD_FLG_INFLBCK) || fd == ps->kp_fd); #endif - ps->no_of_user_fds++; + erts_smp_atomic_inc(&ps->no_of_user_fds); ps->fds_status[fd].pix = pix = ps->no_poll_fds++; if (pix >= ps->poll_fds_len) grow_poll_fds(ps, pix); @@ -1303,7 +1303,7 @@ static int update_pollset(ErtsPollSet ps, int fd) if (!ps->fds_status[fd].used_events) { ASSERT(events); - ps->no_of_user_fds++; + erts_smp_atomic_inc(&ps->no_of_user_fds); #if ERTS_POLL_USE_FALLBACK ps->no_select_fds++; ps->fds_status[fd].flags |= ERTS_POLL_FD_FLG_INFLBCK; @@ -1311,7 +1311,7 @@ static int update_pollset(ErtsPollSet ps, int fd) } else if (!events) { ASSERT(ps->fds_status[fd].used_events); - ps->no_of_user_fds--; + erts_smp_atomic_dec(&ps->no_of_user_fds); ps->fds_status[fd].events = events; #if ERTS_POLL_USE_FALLBACK ps->no_select_fds--; @@ -1912,7 +1912,8 @@ static ERTS_INLINE int check_fd_events(ErtsPollSet ps, SysTimeval *tv, int max_res, int *ps_locked) { ASSERT(!*ps_locked); - if (ps->no_of_user_fds == 0 && tv->tv_usec == 0 && tv->tv_sec == 0) { + if (erts_smp_atomic_read(&ps->no_of_user_fds) == 0 + && tv->tv_usec == 0 && tv->tv_sec == 0) { /* Nothing to poll and zero timeout; done... */ return 0; } @@ -1950,7 +1951,7 @@ check_fd_events(ErtsPollSet ps, SysTimeval *tv, int max_res, int *ps_locked) * the maximum number of file descriptors in the poll set. */ struct dvpoll poll_res; - int nfds = ps->no_of_user_fds; + int nfds = (int) erts_smp_atomic_read(&ps->no_of_user_fds); #ifdef ERTS_SMP nfds++; /* Wakeup pipe */ #endif @@ -2228,7 +2229,7 @@ ERTS_POLL_EXPORT(erts_poll_create_pollset)(void) ps->internal_fd_limit = 0; ps->fds_status = NULL; ps->fds_status_len = 0; - ps->no_of_user_fds = 0; + erts_smp_atomic_init(&ps->no_of_user_fds, 0); #if ERTS_POLL_USE_KERNEL_POLL ps->kp_fd = -1; #if ERTS_POLL_USE_EPOLL @@ -2326,7 +2327,7 @@ ERTS_POLL_EXPORT(erts_poll_create_pollset)(void) #if ERTS_POLL_USE_FALLBACK ps->fallback_used = 0; #endif - ps->no_of_user_fds = 0; /* Don't count wakeup pipe and fallback fd */ + erts_smp_atomic_set(&ps->no_of_user_fds, 0); /* Don't count wakeup pipe and fallback fd */ erts_smp_spin_lock(&pollsets_lock); ps->next = pollsets; @@ -2472,7 +2473,7 @@ ERTS_POLL_EXPORT(erts_poll_info)(ErtsPollSet ps, ErtsPollInfo *pip) pip->memory_size = size; - pip->poll_set_size = ps->no_of_user_fds; + pip->poll_set_size = (int) erts_smp_atomic_read(&ps->no_of_user_fds); #ifdef ERTS_SMP pip->poll_set_size++; /* Wakeup pipe */ #endif diff --git a/erts/emulator/sys/unix/sys.c b/erts/emulator/sys/unix/sys.c index 400ef6c0ce..af4ab693dc 100644 --- a/erts/emulator/sys/unix/sys.c +++ b/erts/emulator/sys/unix/sys.c @@ -123,8 +123,6 @@ static ErtsSysReportExit *report_exit_transit_list; extern int check_async_ready(void); extern int driver_interrupt(int, int); -/*EXTERN_FUNCTION(void, increment_time, (int));*/ -/*EXTERN_FUNCTION(int, next_time, (_VOID_));*/ extern void do_break(void); extern void erl_sys_args(int*, char**); @@ -221,10 +219,10 @@ static struct fd_data { } *fd_data; /* indexed by fd */ /* static FUNCTION(int, write_fill, (int, char*, int)); unused? */ -static FUNCTION(void, note_child_death, (int, int)); +static void note_child_death(int, int); #if CHLDWTHR -static FUNCTION(void *, child_waiter, (void *)); +static void* child_waiter(void *); #endif /********************* General functions ****************************/ @@ -2562,7 +2560,6 @@ extern Preload pre_loaded[]; void erts_sys_alloc_init(void) { - elib_ensure_initialized(); } void *erts_sys_alloc(ErtsAlcType_t t, void *x, Uint sz) diff --git a/erts/emulator/sys/unix/sys_float.c b/erts/emulator/sys/unix/sys_float.c index 1ce81f8716..6e9376b0f3 100644 --- a/erts/emulator/sys/unix/sys_float.c +++ b/erts/emulator/sys/unix/sys_float.c @@ -820,8 +820,17 @@ sys_chars_to_double(char* buf, double* fp) } #ifdef NO_FPE_SIGNALS - if (errno == ERANGE && (*fp == 0.0 || *fp == HUGE_VAL || *fp == -HUGE_VAL)) { - return -1; + if (errno == ERANGE) { + if (*fp == HUGE_VAL || *fp == -HUGE_VAL) { + /* overflow, should give error */ + return -1; + } else if (t == s && *fp == 0.0) { + /* This should give 0.0 - OTP-7178 */ + errno = 0; + + } else if (*fp == 0.0) { + return -1; + } } #endif return 0; @@ -831,7 +840,9 @@ int matherr(struct exception *exc) { #if !defined(NO_FPE_SIGNALS) - set_current_fp_exception((unsigned long)__builtin_return_address(0)); + volatile unsigned long *fpexnp = erts_get_current_fp_exception(); + if (fpexnp != NULL) + *fpexnp = (unsigned long)__builtin_return_address(0); #endif return 1; } diff --git a/erts/emulator/sys/win32/sys.c b/erts/emulator/sys/win32/sys.c index 54f71b202d..15d4cd7361 100644 --- a/erts/emulator/sys/win32/sys.c +++ b/erts/emulator/sys/win32/sys.c @@ -37,7 +37,7 @@ void erts_sys_init_float(void); void erl_start(int, char**); -void erl_exit(int n, char*, _DOTS_); +void erl_exit(int n, char*, ...); void erl_error(char*, va_list); void erl_crash_dump(char*, int, char*, ...); @@ -67,10 +67,10 @@ static void async_read_file(struct async_io* aio, LPVOID buf, DWORD numToRead); static int async_write_file(struct async_io* aio, LPVOID buf, DWORD numToWrite); static int get_overlapped_result(struct async_io* aio, LPDWORD pBytesRead, BOOL wait); -static FUNCTION(BOOL, CreateChildProcess, (char *, HANDLE, HANDLE, - HANDLE, LPHANDLE, BOOL, - LPVOID, LPTSTR, unsigned, - char **, int *)); +static BOOL CreateChildProcess(char *, HANDLE, HANDLE, + HANDLE, LPHANDLE, BOOL, + LPVOID, LPTSTR, unsigned, + char **, int *); static int create_pipe(LPHANDLE, LPHANDLE, BOOL, BOOL); static int ApplicationType(const char* originalName, char fullPath[MAX_PATH], BOOL search_in_path, BOOL handle_quotes, @@ -93,7 +93,7 @@ static erts_smp_mtx_t sys_driver_data_lock; #define APPL_WIN3X 2 #define APPL_WIN32 3 -static FUNCTION(int, driver_write, (long, HANDLE, byte*, int)); +static int driver_write(long, HANDLE, byte*, int); static void common_stop(int); static int create_file_thread(struct async_io* aio, int mode); #ifdef ERTS_SMP @@ -2627,7 +2627,6 @@ erts_sys_main_thread(void) void erts_sys_alloc_init(void) { - elib_ensure_initialized(); } void *erts_sys_alloc(ErtsAlcType_t t, void *x, Uint sz) @@ -3002,7 +3001,6 @@ erts_sys_pre_init(void) } #endif erts_smp_atomic_init(&sys_misc_mem_sz, 0); - erts_sys_env_init(); } void noinherit_std_handle(DWORD type) @@ -3018,6 +3016,8 @@ void erl_sys_init(void) { HANDLE handle; + erts_sys_env_init(); + noinherit_std_handle(STD_OUTPUT_HANDLE); noinherit_std_handle(STD_INPUT_HANDLE); noinherit_std_handle(STD_ERROR_HANDLE); diff --git a/erts/emulator/test/float_SUITE.erl b/erts/emulator/test/float_SUITE.erl index 102e472ea6..99e9457985 100644 --- a/erts/emulator/test/float_SUITE.erl +++ b/erts/emulator/test/float_SUITE.erl @@ -22,7 +22,10 @@ -include("test_server.hrl"). -export([all/1,init_per_testcase/2,fin_per_testcase/2, - fpe/1,fp_drv/1,fp_drv_thread/1,denormalized/1,match/1,bad_float_unpack/1]). + fpe/1,fp_drv/1,fp_drv_thread/1,denormalized/1,match/1, + bad_float_unpack/1]). +-export([otp_7178/1]). + init_per_testcase(Func, Config) when is_atom(Func), is_list(Config) -> Dog = ?t:timetrap(?t:minutes(3)), @@ -33,7 +36,29 @@ fin_per_testcase(_Func, Config) -> ?t:timetrap_cancel(Dog). all(suite) -> - [fpe,fp_drv,fp_drv_thread,denormalized,match,bad_float_unpack]. + [fpe, + fp_drv, + fp_drv_thread, + otp_7178, + denormalized, + match, + bad_float_unpack]. + +%% +%% OTP-7178, list_to_float on very small numbers should give 0.0 +%% instead of exception, i.e. ignore underflow. +%% +otp_7178(suite) -> + []; +otp_7178(doc) -> + ["test that list_to_float on very small numbers give 0.0"]; +otp_7178(Config) when is_list(Config) -> + ?line X = list_to_float("1.0e-325"), + ?line true = (X < 0.00000001) and (X > -0.00000001), + ?line Y = list_to_float("1.0e-325325325"), + ?line true = (Y < 0.00000001) and (Y > -0.00000001), + ?line {'EXIT', {badarg,_}} = (catch list_to_float("1.0e83291083210")), + ok. %% Forces floating point exceptions and tests that subsequent, legal, %% operations are calculated correctly. Original version by Sebastian diff --git a/erts/emulator/test/nif_SUITE_data/nif_SUITE.c b/erts/emulator/test/nif_SUITE_data/nif_SUITE.c index 17f644829f..8489124966 100644 --- a/erts/emulator/test/nif_SUITE_data/nif_SUITE.c +++ b/erts/emulator/test/nif_SUITE_data/nif_SUITE.c @@ -296,6 +296,30 @@ static int test_ulong(ErlNifEnv* env, unsigned long i1) return 1; } +static int test_int64(ErlNifEnv* env, ErlNifSInt64 i1) +{ + ErlNifSInt64 i2 = 0; + ERL_NIF_TERM int_term = enif_make_int64(env, i1); + if (!enif_get_int64(env,int_term, &i2) || i1 != i2) { + fprintf(stderr, "test_int64(%ld) ...FAILED i2=%ld\r\n", + (long)i1, (long)i2); + return 0; + } + return 1; +} + +static int test_uint64(ErlNifEnv* env, ErlNifUInt64 i1) +{ + ErlNifUInt64 i2 = 0; + ERL_NIF_TERM int_term = enif_make_uint64(env, i1); + if (!enif_get_uint64(env,int_term, &i2) || i1 != i2) { + fprintf(stderr, "test_ulong(%lu) ...FAILED i2=%lu\r\n", + (unsigned long)i1, (unsigned long)i2); + return 0; + } + return 1; +} + static int test_double(ErlNifEnv* env, double d1) { double d2 = 0; @@ -319,6 +343,8 @@ static ERL_NIF_TERM type_test(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[ unsigned uint; long slong; unsigned long ulong; + ErlNifSInt64 sint64; + ErlNifUInt64 uint64; double d; ERL_NIF_TERM atom, ref1, ref2; @@ -352,11 +378,25 @@ static ERL_NIF_TERM type_test(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[ slong -= slong / 3 + 1; } while (slong >= 0); + sint64 = ((ErlNifSInt64)1 << 63); /* INT64_MIN */ + do { + if (!test_int64(env,sint64)) { + goto error; + } + sint64 += ~sint64 / 3 + 1; + } while (sint64 < 0); + sint64 = ((ErlNifUInt64)1 << 63) - 1; /* INT64_MAX */ + do { + if (!test_int64(env,sint64)) { + goto error; + } + sint64 -= sint64 / 3 + 1; + } while (sint64 >= 0); uint = UINT_MAX; for (;;) { if (!test_uint(env,uint)) { - + goto error; } if (uint == 0) break; uint -= uint / 3 + 1; @@ -364,11 +404,19 @@ static ERL_NIF_TERM type_test(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[ ulong = ULONG_MAX; for (;;) { if (!test_ulong(env,ulong)) { - + goto error; } if (ulong == 0) break; ulong -= ulong / 3 + 1; } + uint64 = (ErlNifUInt64)-1; /* UINT64_MAX */ + for (;;) { + if (!test_uint64(env,uint64)) { + goto error; + } + if (uint64 == 0) break; + uint64 -= uint64 / 3 + 1; + } if (MAX_SMALL < INT_MAX) { /* 32-bit */ for (i=-10 ; i <= 10; i++) { @@ -391,11 +439,18 @@ static ERL_NIF_TERM type_test(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[ for (i=-10 ; i < 10; i++) { if (!test_long(env,MAX_SMALL+i) || !test_ulong(env,MAX_SMALL+i) || - !test_long(env,MIN_SMALL+i)) { + !test_long(env,MIN_SMALL+i) || + !test_int64(env,MAX_SMALL+i) || !test_uint64(env,MAX_SMALL+i) || + !test_int64(env,MIN_SMALL+i)) { goto error; } + if (MAX_SMALL < INT_MAX) { + if (!test_int(env,MAX_SMALL+i) || !test_uint(env,MAX_SMALL+i) || + !test_int(env,MIN_SMALL+i)) { + goto error; + } + } } - for (d=3.141592e-100 ; d < 1e100 ; d *= 9.97) { if (!test_double(env,d) || !test_double(env,-d)) { goto error; @@ -974,8 +1029,11 @@ static ERL_NIF_TERM make_term_list0(struct make_term_info* mti, int n) static ERL_NIF_TERM make_term_resource(struct make_term_info* mti, int n) { void* resource = enif_alloc_resource(mti->resource_type, 10); + ERL_NIF_TERM term; fill(resource, 10, n); - return enif_make_resource(mti->dst_env, resource); + term = enif_make_resource(mti->dst_env, resource); + enif_release_resource(resource); + return term; } static ERL_NIF_TERM make_term_new_binary(struct make_term_info* mti, int n) { diff --git a/erts/emulator/test/scheduler_SUITE.erl b/erts/emulator/test/scheduler_SUITE.erl index 4f4458802c..06442bfad6 100644 --- a/erts/emulator/test/scheduler_SUITE.erl +++ b/erts/emulator/test/scheduler_SUITE.erl @@ -47,6 +47,7 @@ scheduler_bind/1, scheduler_bind_types/1, cpu_topology/1, + update_cpu_info/1, sct_cmd/1, sbt_cmd/1, scheduler_suspend/1, @@ -249,6 +250,7 @@ bound_loop(NS, N, M, Sched) -> scheduler_bind(suite) -> [scheduler_bind_types, cpu_topology, + update_cpu_info, sct_cmd, sbt_cmd]. @@ -772,6 +774,137 @@ cpu_topology_cmdline_test(Config, Topology, Cmd) -> ?line stop_node(Node), ?line ok. +update_cpu_info(Config) when is_list(Config) -> + ?line OldOnline = erlang:system_info(schedulers_online), + ?line OldAff = get_affinity_mask(), + ?line ?t:format("START - Affinity mask: ~p - Schedulers online: ~p - Scheduler bindings: ~p~n", + [OldAff, OldOnline, erlang:system_info(scheduler_bindings)]), + ?line case {erlang:system_info(logical_processors_available), OldAff} of + {Avail, _} when Avail == unknown; OldAff == unknown -> + %% Nothing much to test; just a smoke test + case erlang:system_info(update_cpu_info) of + unchanged -> ?line ok; + changed -> ?line ok + end; + _ -> + try + ?line adjust_schedulers_online(), + case erlang:system_info(schedulers_online) of + 1 -> + %% Nothing much to test; just a smoke test + ?line ok; + Onln0 -> + %% unset least significant bit + ?line Aff = (OldAff band (OldAff - 1)), + ?line set_affinity_mask(Aff), + ?line Onln1 = Onln0 - 1, + ?line case adjust_schedulers_online() of + {Onln0, Onln1} -> + ?line Onln1 = erlang:system_info(schedulers_online), + ?line receive after 500 -> ok end, + ?line ?t:format("TEST - Affinity mask: ~p - Schedulers online: ~p - Scheduler bindings: ~p~n", + [Aff, Onln1, erlang:system_info(scheduler_bindings)]), + ?line unchanged = adjust_schedulers_online(), + ?line ok; + Fail -> + ?line ?t:fail(Fail) + end + end + after + set_affinity_mask(OldAff), + adjust_schedulers_online(), + erlang:system_flag(schedulers_online, OldOnline), + receive after 500 -> ok end, + ?t:format("END - Affinity mask: ~p - Schedulers online: ~p - Scheduler bindings: ~p~n", + [get_affinity_mask(), + erlang:system_info(schedulers_online), + erlang:system_info(scheduler_bindings)]) + end + end. + +adjust_schedulers_online() -> + case erlang:system_info(update_cpu_info) of + unchanged -> + unchanged; + changed -> + Avail = erlang:system_info(logical_processors_available), + {erlang:system_flag(schedulers_online, Avail), Avail} + end. + +read_affinity(Data) -> + Exp = "pid " ++ os:getpid() ++ "'s current affinity mask", + case string:tokens(Data, ":") of + [Exp, DirtyAffinityStr] -> + AffinityStr = string:strip(string:strip(DirtyAffinityStr, + both, $ ), + both, $\n), + case catch erlang:list_to_integer(AffinityStr, 16) of + Affinity when is_integer(Affinity) -> + Affinity; + _ -> + bad + end; + _ -> + bad + end. + +get_affinity_mask(Port, Status, Affinity) when Status == unknown; + Affinity == unknown -> + receive + {Port,{data, Data}} -> + get_affinity_mask(Port, Status, read_affinity(Data)); + {Port,{exit_status,S}} -> + get_affinity_mask(Port, S, Affinity) + end; +get_affinity_mask(Port, Status, bad) -> + unknown; +get_affinity_mask(Port, Status, Affinity) -> + Affinity. + +get_affinity_mask() -> + case ?t:os_type() of + {unix, linux} -> + case catch open_port({spawn, "taskset -p " ++ os:getpid()}, + [exit_status]) of + Port when is_port(Port) -> + get_affinity_mask(Port, unknown, unknown); + _ -> + unknown + end; + _ -> + unknown + end. + +set_affinity_mask(Port, unknown) -> + receive + {Port,{data, _}} -> + set_affinity_mask(Port, unknown); + {Port,{exit_status,Status}} -> + set_affinity_mask(Port, Status) + end; +set_affinity_mask(Port, Status) -> + receive + {Port,{data, _}} -> + set_affinity_mask(Port, unknown) + after 0 -> + Status + end. + +set_affinity_mask(Mask) -> + Cmd = lists:flatten(["taskset -p ", + io_lib:format("~.16b", [Mask]), + " ", + os:getpid()]), + case catch open_port({spawn, Cmd}, [exit_status]) of + Port when is_port(Port) -> + case set_affinity_mask(Port, unknown) of + 0 -> ok; + _ -> exit(failed_to_set_affinity) + end; + _ -> + exit(failed_to_set_affinity) + end. + sct_cmd(Config) when is_list(Config) -> ?line Topology = ?TOPOLOGY_A_TERM, ?line OldRelFlags = clear_erl_rel_flags(), diff --git a/erts/emulator/test/time_SUITE.erl b/erts/emulator/test/time_SUITE.erl index 2ad1f0d201..095e9dd1af 100644 --- a/erts/emulator/test/time_SUITE.erl +++ b/erts/emulator/test/time_SUITE.erl @@ -34,6 +34,8 @@ consistency/1, now/1, now_unique/1, now_update/1, timestamp/1]). +-export([local_to_univ_utc/1]). + -include("test_server.hrl"). -export([linear_time/1]). @@ -53,7 +55,40 @@ -define(dst_timezone, 2). all(suite) -> [univ_to_local, local_to_univ, - bad_univ_to_local, bad_local_to_univ, consistency, now, timestamp]. + local_to_univ_utc, + bad_univ_to_local, bad_local_to_univ, + consistency, now, timestamp]. + +local_to_univ_utc(suite) -> + []; +local_to_univ_utc(doc) -> + ["Test that DST = true on timezones without DST is ignored"]; +local_to_univ_utc(Config) when is_list(Config) -> + case os:type() of + {unix,_} -> + %% TZ variable has a meaning + ?line {ok, Node} = + test_server:start_node(local_univ_utc,peer, + [{args, "-env TZ UTC"}]), + ?line {{2008,8,1},{0,0,0}} = + rpc:call(Node, + erlang,localtime_to_universaltime, + [{{2008, 8, 1}, {0, 0, 0}}, + false]), + ?line {{2008,8,1},{0,0,0}} = + rpc:call(Node, + erlang,localtime_to_universaltime, + [{{2008, 8, 1}, {0, 0, 0}}, + true]), + ?line [{{2008,8,1},{0,0,0}}] = + rpc:call(Node, + calendar,local_time_to_universal_time_dst, + [{{2008, 8, 1}, {0, 0, 0}}]), + ?line test_server:stop_node(Node), + ok; + _ -> + {skip,"Only valid on Unix"} + end. %% Tests conversion from univeral to local time. diff --git a/erts/epmd/src/epmd.c b/erts/epmd/src/epmd.c index 6ddf30efe3..9c2ce065bb 100644 --- a/erts/epmd/src/epmd.c +++ b/erts/epmd/src/epmd.c @@ -236,7 +236,7 @@ int main(int argc, char** argv) else usage(g); } - dbg_printf(g,0,"epmd running - daemon = %d",g->is_daemon); + dbg_printf(g,1,"epmd running - daemon = %d",g->is_daemon); #ifndef NO_SYSCONF if ((g->max_conn = sysconf(_SC_OPEN_MAX)) <= 0) diff --git a/erts/etc/common/erlexec.c b/erts/etc/common/erlexec.c index 76ce0a7e3c..c1fc2aebee 100644 --- a/erts/etc/common/erlexec.c +++ b/erts/etc/common/erlexec.c @@ -120,6 +120,7 @@ static char *plusM_other_switches[] = { static char *pluss_val_switches[] = { "bt", "ct", + "wt", "ss", NULL }; diff --git a/erts/etc/win32/cygwin_tools/vc/ld.sh b/erts/etc/win32/cygwin_tools/vc/ld.sh index ac39bf871c..b04935ed9b 100755 --- a/erts/etc/win32/cygwin_tools/vc/ld.sh +++ b/erts/etc/win32/cygwin_tools/vc/ld.sh @@ -3,7 +3,7 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 2002-2009. All Rights Reserved. +# Copyright Ericsson AB 2002-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 @@ -167,6 +167,9 @@ eval link.exe "$CMD" >/tmp/link.exe.${p}.1 2>/tmp/link.exe.${p}.2 RES=$? CMANIFEST=`cygpath $MANIFEST` if [ "$RES" = "0" -a -f "$CMANIFEST" ]; then + # Add stuff to manifest to turn off "virtualization" + sed -i "s/<\/assembly>/ <ms_asmv2:trustInfo xmlns:ms_asmv2=\"urn:schemas-microsoft-com:asm.v2\">\n <ms_asmv2:security>\n <ms_asmv2:requestedPrivileges>\n <ms_asmv2:requestedExecutionLevel level=\"AsInvoker\" uiAccess=\"false\"\/>\n <\/ms_asmv2:requestedPrivileges>\n <\/ms_asmv2:security>\n <\/ms_asmv2:trustInfo>\n<\/assembly>/" $CMANIFEST + eval mt.exe -nologo -manifest "$MANIFEST" -outputresource:"$OUTPUTRES" >>/tmp/link.exe.${p}.1 2>>/tmp/link.exe.${p}.2 RES=$? if [ "$RES" != "0" ]; then diff --git a/erts/include/internal/erl_misc_utils.h b/erts/include/internal/erl_misc_utils.h index 6b875ff824..507e1726f4 100644 --- a/erts/include/internal/erl_misc_utils.h +++ b/erts/include/internal/erl_misc_utils.h @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2006-2009. All Rights Reserved. + * Copyright Ericsson AB 2006-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 @@ -34,7 +34,7 @@ typedef struct { erts_cpu_info_t *erts_cpu_info_create(void); void erts_cpu_info_destroy(erts_cpu_info_t *cpuinfo); -void erts_cpu_info_update(erts_cpu_info_t *cpuinfo); +int erts_cpu_info_update(erts_cpu_info_t *cpuinfo); int erts_get_cpu_configured(erts_cpu_info_t *cpuinfo); int erts_get_cpu_online(erts_cpu_info_t *cpuinfo); int erts_get_cpu_available(erts_cpu_info_t *cpuinfo); @@ -51,6 +51,7 @@ int erts_unbind_from_cpu_str(char *str); int erts_milli_sleep(long); #ifdef __WIN32__ +int erts_map_win_error_to_errno(DWORD win_error); int erts_get_last_win_errno(void); #endif diff --git a/erts/lib_src/common/erl_misc_utils.c b/erts/lib_src/common/erl_misc_utils.c index d2ef7140a5..116c9886d8 100644 --- a/erts/lib_src/common/erl_misc_utils.c +++ b/erts/lib_src/common/erl_misc_utils.c @@ -21,10 +21,13 @@ #include "config.h" #endif +#if defined(__WIN32__) +# include <windows.h> +#endif + #include "erl_misc_utils.h" #if defined(__WIN32__) -# include <windows.h> #elif defined(VXWORKS) # include <selectLib.h> #else /* UNIX */ @@ -62,10 +65,10 @@ #if defined(HAVE_SCHED_xETAFFINITY) # include <sched.h> # define ERTS_HAVE_MISC_UTIL_AFFINITY_MASK__ -#define ERTS_MU_GET_PROC_AFFINITY__(CPUINFOP) \ +#define ERTS_MU_GET_PROC_AFFINITY__(CPUINFOP, CPUSET) \ (sched_getaffinity((CPUINFOP)->pid, \ sizeof(cpu_set_t), \ - &(CPUINFOP)->cpuset) != 0 ? -errno : 0) + (CPUSET)) != 0 ? -errno : 0) #define ERTS_MU_SET_THR_AFFINITY__(SETP) \ (sched_setaffinity(0, sizeof(cpu_set_t), (SETP)) != 0 ? -errno : 0) #elif defined(__WIN32__) @@ -99,6 +102,26 @@ static int read_topology(erts_cpu_info_t *cpuinfo); +#if defined(ERTS_HAVE_MISC_UTIL_AFFINITY_MASK__) +static int +cpu_sets_are_eq(cpu_set_t *x, cpu_set_t *y) +{ + int i; + for (i = 0; i < CPU_SETSIZE; i++) { + if (CPU_ISSET(i, x)) { + if (!CPU_ISSET(i, y)) + return 0; + } + else { + if (CPU_ISSET(i, y)) + return 0; + } + } + return 1; +} + +#endif + int erts_milli_sleep(long ms) { @@ -137,15 +160,15 @@ struct erts_cpu_info_t_ { #if defined(__WIN32__) static __forceinline int -get_proc_affinity(erts_cpu_info_t *cpuinfo) +get_proc_affinity(erts_cpu_info_t *cpuinfo, cpu_set_t *cpuset) { DWORD pamask, samask; if (GetProcessAffinityMask(GetCurrentProcess(), &pamask, &samask)) { - cpuinfo->cpuset = (cpu_set_t) pamask; + *cpuset = (cpu_set_t) pamask; return 0; } else { - cpuinfo->cpuset = (cpu_set_t) 0; + *cpuset = (cpu_set_t) 0; return -erts_get_last_win_errno(); } } @@ -179,6 +202,9 @@ erts_cpu_info_create(void) #endif cpuinfo->topology_size = 0; cpuinfo->topology = NULL; + cpuinfo->configured = -1; + cpuinfo->online = -1; + cpuinfo->available = -1; erts_cpu_info_update(cpuinfo); return cpuinfo; } @@ -203,34 +229,40 @@ erts_cpu_info_destroy(erts_cpu_info_t *cpuinfo) } } -void +int erts_cpu_info_update(erts_cpu_info_t *cpuinfo) { - cpuinfo->configured = 0; - cpuinfo->online = 0; - cpuinfo->available = 0; + int changed = 0; + int configured = 0; + int online = 0; + int available = 0; + erts_cpu_topology_t *old_topology; + int old_topology_size; +#if defined(ERTS_HAVE_MISC_UTIL_AFFINITY_MASK__) + cpu_set_t cpuset; +#endif #ifdef __WIN32__ { int i; SYSTEM_INFO sys_info; GetSystemInfo(&sys_info); - cpuinfo->configured = (int) sys_info.dwNumberOfProcessors; + configured = (int) sys_info.dwNumberOfProcessors; for (i = 0; i < sizeof(DWORD)*8; i++) if (sys_info.dwActiveProcessorMask & (((DWORD) 1) << i)) - cpuinfo->online++; + online++; } #elif !defined(NO_SYSCONF) && (defined(_SC_NPROCESSORS_CONF) \ || defined(_SC_NPROCESSORS_ONLN)) #ifdef _SC_NPROCESSORS_CONF - cpuinfo->configured = (int) sysconf(_SC_NPROCESSORS_CONF); - if (cpuinfo->configured < 0) - cpuinfo->configured = 0; + configured = (int) sysconf(_SC_NPROCESSORS_CONF); + if (configured < 0) + configured = 0; #endif #ifdef _SC_NPROCESSORS_ONLN - cpuinfo->online = (int) sysconf(_SC_NPROCESSORS_ONLN); - if (cpuinfo->online < 0) - cpuinfo->online = 0; + online = (int) sysconf(_SC_NPROCESSORS_ONLN); + if (online < 0) + online = 0; #endif #elif defined(HAVE_SYS_SYSCTL_H) && defined(CTL_HW) && (defined(HW_NCPU) \ || defined(HW_AVAILCPU)) @@ -242,71 +274,138 @@ erts_cpu_info_update(erts_cpu_info_t *cpuinfo) len = sizeof(int); mib[0] = CTL_HW; mib[1] = HW_NCPU; - if (sysctl(&mib[0], 2, &cpuinfo->configured, &len, NULL, 0) < 0) - cpuinfo->configured = 0; + if (sysctl(&mib[0], 2, &configured, &len, NULL, 0) < 0) + configured = 0; #endif #ifdef HW_AVAILCPU len = sizeof(int); mib[0] = CTL_HW; mib[1] = HW_AVAILCPU; - if (sysctl(&mib[0], 2, &cpuinfo->online, &len, NULL, 0) < 0) - cpuinfo->online = 0; + if (sysctl(&mib[0], 2, &online, &len, NULL, 0) < 0) + online = 0; #endif } #endif - if (cpuinfo->online > cpuinfo->configured) - cpuinfo->online = cpuinfo->configured; + if (online > configured) + online = configured; + + if (cpuinfo->configured != configured) + changed = 1; + if (cpuinfo->online != online) + changed = 1; #if defined(ERTS_HAVE_MISC_UTIL_AFFINITY_MASK__) - if (ERTS_MU_GET_PROC_AFFINITY__(cpuinfo) == 0) { - int i, c, cn, si; - c = cn = 0; - si = sizeof(cpuinfo->affinity_str_buf) - 1; - cpuinfo->affinity_str_buf[si] = '\0'; - for (i = 0; i < CPU_SETSIZE; i++) { - if (CPU_ISSET(i, &cpuinfo->cpuset)) { - c |= 1 << cn; - cpuinfo->available++; + if (ERTS_MU_GET_PROC_AFFINITY__(cpuinfo, &cpuset) == 0) { + if (!changed && !cpu_sets_are_eq(&cpuset, &cpuinfo->cpuset)) + changed = 1; + + if (!changed) + available = cpuinfo->available; + else { + int i, c, cn, si; + + memcpy((void *) &cpuinfo->cpuset, + (void *) &cpuset, + sizeof(cpu_set_t)); + + c = cn = 0; + si = sizeof(cpuinfo->affinity_str_buf) - 1; + cpuinfo->affinity_str_buf[si] = '\0'; + for (i = 0; i < CPU_SETSIZE; i++) { + if (CPU_ISSET(i, &cpuinfo->cpuset)) { + c |= 1 << cn; + available++; + } + cn++; + if (cn == 4) { + cpuinfo->affinity_str_buf[--si] = (c < 10 + ? '0' + c + : 'A' + c - 10); + c = cn = 0; + } } - cn++; - if (cn == 4) { + if (c) cpuinfo->affinity_str_buf[--si] = (c < 10 ? '0' + c : 'A' + c - 10); - c = cn = 0; - } + while (cpuinfo->affinity_str_buf[si] == '0') + si++; + cpuinfo->affinity_str = &cpuinfo->affinity_str_buf[si]; } - if (c) - cpuinfo->affinity_str_buf[--si] = (c < 10 - ? '0' + c - : 'A' + c - 10); - while (cpuinfo->affinity_str_buf[si] == '0') - si++; - cpuinfo->affinity_str = &cpuinfo->affinity_str_buf[si]; } #elif defined(HAVE_PSET_INFO) { - uint_t numcpus = cpuinfo->configured; - if (cpuinfo->cpuids) - free(cpuinfo->cpuids); - cpuinfo->cpuids = malloc(sizeof(processorid_t)*numcpus); - if (cpuinfo->cpuids) { - if (pset_info(PS_MYID, NULL, &numcpus, &cpuinfo->cpuids) == 0) - cpuinfo->available = (int) numcpus; - if (cpuinfo->available < 0) { - free(cpuinfo->cpuid); - cpuinfo->available = 0; + processorid_t *cpuids; + uint_t numcpus = configured; + cpuids = malloc(sizeof(processorid_t)*numcpus); + if (cpuids) { + if (pset_info(PS_MYID, NULL, &numcpus, &cpuids) == 0) + available = (int) numcpus; + if (available < 0) { + free(cpuids); + cpuids = NULL; + available = 0; } } + if (!cpuids) { + if (cpuinfo->cpuids) + changed = 1; + } + else { + if (cpuinfo->cpuids) + changed = 1; + if (memcmp((void *) cpuinfo->cpuids, + (void *) cpuids, + sizeof(processorid_t)*numcpus) != 0) + changed = 1; + + } + if (!changed) { + if (cpuids) + free(cpuids); + } + else { + if (cpuinfo->cpuids) + free(cpuinfo->cpuids); + cpuinfo->cpuids = cpuids; + } } #endif - if (cpuinfo->available > cpuinfo->online) - cpuinfo->available = cpuinfo->online; + if (available > online) + available = online; + + if (cpuinfo->available != available) + changed = 1; + + cpuinfo->configured = configured; + cpuinfo->online = online; + cpuinfo->available = available; + + old_topology = cpuinfo->topology; + old_topology_size = cpuinfo->topology_size; + cpuinfo->topology = NULL; read_topology(cpuinfo); + if (cpuinfo->topology_size != old_topology_size + || (old_topology_size != 0 + && memcmp((void *) cpuinfo->topology, + (void *) old_topology, + (sizeof(erts_cpu_topology_t) + * old_topology_size)) != 0)) { + changed = 1; + if (old_topology) + free(old_topology); + } + else { + if (cpuinfo->topology) + free(cpuinfo->topology); + cpuinfo->topology = old_topology; + } + + return changed; } int @@ -588,6 +687,56 @@ cpu_cmp(const void *vx, const void *vy) return 0; } +static void +adjust_processor_nodes(erts_cpu_info_t *cpuinfo, int no_nodes) +{ + erts_cpu_topology_t *prev, *this, *last; + if (no_nodes > 1) { + int processor = -1; + int processor_node = 0; + int node = -1; + + qsort(cpuinfo->topology, + cpuinfo->topology_size, + sizeof(erts_cpu_topology_t), + pn_cmp); + + prev = NULL; + this = &cpuinfo->topology[0]; + last = &cpuinfo->topology[cpuinfo->configured-1]; + while (1) { + if (processor == this->processor) { + if (node != this->node) + processor_node = 1; + } + else { + if (processor_node) { + make_processor_node: + while (prev->processor == processor) { + prev->processor_node = prev->node; + prev->node = -1; + if (prev == &cpuinfo->topology[0]) + break; + prev--; + } + processor_node = 0; + } + processor = this->processor; + node = this->node; + } + if (this == last) { + if (processor_node) { + prev = this; + goto make_processor_node; + } + break; + } + prev = this++; + } + } +} + + #ifdef __linux__ static int @@ -641,9 +790,6 @@ read_topology(erts_cpu_info_t *cpuinfo) errno = 0; - if (cpuinfo->topology) - free(cpuinfo->topology); - if (cpuinfo->configured < 1) goto error; @@ -757,49 +903,7 @@ read_topology(erts_cpu_info_t *cpuinfo) cpuinfo->topology = t; } - if (no_nodes > 1) { - int processor = -1; - int processor_node = 0; - int node = -1; - - qsort(cpuinfo->topology, - cpuinfo->topology_size, - sizeof(erts_cpu_topology_t), - pn_cmp); - - prev = NULL; - this = &cpuinfo->topology[0]; - last = &cpuinfo->topology[cpuinfo->configured-1]; - while (1) { - if (processor == this->processor) { - if (node != this->node) - processor_node = 1; - } - else { - if (processor_node) { - make_processor_node: - while (prev->processor == processor) { - prev->processor_node = prev->node; - prev->node = -1; - if (prev == &cpuinfo->topology[0]) - break; - prev--; - } - processor_node = 0; - } - processor = this->processor; - node = this->node; - } - if (this == last) { - if (processor_node) { - prev = this; - goto make_processor_node; - } - break; - } - prev = this++; - } - } + adjust_processor_nodes(cpuinfo, no_nodes); qsort(cpuinfo->topology, cpuinfo->topology_size, @@ -896,9 +1000,6 @@ read_topology(erts_cpu_info_t *cpuinfo) errno = 0; - if (cpuinfo->topology) - free(cpuinfo->topology); - if (cpuinfo->configured < 1) goto error; @@ -985,6 +1086,8 @@ read_topology(erts_cpu_info_t *cpuinfo) } } + adjust_processor_nodes(cpuinfo, 1); + error: if (res == 0) { @@ -1003,6 +1106,275 @@ read_topology(erts_cpu_info_t *cpuinfo) } +#elif defined(__WIN32__) + +/* + * We cannot use Relation* out of the box since all of them are not + * always part of the LOGICAL_PROCESSOR_RELATIONSHIP enum. They are + * however documented as follows... + */ +#define ERTS_MU_RELATION_PROCESSOR_CORE 0 /* RelationProcessorCore */ +#define ERTS_MU_RELATION_NUMA_NODE 1 /* RelationNumaNode */ +#define ERTS_MU_RELATION_CACHE 2 /* RelationCache */ +#define ERTS_MU_RELATION_PROCESSOR_PACKAGE 3 /* RelationProcessorPackage */ + +static __forceinline int +rel_cmp_val(int r) +{ + switch (r) { + case ERTS_MU_RELATION_NUMA_NODE: return 0; + case ERTS_MU_RELATION_PROCESSOR_PACKAGE: return 1; + case ERTS_MU_RELATION_PROCESSOR_CORE: return 2; + default: /* currently not used */ return 3; + } +} + +static int +slpi_cmp(const void *vx, const void *vy) +{ + PSYSTEM_LOGICAL_PROCESSOR_INFORMATION x, y; + x = (PSYSTEM_LOGICAL_PROCESSOR_INFORMATION) vx; + y = (PSYSTEM_LOGICAL_PROCESSOR_INFORMATION) vy; + + if ((int) x->Relationship != (int) y->Relationship) + return (rel_cmp_val((int) x->Relationship) + - rel_cmp_val((int) y->Relationship)); + + switch ((int) x->Relationship) { + case ERTS_MU_RELATION_NUMA_NODE: + if (x->NumaNode.NodeNumber == y->NumaNode.NodeNumber) + break; + return ((int) x->NumaNode.NodeNumber) - ((int) y->NumaNode.NodeNumber); + case ERTS_MU_RELATION_PROCESSOR_CORE: + case ERTS_MU_RELATION_PROCESSOR_PACKAGE: + default: + break; + } + + if (x->ProcessorMask == y->ProcessorMask) + return 0; + return x->ProcessorMask < y->ProcessorMask ? -1 : 1; +} + +typedef BOOL (WINAPI *glpi_t)(PSYSTEM_LOGICAL_PROCESSOR_INFORMATION, PDWORD); + +static int +read_topology(erts_cpu_info_t *cpuinfo) +{ + int res = 0; + glpi_t glpi; + int *core_id = NULL; + PSYSTEM_LOGICAL_PROCESSOR_INFORMATION slpip = NULL; + int wix, rix, max_l, l, packages, nodes, no_slpi; + DWORD slpi_size = 0; + + + glpi = (glpi_t) GetProcAddress(GetModuleHandle("kernel32"), + "GetLogicalProcessorInformation"); + if (!glpi) + return -ENOTSUP; + + cpuinfo->topology = NULL; + + if (cpuinfo->configured < 1 || sizeof(ULONG_PTR)*8 < cpuinfo->configured) + goto error; + + while (1) { + DWORD werr; + if (TRUE == glpi(slpip, &slpi_size)) + break; + werr = GetLastError(); + if (werr != ERROR_INSUFFICIENT_BUFFER) { + res = -erts_map_win_error_to_errno(werr); + goto error; + } + if (slpip) + free(slpip); + slpip = malloc(slpi_size); + if (!slpip) { + res = -ENOMEM; + goto error; + } + } + + no_slpi = (int) slpi_size/sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION); + + qsort(slpip, + no_slpi, + sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION), + slpi_cmp); + + /* + * Now numa node relations appear before package relations which + * appear before core relations which appear before relations + * we aren't interested in... + */ + + max_l = 0; + packages = 0; + nodes = 0; + for (rix = 0; rix < no_slpi; rix++) { + PSYSTEM_LOGICAL_PROCESSOR_INFORMATION this = &slpip[rix]; + for (l = sizeof(ULONG_PTR)*8 - 1; l > 0; l--) { + if (slpip[rix].ProcessorMask & (((ULONG_PTR) 1) << l)) { + if (max_l < l) + max_l = l; + break; + } + } + if ((int) slpip[rix].Relationship == ERTS_MU_RELATION_PROCESSOR_PACKAGE) + packages++; + if ((int) slpip[rix].Relationship == ERTS_MU_RELATION_NUMA_NODE) + nodes++; + } + + core_id = malloc(sizeof(int)*(packages ? packages : 1)); + if (!core_id) { + res = -ENOMEM; + goto error; + } + + for (rix = 0; rix < packages; rix++) + core_id[rix] = 0; + + cpuinfo->topology_size = max_l + 1; + cpuinfo->topology = malloc(sizeof(erts_cpu_topology_t) + * cpuinfo->topology_size); + if (!cpuinfo->topology) { + res = -ENOMEM; + goto error; + } + + for (wix = 0; wix < cpuinfo->topology_size; wix++) { + cpuinfo->topology[wix].node = -1; + cpuinfo->topology[wix].processor = -1; + cpuinfo->topology[wix].processor_node = -1; + cpuinfo->topology[wix].core = -1; + cpuinfo->topology[wix].thread = -1; + cpuinfo->topology[wix].logical = -1; + } + + nodes = 0; + packages = 0; + + for (rix = 0; rix < no_slpi; rix++) { + + switch ((int) slpip[rix].Relationship) { + case ERTS_MU_RELATION_NUMA_NODE: + for (l = 0; l < sizeof(ULONG_PTR)*8; l++) { + if (slpip[rix].ProcessorMask & (((ULONG_PTR) 1) << l)) { + cpuinfo->topology[l].logical = l; + cpuinfo->topology[l].node = slpip[rix].NumaNode.NodeNumber; + } + } + nodes++; + break; + case ERTS_MU_RELATION_PROCESSOR_PACKAGE: + for (l = 0; l < sizeof(ULONG_PTR)*8; l++) { + if (slpip[rix].ProcessorMask & (((ULONG_PTR) 1) << l)) { + cpuinfo->topology[l].logical = l; + cpuinfo->topology[l].processor = packages; + } + } + packages++; + break; + case ERTS_MU_RELATION_PROCESSOR_CORE: { + int thread = 0; + int processor = -1; + for (l = 0; l < sizeof(ULONG_PTR)*8; l++) { + /* + * Nodes and packages may not be supported; pretend + * that there are one if this is the case... + */ + if (!nodes) + cpuinfo->topology[l].node = 0; + if (!packages) + cpuinfo->topology[l].processor = 0; + if (slpip[rix].ProcessorMask & (((ULONG_PTR) 1) << l)) { + if (processor < 0) { + processor = cpuinfo->topology[l].processor; + if (processor < 0) { + res = -EINVAL; + goto error; + } + } + else if (processor != cpuinfo->topology[l].processor) { + res = -EINVAL; + goto error; + } + cpuinfo->topology[l].logical = l; + cpuinfo->topology[l].thread = thread; + cpuinfo->topology[l].core = core_id[processor]; + thread++; + } + } + core_id[processor]++; + break; + } + default: + /* + * We have reached the end of the relationships + * that we (currently) are interested in... + */ + goto relationships_done; + } + } + + relationships_done: + + /* + * There may be unused entries; remove them... + */ + for (rix = wix = 0; rix < cpuinfo->topology_size; rix++) { + if (cpuinfo->topology[rix].logical >= 0) { + if (wix != rix) + cpuinfo->topology[wix] = cpuinfo->topology[rix]; + wix++; + } + } + + if (cpuinfo->topology_size != wix) { + erts_cpu_topology_t *new = cpuinfo->topology; + new = realloc(cpuinfo->topology, + sizeof(erts_cpu_topology_t)*wix); + if (!new) { + res = -ENOMEM; + goto error; + } + cpuinfo->topology = new; + cpuinfo->topology_size = wix; + } + + res = wix; + + adjust_processor_nodes(cpuinfo, nodes); + + qsort(cpuinfo->topology, + cpuinfo->topology_size, + sizeof(erts_cpu_topology_t), + cpu_cmp); + + if (res < cpuinfo->online) + res = -EINVAL; + + error: + + if (res <= 0) { + cpuinfo->topology_size = 0; + if (cpuinfo->topology) { + free(cpuinfo->topology); + cpuinfo->topology = NULL; + } + } + + if (slpip) + free(slpip); + if (core_id) + free(core_id); + + return res; +} + #else static int @@ -1016,9 +1388,9 @@ read_topology(erts_cpu_info_t *cpuinfo) #if defined(__WIN32__) int -erts_get_last_win_errno(void) +erts_map_win_error_to_errno(DWORD win_error) { - switch (GetLastError()) { + switch (win_error) { case ERROR_INVALID_FUNCTION: return EINVAL; /* 1 */ case ERROR_FILE_NOT_FOUND: return ENOENT; /* 2 */ case ERROR_PATH_NOT_FOUND: return ENOENT; /* 3 */ @@ -1099,4 +1471,11 @@ erts_get_last_win_errno(void) } } +int +erts_get_last_win_errno(void) +{ + return erts_map_win_error_to_errno(GetLastError()); +} + + #endif diff --git a/erts/lib_src/common/ethr_mutex.c b/erts/lib_src/common/ethr_mutex.c index f918bba81d..aac0d44a32 100644 --- a/erts/lib_src/common/ethr_mutex.c +++ b/erts/lib_src/common/ethr_mutex.c @@ -1048,7 +1048,7 @@ ethr_cond_signal(ethr_cond *cnd) ethr_ts_event *tse; ETHR_ASSERT(!ethr_not_inited__); - ETHR_ASSERT(!cnd); + ETHR_ASSERT(cnd); ETHR_ASSERT(cnd->initialized == ETHR_COND_INITIALIZED); ETHR_MTX_HARD_DEBUG_FENCE_CHK(cnd); @@ -1089,7 +1089,7 @@ ethr_cond_broadcast(ethr_cond *cnd) int got_all; ethr_ts_event *tse; ETHR_ASSERT(!ethr_not_inited__); - ETHR_ASSERT(!cnd); + ETHR_ASSERT(cnd); ETHR_ASSERT(cnd->initialized == ETHR_COND_INITIALIZED); ETHR_MTX_HARD_DEBUG_FENCE_CHK(cnd); @@ -1158,9 +1158,9 @@ ethr_cond_wait(ethr_cond *cnd, ethr_mutex *mtx) ethr_ts_event *tse; ETHR_ASSERT(!ethr_not_inited__); - ETHR_ASSERT(!cnd); + ETHR_ASSERT(cnd); ETHR_ASSERT(cnd->initialized == ETHR_COND_INITIALIZED); - ETHR_ASSERT(!mtx); + ETHR_ASSERT(mtx); ETHR_ASSERT(mtx->initialized == ETHR_MUTEX_INITIALIZED); tse = ethr_get_ts_event(); diff --git a/erts/preloaded/ebin/prim_inet.beam b/erts/preloaded/ebin/prim_inet.beam Binary files differindex ac336c1b2d..71f6643368 100644 --- a/erts/preloaded/ebin/prim_inet.beam +++ b/erts/preloaded/ebin/prim_inet.beam diff --git a/erts/preloaded/src/prim_inet.erl b/erts/preloaded/src/prim_inet.erl index 0feb591efb..91d39c6a73 100644 --- a/erts/preloaded/src/prim_inet.erl +++ b/erts/preloaded/src/prim_inet.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2000-2009. All Rights Reserved. +%% Copyright Ericsson AB 2000-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 @@ -1206,7 +1206,7 @@ type_opt_1(sctp_default_send_param) -> timetolive = [uint32,0], tsn = [], cumtsn = [], - assoc_id = [sctp_assoc_id,0]}}]; + assoc_id = [[sctp_assoc_id,0]]}}]; %% for SCTP_OPT_EVENTS type_opt_1(sctp_events) -> [{record,#sctp_event_subscribe{ diff --git a/lib/.gitignore b/lib/.gitignore index a33916b3bf..340baf5269 100644 --- a/lib/.gitignore +++ b/lib/.gitignore @@ -128,6 +128,7 @@ /megaco/src/text/megaco_text_parser_v1.erl /megaco/src/text/megaco_text_parser_v2.erl /megaco/src/text/megaco_text_parser_v3.erl +/megaco/doc/html/mstone1.jpg # mnesia diff --git a/lib/appmon/src/appmon_web.erl b/lib/appmon/src/appmon_web.erl index e8a8422a80..fb7144246c 100644 --- a/lib/appmon/src/appmon_web.erl +++ b/lib/appmon/src/appmon_web.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2001-2009. All Rights Reserved. +%% Copyright Ericsson AB 2001-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 @@ -38,12 +38,6 @@ %% webtool -export([configData/0]). - -%% The following directive caters for (significantly) faster native -%% code compilation of one function in this file by the HiPE compiler -%% on register-poor architectures like the x86. --compile([{hipe,[{regalloc,graph_color}]}]). - -behaviour(gen_server). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff --git a/lib/appmon/vsn.mk b/lib/appmon/vsn.mk index cfcb5d3eb6..0675a4eb8b 100644 --- a/lib/appmon/vsn.mk +++ b/lib/appmon/vsn.mk @@ -1,19 +1 @@ -# -# %CopyrightBegin% -# -# Copyright Ericsson AB 1997-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% - APPMON_VSN = 2.1.12 diff --git a/lib/asn1/src/asn1.appup.src b/lib/asn1/src/asn1.appup.src index 753d308684..2d11eddfbf 100644 --- a/lib/asn1/src/asn1.appup.src +++ b/lib/asn1/src/asn1.appup.src @@ -1,111 +1,9 @@ {"%VSN%", - [ - {"1.6.8", - [ - {load_module, asn1rt, soft_purge, soft_purge, []}, - {load_module, asn1rt_per_bin, soft_purge, soft_purge, []}, - {load_module, asn1rt_per_bin_rt2ct, soft_purge, soft_purge, []}, - {load_module, asn1rt_uper_bin, soft_purge, soft_purge, []}, - {load_module, asn1rt_ber_bin, soft_purge, soft_purge, []}, - {load_module, asn1rt_ber_bin_v2, soft_purge, soft_purge, []}, - {load_module, asn1rt_check, soft_purge, soft_purge, []}, - {load_module, asn1rt_driver_handler, soft_purge, soft_purge, []}, - {apply, {asn1rt_driver_handler,unload_driver,[]}} - ] - }, - {"1.6.8.1", - [ - {load_module, asn1rt, soft_purge, soft_purge, []}, - {load_module, asn1rt_per_bin, soft_purge, soft_purge, []}, - {load_module, asn1rt_per_bin_rt2ct, soft_purge, soft_purge, []}, - {load_module, asn1rt_uper_bin, soft_purge, soft_purge, []}, - {load_module, asn1rt_ber_bin, soft_purge, soft_purge, []}, - {load_module, asn1rt_ber_bin_v2, soft_purge, soft_purge, []}, - {load_module, asn1rt_check, soft_purge, soft_purge, []}, - {load_module, asn1rt_driver_handler, soft_purge, soft_purge, []}, - {apply, {asn1rt_driver_handler,unload_driver,[]}} - ] - }, - {"1.6.9", - [ - {load_module, asn1rt, soft_purge, soft_purge, []}, - {load_module, asn1rt_per_bin, soft_purge, soft_purge, []}, - {load_module, asn1rt_per_bin_rt2ct, soft_purge, soft_purge, []}, - {load_module, asn1rt_uper_bin, soft_purge, soft_purge, []}, - {load_module, asn1rt_ber_bin, soft_purge, soft_purge, []}, - {load_module, asn1rt_ber_bin_v2, soft_purge, soft_purge, []}, - {load_module, asn1rt_check, soft_purge, soft_purge, []}, - {load_module, asn1rt_driver_handler, soft_purge, soft_purge, []}, - {apply, {asn1rt_driver_handler,unload_driver,[]}} - ] - }, - {"1.6.10", - [ - {load_module, asn1rt, soft_purge, soft_purge, []}, - {load_module, asn1rt_per_bin, soft_purge, soft_purge, []}, - {load_module, asn1rt_per_bin_rt2ct, soft_purge, soft_purge, []}, - {load_module, asn1rt_uper_bin, soft_purge, soft_purge, []}, - {load_module, asn1rt_ber_bin, soft_purge, soft_purge, []}, - {load_module, asn1rt_ber_bin_v2, soft_purge, soft_purge, []}, - {load_module, asn1rt_check, soft_purge, soft_purge, []}, - {load_module, asn1rt_driver_handler, soft_purge, soft_purge, []}, - {apply, {asn1rt_driver_handler,unload_driver,[]}} - ] - } +% This version does not change anything of the runtime modules +% Only changes in compile time modules and thus no need for upgrade on target +[ ], [ - {"1.6.8", - [ - {load_module, asn1rt, soft_purge, soft_purge, []}, - {load_module, asn1rt_per_bin, soft_purge, soft_purge, []}, - {load_module, asn1rt_per_bin_rt2ct, soft_purge, soft_purge, []}, - {load_module, asn1rt_uper_bin, soft_purge, soft_purge, []}, - {load_module, asn1rt_ber_bin, soft_purge, soft_purge, []}, - {load_module, asn1rt_ber_bin_v2, soft_purge, soft_purge, []}, - {load_module, asn1rt_check, soft_purge, soft_purge, []}, - {load_module, asn1rt_driver_handler, soft_purge, soft_purge, []}, - {apply, {asn1rt_driver_handler,unload_driver,[]}} - ] - }, - {"1.6.8.1", - [ - {load_module, asn1rt, soft_purge, soft_purge, []}, - {load_module, asn1rt_per_bin, soft_purge, soft_purge, []}, - {load_module, asn1rt_per_bin_rt2ct, soft_purge, soft_purge, []}, - {load_module, asn1rt_uper_bin, soft_purge, soft_purge, []}, - {load_module, asn1rt_ber_bin, soft_purge, soft_purge, []}, - {load_module, asn1rt_ber_bin_v2, soft_purge, soft_purge, []}, - {load_module, asn1rt_check, soft_purge, soft_purge, []}, - {load_module, asn1rt_driver_handler, soft_purge, soft_purge, []}, - {apply, {asn1rt_driver_handler,unload_driver,[]}} - ] - }, - {"1.6.9", - [ - {load_module, asn1rt, soft_purge, soft_purge, []}, - {load_module, asn1rt_per_bin, soft_purge, soft_purge, []}, - {load_module, asn1rt_per_bin_rt2ct, soft_purge, soft_purge, []}, - {load_module, asn1rt_uper_bin, soft_purge, soft_purge, []}, - {load_module, asn1rt_ber_bin, soft_purge, soft_purge, []}, - {load_module, asn1rt_ber_bin_v2, soft_purge, soft_purge, []}, - {load_module, asn1rt_check, soft_purge, soft_purge, []}, - {load_module, asn1rt_driver_handler, soft_purge, soft_purge, []}, - {apply, {asn1rt_driver_handler,unload_driver,[]}} - ] - }, - {"1.6.10", - [ - {load_module, asn1rt, soft_purge, soft_purge, []}, - {load_module, asn1rt_per_bin, soft_purge, soft_purge, []}, - {load_module, asn1rt_per_bin_rt2ct, soft_purge, soft_purge, []}, - {load_module, asn1rt_uper_bin, soft_purge, soft_purge, []}, - {load_module, asn1rt_ber_bin, soft_purge, soft_purge, []}, - {load_module, asn1rt_ber_bin_v2, soft_purge, soft_purge, []}, - {load_module, asn1rt_check, soft_purge, soft_purge, []}, - {load_module, asn1rt_driver_handler, soft_purge, soft_purge, []}, - {apply, {asn1rt_driver_handler,unload_driver,[]}} - ] - } ]}. diff --git a/lib/asn1/src/asn1_records.hrl b/lib/asn1/src/asn1_records.hrl index 8a428b744c..59a9acb7e7 100644 --- a/lib/asn1/src/asn1_records.hrl +++ b/lib/asn1/src/asn1_records.hrl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1997-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 1997-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% %% %% @@ -36,7 +36,8 @@ -record(module,{pos,name,defid,tagdefault='EXPLICIT',exports={exports,[]},imports={imports,[]}, extensiondefault=empty,typeorval}). --record('SEQUENCE',{pname=false,tablecinf=false,components=[]}). +-record('ExtensionAdditionGroup',{number}). +-record('SEQUENCE',{pname=false,tablecinf=false,extaddgroup,components=[]}). -record('SET',{pname=false,sorted=false,tablecinf=false,components=[]}). -record('ComponentType',{pos,name,typespec,prop,tags,textual_order}). -record('ObjectClassFieldType',{classname,class,fieldname,type}). diff --git a/lib/asn1/src/asn1ct.erl b/lib/asn1/src/asn1ct.erl index ae681a4a78..968468cb7f 100644 --- a/lib/asn1/src/asn1ct.erl +++ b/lib/asn1/src/asn1ct.erl @@ -1674,7 +1674,7 @@ create_pdec_inc_command(ModName, % [concat_sequential(lists:reverse(Comms), % [LastComm,CompAcc])|Acc] case lists:reverse(TagCommand) of - [Atom|Comms]�when is_atom(Atom) -> + [Atom|Comms] when is_atom(Atom) -> [concat_sequential(lists:reverse(Comms), [Atom,CompAcc])|Acc]; [[Command2,Tag2]|Comms] -> diff --git a/lib/asn1/src/asn1ct_check.erl b/lib/asn1/src/asn1ct_check.erl index 54a5c7e727..1c9f2c759a 100644 --- a/lib/asn1/src/asn1ct_check.erl +++ b/lib/asn1/src/asn1ct_check.erl @@ -3227,7 +3227,7 @@ check_ptype(_S,_PTDef,Ts) when is_record(Ts,objectclass) -> % check_type(S,Type,ObjSpec={{objectclassname,_},_}) -> -% check_class(S,ObjSpec); + % check_class(S,ObjSpec); check_type(_S,Type,Ts) when is_record(Type,typedef), (Type#typedef.checked==true) -> Ts; @@ -3357,6 +3357,7 @@ check_type(S=#state{recordtopname=TopName},Type,Ts) when is_record(Ts,type) -> merge_tags(Tag,?TAG_PRIMITIVE(?N_INTEGER))}; 'REAL' -> check_real(S,Constr), + TempNewDef#newt{tag=merge_tags(Tag,?TAG_PRIMITIVE(?N_REAL))}; {'BIT STRING',NamedNumberList} -> NewL = check_bitstring(S,NamedNumberList,Constr), @@ -5522,24 +5523,9 @@ check_sequence(S,Type,Comps) -> Components2 = maybe_automatic_tags(S,Components), %% check the table constraints from here. The outermost type %% is Type, the innermost is Comps (the list of components) - NewComps = - case check_each_component(S,Type,Components2) of - NewComponents when is_list(NewComponents) -> - check_unique_sequence_tags(S,NewComponents), - NewComponents; - Ret = {NewComponents,NewEcomps} -> - TagComps = NewComponents ++ - [Comp#'ComponentType'{prop='OPTIONAL'}|| Comp <- NewEcomps], - %% extension components are like optionals when it comes to tagging - check_unique_sequence_tags(S,TagComps), - Ret; - Ret = {Root1,NewE,Root2} -> - TagComps = Root1 ++ [Comp#'ComponentType'{prop='OPTIONAL'}|| Comp <- NewE]++Root2, - %% This is not correct handling if Extension - %% contains ExtensionAdditionGroups - check_unique_sequence_tags(S,TagComps), - Ret - end, + NewComps = check_each_component2(S,Type,Components2), + check_unique_sequence_tags(S,NewComps), + %% CRelInf is the "leading attribute" information %% necessary for code generating of the look up in the %% object set table, @@ -5553,12 +5539,45 @@ check_sequence(S,Type,Comps) -> %% the involved class removed, as the class of the object %% set. CompListWithTblInf = get_tableconstraint_info(S,Type,NewComps2), - - {CRelInf,CompListWithTblInf}; + %% If encoding rule is in the PER family the Root Components + %% after the second extension mark should be encoded before + %% all extensions i.e together with the first Root components + + NewComps3 = textual_order(CompListWithTblInf), + CompListTuple = + complist_as_tuple(is_erule_per(S#state.erule),NewComps3), + {CRelInf,CompListTuple}; Dupl -> - throw({error,{asn1,{duplicate_components,Dupl}}}) + throw({error,{asn1,{duplicate_components,Dupl}}}) end. +complist_as_tuple(Per,CompList) -> + complist_as_tuple(Per,CompList,[],[],[],root). + +complist_as_tuple(Per,[#'EXTENSIONMARK'{}|T],Acc,Ext,Acc2,root) -> + complist_as_tuple(Per,T,Acc,Ext,Acc2,ext); +complist_as_tuple(Per,[#'EXTENSIONMARK'{}|T],Acc,Ext,Acc2,ext) -> + complist_as_tuple(Per,T,Acc,Ext,Acc2,root2); +complist_as_tuple(_Per,[#'EXTENSIONMARK'{}|_T],_Acc,_Ext,_Acc2,root2) -> + throw({error,{asn1,{too_many_extension_marks}}}); +complist_as_tuple(Per,[C|T],Acc,Ext,Acc2,root) -> + complist_as_tuple(Per,T,[C|Acc],Ext,Acc2,root); +complist_as_tuple(Per,[C|T],Acc,Ext,Acc2,ext) -> + complist_as_tuple(Per,T,Acc,[C|Ext],Acc2,ext); +complist_as_tuple(Per,[C|T],Acc,Ext,Acc2,root2) -> + complist_as_tuple(Per,T,Acc,Ext,[C|Acc2],root2); +complist_as_tuple(_Per,[],Acc,_Ext,_Acc2,root) -> + lists:reverse(Acc); +complist_as_tuple(_Per,[],Acc,Ext,_Acc2,ext) -> + {lists:reverse(Acc),lists:reverse(Ext)}; +%%complist_as_tuple(_Per = true,[],Acc,Ext,Acc2,root2) -> +%% {lists:reverse(Acc)++lists:reverse(Acc2),lists:reverse(Ext)}; +complist_as_tuple(_Per,[],Acc,Ext,Acc2,root2) -> + {lists:reverse(Acc),lists:reverse(Ext),lists:reverse(Acc2)}. + +is_erule_per(Erule) -> + lists:member(Erule,[per,per_bin,uper_bin]). + expand_components(S, [{'COMPONENTS OF',Type}|T]) -> CompList = expand_components2(S,get_referenced_type(S,Type#type.def)), expand_components(S,CompList) ++ expand_components(S,T); @@ -5601,13 +5620,26 @@ take_only_rootset([#'EXTENSIONMARK'{}|_T])-> take_only_rootset([H|T]) -> [H|take_only_rootset(T)]. -check_unique_sequence_tags(S,[#'ComponentType'{prop=mandatory}|Rest]) -> - check_unique_sequence_tags(S,Rest); -check_unique_sequence_tags(S,[C|Rest]) when is_record(C,'ComponentType') -> +check_unique_sequence_tags(S,CompList) -> + TagComps = case complist_as_tuple(false,CompList) of + {R1,Ext,R2} -> + R1 ++ [C#'ComponentType'{prop='OPTIONAL'}|| + C = #'ComponentType'{} <- Ext]++R2; + {R1,Ext} -> + R1 ++ [C#'ComponentType'{prop='OPTIONAL'}|| + C = #'ComponentType'{} <- Ext]; + _ -> + CompList + end, + check_unique_sequence_tags0(S,TagComps). + +check_unique_sequence_tags0(S,[#'ComponentType'{prop=mandatory}|Rest]) -> + check_unique_sequence_tags0(S,Rest); +check_unique_sequence_tags0(S,[C=#'ComponentType'{}|Rest]) -> check_unique_sequence_tags1(S,Rest,[C]);% optional or default -check_unique_sequence_tags(S,[_ExtensionMarker|Rest]) -> - check_unique_sequence_tags(S,Rest); -check_unique_sequence_tags(_S,[]) -> +check_unique_sequence_tags0(S,[_ExtensionMarker|Rest]) -> + check_unique_sequence_tags0(S,Rest); +check_unique_sequence_tags0(_S,[]) -> true. check_unique_sequence_tags1(S,[C|Rest],Acc) when is_record(C,'ComponentType') -> @@ -5807,8 +5839,10 @@ get_least_tag(TagList) -> %% adds the textual order to the components to keep right order of %% components in the asn1-value. textual_order(Cs) -> - Fun = fun(C,Index) -> - {C#'ComponentType'{textual_order=Index},Index+1} + Fun = fun(C=#'ComponentType'{},Index) -> + {C#'ComponentType'{textual_order=Index},Index+1}; + (Other,Index) -> + {Other,Index} end, {NewCs,_} = textual_order(Cs,Fun,1), NewCs. @@ -5879,7 +5913,6 @@ check_selectiontype2(S,Name,TypeDef) -> error({type,Msg,S}) end. - check_restrictedstring(_S,_Def,_Constr) -> ok. @@ -5899,16 +5932,16 @@ check_choice(S,Type,Components) when is_list(Components) -> [] -> %% sort_canonical(Components), Components2 = maybe_automatic_tags(S,Components), - %NewComps = - case check_each_alternative(S,Type,Components2) of - {NewComponents,NewEcomps} -> - check_unique_tags(S,NewComponents ++ NewEcomps), - {NewComponents,NewEcomps}; - NewComponents -> - check_unique_tags(S,NewComponents), - NewComponents - end; - + NewComps = check_each_alternative2(S,Type,Components2), + %% ExtensionAdditionGroup markers i.e '[[' ']]' are not + %% significant for encoding/decoding a choice + %% therefore we remove them here + NewComps2 = lists:filter(fun(#'ExtensionAdditionGroup'{}) -> false; + ('ExtensionAdditionGroupEnd') -> false; + (_) -> true + end,NewComps), + check_unique_tags(S,NewComps2), + complist_as_tuple(is_erule_per(S#state.erule),NewComps2); Dupl -> throw({error,{asn1,{duplicate_choice_alternatives,Dupl}}}) end; @@ -6036,12 +6069,17 @@ check_unique2([_|T],Pos,Acc) -> check_unique2([],_,Acc) -> lists:reverse(Acc). -check_each_component(S,Type,Components) -> - check_each_component(S,Type,Components,[],[],[],root1). -check_each_component(S = #state{abscomppath=Path,recordtopname=TopName},Type, - [C|Ct],Acc,Extacc,Acc2,Ext) when is_record(C,'ComponentType') -> - #'ComponentType'{name=Cname,typespec=Ts,prop=Prop} = C, +%% Replaces check_each_component and does the same work except that +%% it keeps the complist as a flat list and does not create a tuple with root and +%% extensions separated +check_each_component2(S,Type,Components) -> + check_each_component2(S,Type,Components,[]). + +check_each_component2(S = #state{abscomppath=Path,recordtopname=TopName}, + Type, + [C = #'ComponentType'{name=Cname,typespec=Ts,prop=Prop}|Ct], + Acc) -> NewAbsCPath = case Ts#type.def of #'Externaltypereference'{} -> []; @@ -6058,75 +6096,48 @@ check_each_component(S = #state{abscomppath=Path,recordtopname=TopName},Type, DefaultValue -> {'DEFAULT',DefaultValue} end, NewC = C#'ComponentType'{typespec=CheckedTs,prop=NewProp,tags=NewTags}, - case Ext of - root1 -> - check_each_component(S,Type,Ct,[NewC|Acc],Extacc,Acc2,Ext); - ext -> - check_each_component(S,Type,Ct,Acc,[NewC|Extacc],Acc2,Ext); - root2 -> - check_each_component(S,Type,Ct,Acc,Extacc,[NewC|Acc2],Ext) - end; -check_each_component(S,Type,[_|Ct],Acc,Extacc,Acc2,root1) -> % skip 'EXTENSIONMARK' - check_each_component(S,Type,Ct,Acc,Extacc,Acc2,ext); -check_each_component(S,Type,[_|Ct],Acc,Extacc,Acc2,ext) -> % skip 'EXTENSIONMARK' - check_each_component(S,Type,Ct,Acc,Extacc,Acc2,root2); -check_each_component(_S,_,[_C|_Ct],_,_,_,root2) -> % 'EXTENSIONMARK' - throw({error,{asn1,{too_many_extension_marks}}}); -check_each_component(_S,_,[],Acc,Extacc,_,ext) -> - {lists:reverse(Acc),lists:reverse(Extacc)}; -check_each_component(_S,_,[],Acc1,ExtAcc,Acc2,root2) -> - {lists:reverse(Acc1),lists:reverse(ExtAcc),lists:reverse(Acc2)}; -check_each_component(_S,_,[],Acc,_,_,root1) -> + check_each_component2(S,Type,Ct,[NewC|Acc]); + +check_each_component2(S,Type,[OtherMarker|Ct],Acc) -> + %% let 'EXTENSIONMARK' and 'ExtensionAdditionGroup' markers pass through as is + check_each_component2(S,Type,Ct,[OtherMarker|Acc]); +check_each_component2(_S,_,[],Acc) -> lists:reverse(Acc). -%% check_each_alternative(S,Type,{Rlist,ExtList}) -> + +%% check_each_alternative2(S,Type,{Rlist,ExtList}) -> %% {check_each_alternative(S,Type,Rlist), %% check_each_alternative(S,Type,ExtList)}; -check_each_alternative(S,Type,[C|Ct]) -> - check_each_alternative(S,Type,[C|Ct],[],[],noext). +check_each_alternative2(S,Type,[C|Ct]) -> + check_each_alternative2(S,Type,[C|Ct],[]). -check_each_alternative(S=#state{abscomppath=Path,recordtopname=TopName},Type,[C|Ct], - Acc,Extacc,Ext) when is_record(C,'ComponentType') -> - #'ComponentType'{name=Cname,typespec=Ts,prop=_Prop} = C, +check_each_alternative2(S=#state{abscomppath=Path,recordtopname=TopName}, + Type, + [C = #'ComponentType'{name=Cname,typespec=Ts}|Ct], + Acc) -> NewAbsCPath = case Ts#type.def of #'Externaltypereference'{} -> []; _ -> [Cname|Path] end, - NewState = - S#state{abscomppath=NewAbsCPath,recordtopname=[Cname|TopName]}, - CheckedTs = check_type(NewState,Type,Ts), + CheckedTs = check_type(S#state{abscomppath=NewAbsCPath, + recordtopname=[Cname|TopName]},Type,Ts), NewTags = get_taglist(S,CheckedTs), + NewC = C#'ComponentType'{typespec=CheckedTs,tags=NewTags}, - case Ext of - noext -> - check_each_alternative(S,Type,Ct,[NewC|Acc],Extacc,Ext); - ext -> - check_each_alternative(S,Type,Ct,Acc,[NewC|Extacc],Ext) - end; + check_each_alternative2(S,Type,Ct,[NewC|Acc]); -check_each_alternative(S,Type,[_|Ct],Acc,Extacc,noext) -> % skip 'EXTENSIONMARK' - check_each_alternative(S,Type,Ct,Acc,Extacc,ext); -check_each_alternative(_S,_,[_C|_Ct],_,_,ext) -> % skip 'EXTENSIONMARK' - throw({error,{asn1,{too_many_extension_marks}}}); -check_each_alternative(_S,_,[],Acc,Extacc,ext) -> - {lists:reverse(Acc),lists:reverse(Extacc)}; -check_each_alternative(_S,_,[],Acc,_,noext) -> +check_each_alternative2(S,Type,[OtherMarker|Ct],Acc) -> + %% let 'EXTENSIONMARK' and 'ExtensionAdditionGroup' markers pass through as is + check_each_alternative2(S,Type,Ct,[OtherMarker|Acc]); +check_each_alternative2(_S,_,[],Acc) -> lists:reverse(Acc). + %% componentrelation_leadingattr/2 searches the structure for table %% constraints, if any is found componentrelation_leadingattr/5 is %% called. componentrelation_leadingattr(S,CompList) -> - Cs = - case CompList of - {Comp1, EComps, Comp2} -> - Comp1++EComps++Comp2; - {Components,EComponents} when is_list(Components) -> - Components ++ EComponents; - CompList when is_list(CompList) -> - CompList - end, %% get_simple_table_if_used/2 should find out whether there are any %% component relation constraints in the entire tree of Cs1 that @@ -6135,12 +6146,22 @@ componentrelation_leadingattr(S,CompList) -> %% componentrelation_leadingattr/6. The step when the leading %% attribute and the syntax tree is modified to support the code %% generating. - case get_simple_table_if_used(S,Cs) of + case get_simple_table_if_used(S,CompList) of [] -> {false,CompList}; - STList -> - componentrelation_leadingattr(S,Cs,Cs,STList,[],[]) + _ -> + componentrelation_leadingattr(S,CompList,CompList,[],[]) end. + +%%FIXME expand_ExtAddGroups([C#'ExtensionAdditionGroup'{components=ExtAdds}|T], +%% CurrPos,PosAcc,CompAcc) -> +%% expand_ExtAddGroups(T,CurrPos+ L = lenght(ExtAdds),[{CurrPos,L}|PosAcc],ExtAdds++CompAcc); +%% expand_ExtAddGroups([C|T],CurrPos,PosAcc,CompAcc) -> +%% expand_ExtAddGroups(T,CurrPos+ 1,PosAcc,[C|CompAcc]); +%% expand_ExtAddGroups([],_CurrPos,PosAcc,CompAcc) -> +%% {lists:reverse(PosAcc),lists:reverse(CompAcc)}. + + %% componentrelation_leadingattr/6 when all components are searched %% the new modified components are returned together with the "leading %% attribute" information, which later is stored in the tablecinf @@ -6150,11 +6171,12 @@ componentrelation_leadingattr(S,CompList) -> %% is used in code generating phase too, to recognice the proper %% components for "open type" encoding and to propagate the result of %% the object set lookup when needed. -componentrelation_leadingattr(_,[],_CompList,_,[],NewCompList) -> +componentrelation_leadingattr(_,[],_CompList,[],NewCompList) -> {false,lists:reverse(NewCompList)}; -componentrelation_leadingattr(_,[],_CompList,_,LeadingAttr,NewCompList) -> +componentrelation_leadingattr(_,[],_CompList,LeadingAttr,NewCompList) -> {lists:last(LeadingAttr),lists:reverse(NewCompList)}; %send all info in Ts later -componentrelation_leadingattr(S,[C|Cs],CompList,STList,Acc,CompAcc) -> + +componentrelation_leadingattr(S,[C= #'ComponentType'{}|Cs],CompList,Acc,CompAcc) -> {LAAcc,NewC} = case catch componentrelation1(S,C#'ComponentType'.typespec, [C#'ComponentType'.name]) of @@ -6205,7 +6227,7 @@ componentrelation_leadingattr(S,[C|Cs],CompList,STList,Acc,CompAcc) -> %% no constraint was found {[],C} end, - componentrelation_leadingattr(S,Cs,CompList,STList,LAAcc++Acc, + componentrelation_leadingattr(S,Cs,CompList,LAAcc++Acc, [NewC|CompAcc]). object_set_mod_name(_S,ObjSet) when is_atom(ObjSet) -> @@ -6228,11 +6250,9 @@ object_set_mod_name(S,#'Externaltypereference'{module=M,type=T}) -> %% generation of the look up functionality in the object set table are %% returned. get_simple_table_if_used(S,Cs) -> - CNames = lists:map(fun(#'ComponentType'{name=Name}) -> Name; - (_) -> [] %% in case of extension marks - end, - Cs), - RefedSimpleTable=any_component_relation(S,Cs,CNames,[],[]), + CNames = [Name||#'ComponentType'{name=Name}<-Cs], + JustComponents = [C || C = #'ComponentType'{}<-Cs], + RefedSimpleTable=any_component_relation(S,JustComponents,CNames,[],[]), get_simple_table_info(S,Cs,remove_doubles(RefedSimpleTable)). remove_doubles(L) -> @@ -6336,9 +6356,7 @@ simple_table_info(S,Type,_) -> %% beginning of the search. CNames holds the names of all components %% of the start level, this info is used if an outermost at-notation %% is found to check the validity of the at-list. -any_component_relation(S,[C|Cs],CNames,NamePath,Acc) -> - CName = C#'ComponentType'.name, - Type = C#'ComponentType'.typespec, +any_component_relation(S,[#'ComponentType'{name=CName,typespec=Type}|Cs],CNames,NamePath,Acc) -> CRelPath = case constraint_member(componentrelation,Type#type.constraint) of %% [{componentrelation,_,AtNotation}] -> @@ -6358,9 +6376,9 @@ any_component_relation(S,[C|Cs],CNames,NamePath,Acc) -> case {Type#type.inlined, asn1ct_gen:type(asn1ct_gen:get_inner(Type#type.def))} of {no,{constructed,bif}} -> + {InnerCs,NewNamePath} = case get_components(Type#type.def) of - {IC1,_IC2} -> {IC1 ++ IC1,[CName|NamePath]}; T when is_record(T,type) -> {T,NamePath}; IC -> {IC,[CName|NamePath]} end, @@ -6384,11 +6402,7 @@ any_component_relation(S,Type,CNames,NamePath,Acc) when is_record(Type,type) -> case {Type#type.inlined, asn1ct_gen:type(asn1ct_gen:get_inner(Type#type.def))} of {no,{constructed,bif}} -> - InnerCs = - case get_components(Type#type.def) of - {IC1,_IC2} -> IC1 ++ IC1; - IC -> IC - end, + InnerCs = get_components(Type#type.def), any_component_relation(S,InnerCs,CNames,NamePath,[]); _ -> [] @@ -6456,11 +6470,11 @@ get_components(Def) -> get_components(any,Def). get_components(_,#'SEQUENCE'{components=Cs}) -> - Cs; + tuple2complist(Cs); get_components(_,#'SET'{components=Cs}) -> - Cs; + tuple2complist(Cs); get_components(_,{'CHOICE',Cs}) -> - Cs; + tuple2complist(Cs); %do not step in inlined structures get_components(any,{'SEQUENCE OF',T = #type{def=_Def,inlined=no}}) -> % get_components(any,Def); @@ -6471,6 +6485,13 @@ get_components(any,{'SET OF',T = #type{def=_Def,inlined=no}}) -> get_components(_,_) -> []. +tuple2complist({R,E}) -> + R ++ E; +tuple2complist({R1,E,R2}) -> + R1 ++ E ++ R2; +tuple2complist(List) when is_list(List) -> + List. + get_choice_components(_S,{'CHOICE',Components}) when is_list(Components)-> Components; get_choice_components(_S,{'CHOICE',{C1,C2}}) when is_list(C1),is_list(C2) -> @@ -6731,8 +6752,7 @@ get_tableconstraint_info(S,Type,CheckedTs) -> get_tableconstraint_info(_S,_Type,[],Acc) -> lists:reverse(Acc); -get_tableconstraint_info(S,Type,[C|Cs],Acc) -> - CheckedTs = C#'ComponentType'.typespec, +get_tableconstraint_info(S,Type,[C=#'ComponentType'{typespec=CheckedTs}|Cs],Acc) -> AccComp = case CheckedTs#type.def of %% ObjectClassFieldType @@ -6768,7 +6788,9 @@ get_tableconstraint_info(S,Type,[C|Cs],Acc) -> _ -> C end, - get_tableconstraint_info(S,Type,Cs,[AccComp|Acc]). + get_tableconstraint_info(S,Type,Cs,[AccComp|Acc]); +get_tableconstraint_info(S,Type,[C|Cs],Acc) -> + get_tableconstraint_info(S,Type,Cs,[C|Acc]). get_referenced_fieldname([{_,FirstFieldname}]) -> {FirstFieldname,[]}; @@ -6850,7 +6872,9 @@ get_taglist(S,Type) when is_record(Type,type) -> [asn1ct_gen:def_to_tag(Tag)] end; get_taglist(S,{'CHOICE',{Rc,Ec}}) -> - get_taglist(S,{'CHOICE',Rc ++ Ec}); + get_taglist1(S,Rc ++ Ec); +get_taglist(S,{'CHOICE',{R1,E,R2}}) -> + get_taglist1(S,R1 ++ E ++ R2); get_taglist(S,{'CHOICE',Components}) -> get_taglist1(S,Components); %% ObjectClassFieldType OTP-4390 diff --git a/lib/asn1/src/asn1ct_constructed_ber.erl b/lib/asn1/src/asn1ct_constructed_ber.erl index 51a241ffbd..77b78dcac7 100644 --- a/lib/asn1/src/asn1ct_constructed_ber.erl +++ b/lib/asn1/src/asn1ct_constructed_ber.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1997-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 1997-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% %% %% @@ -71,13 +71,15 @@ gen_encode_sequence(Erules,Typename,D) when is_record(D,type) -> ok end, - {SeqOrSet,TableConsInfo,CompList} = + {SeqOrSet,TableConsInfo,CompList0} = case D#type.def of #'SEQUENCE'{tablecinf=TCI,components=CL} -> {'SEQUENCE',TCI,CL}; #'SET'{tablecinf=TCI,components=CL} -> {'SET',TCI,CL} end, + %% filter away extensionAdditiongroup markers + CompList = filter_complist(CompList0), Ext = extensible(CompList), CompList1 = case CompList of {Rl1,El,Rl2} -> Rl1 ++ El ++ Rl2; @@ -189,7 +191,11 @@ gen_encode_sequence(Erules,Typename,D) when is_record(D,type) -> gen_decode_sequence(Erules,Typename,D) when is_record(D,type) -> asn1ct_name:start(), asn1ct_name:new(tag), - #'SEQUENCE'{tablecinf=TableConsInfo,components=CList} = D#type.def, + #'SEQUENCE'{tablecinf=TableConsInfo,components=CList0} = D#type.def, + + %% filter away extensionAdditiongroup markers + CList = filter_complist(CList0), + Ext = extensible(CList), {CompList,CompList2} = case CList of {Rl1,El,Rl2} -> {Rl1 ++ El ++ Rl2,CList}; @@ -369,7 +375,10 @@ gen_decode_set(Erules,Typename,D) when is_record(D,type) -> asn1ct_name:clear(), asn1ct_name:new(term), asn1ct_name:new(tag), - #'SET'{components=TCompList} = D#type.def, + #'SET'{components=TCompList0} = D#type.def, + + %% filter away extensionAdditiongroup markers + TCompList = filter_complist(TCompList0), Ext = extensible(TCompList), ToOptional = fun(mandatory) -> 'OPTIONAL'; @@ -1473,6 +1482,22 @@ extensible({RootList,ExtList}) -> {ext,length(RootList)+1,length(ExtList)}; extensible({_Rl1,_ExtL,_Rl2}) -> extensible. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% filter away ExtensionAdditionGroup start and end marks since these +%% have no significance for the BER encoding +%% +filter_complist(CompList) when is_list(CompList) -> + lists:filter(fun(#'ExtensionAdditionGroup'{}) -> + false; + ('ExtensionAdditionGroupEnd') -> + false; + (_) -> + true + end, CompList); +filter_complist({Root,Ext}) -> + {Root,filter_complist(Ext)}; +filter_complist({Root1,Ext,Root2}) -> + {Root1,filter_complist(Ext),Root2}. print_attribute_comment(InnerType,Pos,Prop) -> CommentLine = "%%-------------------------------------------------", diff --git a/lib/asn1/src/asn1ct_constructed_per.erl b/lib/asn1/src/asn1ct_constructed_per.erl index 2a1c0ebc6b..df430c4f88 100644 --- a/lib/asn1/src/asn1ct_constructed_per.erl +++ b/lib/asn1/src/asn1ct_constructed_per.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1997-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 1997-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% %% %% @@ -46,13 +46,24 @@ gen_encode_constructed(Erule,Typename,D) when is_record(D,type) -> asn1ct_name:start(), asn1ct_name:new(term), asn1ct_name:new(bytes), - {CompList,TableConsInfo} = + {ExtAddGroup,TmpCompList,TableConsInfo} = case D#type.def of - #'SEQUENCE'{tablecinf=TCI,components=CL} -> - {CL,TCI}; + #'SEQUENCE'{tablecinf=TCI,components=CL,extaddgroup=ExtAddGroup0} -> + {ExtAddGroup0,CL,TCI}; #'SET'{tablecinf=TCI,components=CL} -> - {CL,TCI} + {undefined,CL,TCI} end, + + CompList = case ExtAddGroup of + undefined -> + TmpCompList; + _ when is_integer(ExtAddGroup) -> + %% This is a fake SEQUENCE representing an ExtensionAdditionGroup + %% Reset the textual order so we get the right + %% index of the components + [Comp#'ComponentType'{textual_order=undefined}|| + Comp<-TmpCompList] + end, case Typename of ['EXTERNAL'] -> emit({{var,asn1ct_name:next(val)}, @@ -78,7 +89,7 @@ gen_encode_constructed(Erule,Typename,D) when is_record(D,type) -> ",",{var,asn1ct_name:curr(val)},"),",nl}) end, asn1ct_name:new(val), - Ext = extensible(CompList), + Ext = extensible_enc(CompList), case Ext of {ext,_,NumExt} when NumExt > 0 -> emit(["Extensions = ?RT_PER:fixextensions(",{asis,Ext}, @@ -188,9 +199,10 @@ gen_decode_constructed(Erules,Typename,D) when is_record(D,type) -> #'SEQUENCE'{tablecinf=TCI,components=CL} -> {add_textual_order(CL),TCI}; #'SET'{tablecinf=TCI,components=CL} -> - {add_textual_order(CL),TCI} +%% {add_textual_order(CL),TCI} + {CL,TCI} % the textual order is already taken care of end, - Ext = extensible(CompList), + Ext = extensible_dec(CompList), MaybeComma1 = case Ext of {ext,_Pos,_NumExt} -> gen_dec_extension_value("Bytes"), @@ -243,8 +255,9 @@ gen_decode_constructed(Erules,Typename,D) when is_record(D,type) -> {false,false,false} end end, + NewCompList = wrap_compList(CompList), {AccTerm,AccBytes} = - gen_dec_components_call(Erules,Typename,CompList,MaybeComma2,DecObjInf,Ext,length(Optionals)), + gen_dec_components_call(Erules,Typename,NewCompList,MaybeComma2,DecObjInf,Ext,length(Optionals)), case asn1ct_name:all(term) of [] -> emit(MaybeComma2); % no components at all _ -> emit({com,nl}) @@ -284,7 +297,10 @@ gen_decode_constructed(Erules,Typename,D) when is_record(D,type) -> emit(" {ASN11994Format,"); _ -> emit(["{{'",RecordName,"'"]), - mkvlist(textual_order(CompList,asn1ct_name:all(term))), + %% CompList is used here because we don't want + %% ExtensionAdditionGroups to be wrapped in SEQUENCES when + %% we are ordering the fields according to textual order + mkvlist(textual_order(to_encoding_order(CompList),asn1ct_name:all(term))), emit("},") end, emit({{var,asn1ct_name:curr(bytes)},"}"}), @@ -293,17 +309,12 @@ gen_decode_constructed(Erules,Typename,D) when is_record(D,type) -> textual_order([#'ComponentType'{textual_order=undefined}|_],TermList) -> TermList; textual_order(CompList,TermList) when is_list(CompList) -> - TermTuple = list_to_tuple(TermList), %% ['Term1','Term2',...'TermN'] - %% OrderList is ordered by canonical order of tags - TmpTuple = TermTuple, - OrderList = [Ix||#'ComponentType'{textual_order=Ix} <- CompList], - Fun = fun(X,{Tpl,Ix}) -> - - {setelement(X,Tpl,element(Ix,TermTuple)),Ix+1} - end, - {Ret,_} = lists:foldl(Fun,{TmpTuple,1},OrderList), -%% io:format("TermTuple: ~p~nOrderList: ~p~nRet: ~p~n",[TermTuple,OrderList,tuple_to_list(Ret)]), - tuple_to_list(Ret); + OrderList = [Ix||#'ComponentType'{textual_order=Ix} <- CompList], + [Term||{_,Term}<- + lists:sort(lists:zip(OrderList, + lists:sublist(TermList,length(OrderList))))]; + %% sublist is just because Termlist can sometimes be longer than + %% OrderList, which it really shouldn't textual_order({Root,Ext},TermList) -> textual_order(Root ++ Ext,TermList); textual_order({Root1,Ext,Root2},TermList) -> @@ -379,7 +390,7 @@ emit_opt_or_mand_check(Val,Term) -> gen_encode_choice(Erule,Typename,D) when is_record(D,type) -> {'CHOICE',CompList} = D#type.def, emit({"[",nl}), - Ext = extensible(CompList), + Ext = extensible_enc(CompList), gen_enc_choice(Erule,Typename,CompList,Ext), emit({nl,"].",nl}). @@ -388,7 +399,7 @@ gen_decode_choice(Erules,Typename,D) when is_record(D,type) -> asn1ct_name:clear(), asn1ct_name:new(bytes), {'CHOICE',CompList} = D#type.def, - Ext = extensible(CompList), + Ext = extensible_enc(CompList), gen_dec_choice(Erules,Typename,CompList,Ext), emit({".",nl}). @@ -558,12 +569,32 @@ mkvlist2([H|T]) -> mkvlist2([]) -> true. -extensible(CompList) when is_list(CompList) -> + +extensible_dec(CompList) when is_list(CompList) -> + noext; +extensible_dec({RootList,ExtList}) -> + {ext,length(RootList)+1,ext_length(ExtList)}; +extensible_dec({Rl1,Ext,Rl2}) -> + {ext,length(Rl1)+length(Rl2)+1,ext_length(Ext)}. + +extensible_enc(CompList) when is_list(CompList) -> noext; -extensible({RootList,ExtList}) -> - {ext,length(RootList)+1,length(ExtList)}; -extensible({Rl1,Ext,_Rl2}) -> - {ext,length(Rl1)+1,length(Ext)}. +extensible_enc({RootList,ExtList}) -> + {ext,length(RootList)+1,ext_length(ExtList)}; +extensible_enc({Rl1,Ext,_Rl2}) -> + {ext,length(Rl1)+1,ext_length(Ext)}. + +ext_length(ExtList) -> ext_length(ExtList,normal,0). +ext_length([{'ExtensionAdditionGroup',_Num}|T],_,Acc)-> + ext_length(T,group,Acc); +ext_length(['ExtensionAdditionGroupEnd'|T],group,Acc) -> + ext_length(T,normal,Acc+1); +ext_length([#'ComponentType'{}|T],State=group,Acc) -> + ext_length(T,State,Acc); +ext_length([#'ComponentType'{}|T],State=normal,Acc) -> + ext_length(T,State,Acc+1); +ext_length([],_,Acc) -> + Acc. gen_dec_extension_value(_) -> emit({"{Ext,",{next,bytes},"} = ?RT_PER:getext(",{curr,bytes},")"}), @@ -574,7 +605,11 @@ gen_dec_extension_value(_) -> %% there are optional components, start with 2 because first element %% is the record name -optionals({L1,_Ext,L2}) -> optionals(L1++L2,[],2); +optionals({L1,Ext,L2}) -> + Opt1 = optionals(L1,[],2), + ExtComps = length([C||C = #'ComponentType'{}<-Ext]), + Opt2 = optionals(L2,[],2+length(L1)+ExtComps), + Opt1 ++ Opt2; optionals({L,_Ext}) -> optionals(L,[],2); optionals(L) -> optionals(L,[],2). @@ -617,6 +652,13 @@ get_optionality_pos(TextPos,OptTable) -> no_num end. +to_encoding_order(Cs) when is_list(Cs) -> + Cs; +to_encoding_order(Cs = {_Root,_Ext}) -> + Cs; +to_encoding_order({R1,Ext,R2}) -> + {R1++R2,Ext}. + add_textual_order(Cs) when is_list(Cs) -> {NewCs,_} = add_textual_order1(Cs,1), NewCs; @@ -629,26 +671,20 @@ add_textual_order({R1,Ext,R2}) -> {NewExt,Num2} = add_textual_order1(Ext,Num1), {NewR2,_} = add_textual_order1(R2,Num2), {NewR1,NewExt,NewR2}. -add_textual_order1(Cs=[#'ComponentType'{textual_order=Int}|_],I) - when is_integer(Int) -> - {Cs,I}; +%%add_textual_order1(Cs=[#'ComponentType'{textual_order=Int}|_],I) +%% when is_integer(Int) -> +%% {Cs,I}; add_textual_order1(Cs,NumIn) -> - lists:mapfoldl(fun(C,Num) -> + lists:mapfoldl(fun(C=#'ComponentType'{},Num) -> {C#'ComponentType'{textual_order=Num}, - Num+1} + Num+1}; + (OtherMarker,Num) -> + {OtherMarker,Num} end, NumIn,Cs). gen_enc_components_call(Erule,TopType,{Root1,ExtList,Root2},MaybeComma,DynamicEnc,Ext) -> - Rpos = gen_enc_components_call1(Erule,TopType,Root1,1,MaybeComma,DynamicEnc,noext), - case Ext of - {ext,_,ExtNum} when ExtNum > 0 -> - emit([nl, - ",Extensions",nl]); - _ -> true - end, - Rpos2 = gen_enc_components_call1(Erule,TopType,ExtList,Rpos,MaybeComma,DynamicEnc,Ext), - gen_enc_components_call1(Erule,TopType,Root2,Rpos2,MaybeComma,DynamicEnc,noext); + gen_enc_components_call(Erule,TopType,{Root1++Root2,ExtList},MaybeComma,DynamicEnc,Ext); gen_enc_components_call(Erule,TopType,{CompList,ExtList},MaybeComma,DynamicEnc,Ext) -> %% The type has extensionmarker Rpos = gen_enc_components_call1(Erule,TopType,CompList,1,MaybeComma,DynamicEnc,noext), @@ -659,7 +695,8 @@ gen_enc_components_call(Erule,TopType,{CompList,ExtList},MaybeComma,DynamicEnc,E _ -> true end, %handle extensions - gen_enc_components_call1(Erule,TopType,ExtList,Rpos,MaybeComma,DynamicEnc,Ext); + NewExtList = wrap_extensionAdditionGroups(ExtList), + gen_enc_components_call1(Erule,TopType,NewExtList,Rpos,MaybeComma,DynamicEnc,Ext); gen_enc_components_call(Erule,TopType, CompList, MaybeComma, DynamicEnc, Ext) -> %% The type has no extensionmarker gen_enc_components_call1(Erule,TopType,CompList,1,MaybeComma,DynamicEnc,Ext). @@ -719,6 +756,26 @@ gen_enc_component_default(Erule,TopType,Cname,Type,Pos,DynamicEnc,Ext,DefaultVal 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) -> + emit({nl,"begin",nl}), + + asn1ct_name:new(tmpval), + ExtAddGroupTypeName = asn1ct_gen:list2name([Cname|TopType]), + emit({{curr,tmpval}," = {'",ExtAddGroupTypeName,"', "}), + ExtNames = [ExtName||#'ComponentType'{name=ExtName}<-ExtGroupCompList], + Elements = make_elements(Pos+1,"Val1",ExtNames), + emit({Elements,"},"}), + 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,"Val1",Cname), emit({"case ",Element," of",nl}), @@ -834,29 +891,7 @@ gen_enc_line(Erule,TopType,Cname,Type,Element, _Pos,DynamicEnc,Ext) -> _ -> true end. gen_dec_components_call(Erule,TopType,{Root1,ExtList,Root2},MaybeComma,DecInfObj,Ext,NumberOfOptionals) -> - %% The type has extensionmarker - OptTable = create_optionality_table(Root1 ++ Root2), - {Rpos,AccTerm,AccBytes} = - gen_dec_components_call1(Erule,TopType, Root1, 1, OptTable, - MaybeComma,DecInfObj, noext,[],[], - NumberOfOptionals), - emit([",",nl,"{Extensions,",{next,bytes},"} = "]), - emit(["?RT_PER:getextension(Ext,",{curr,bytes},"),",nl]), - asn1ct_name:new(bytes), - {Epos,AccTermE,AccBytesE} = - gen_dec_components_call1(Erule,TopType,ExtList,Rpos, OptTable, "", - DecInfObj,Ext,[],[],NumberOfOptionals), - case ExtList of - [] -> true; - _ -> emit([",",nl]) - end, - emit([{next,bytes},"= ?RT_PER:skipextensions(",{curr,bytes},",", - length(ExtList)+1,",Extensions),",nl]), - asn1ct_name:new(bytes), - {_RPos2,AccTerm2,AccBytes2} = - gen_dec_components_call1(Erule,TopType,Root2,Epos,OptTable, - "",DecInfObj,noext,[],[],NumberOfOptionals), - {AccTerm++AccTermE++AccTerm2,AccBytes++AccBytesE++AccBytes2}; + gen_dec_components_call(Erule,TopType,{Root1++Root2,ExtList},MaybeComma,DecInfObj,Ext,NumberOfOptionals); gen_dec_components_call(Erule,TopType,{CompList,ExtList},MaybeComma, DecInfObj,Ext,NumberOfOptionals) -> %% The type has extensionmarker @@ -868,8 +903,9 @@ gen_dec_components_call(Erule,TopType,{CompList,ExtList},MaybeComma, emit([",",nl,"{Extensions,",{next,bytes},"} = "]), emit(["?RT_PER:getextension(Ext,",{curr,bytes},"),",nl]), asn1ct_name:new(bytes), + NewExtList = wrap_extensionAdditionGroups(ExtList), {_Epos,AccTermE,AccBytesE} = - gen_dec_components_call1(Erule,TopType,ExtList,Rpos, OptTable, + gen_dec_components_call1(Erule,TopType,NewExtList,Rpos, OptTable, "",DecInfObj,Ext,[],[],NumberOfOptionals), case ExtList of [] -> true; @@ -942,8 +978,18 @@ gen_dec_components_call1(Erule,TopType, asn1ct_name:new(tmpterm), emit({"{",{curr,tmpterm},", ",{next,bytes},"} = "}); _ -> - asn1ct_name:new(term), - emit({"{",{curr,term},",",{next,bytes},"} = "}) + case Type of + #type{def=#'SEQUENCE'{ + extaddgroup=Number1, + components=ExtGroupCompList1}} when is_integer(Number1)-> + emit({"{{_,"}), + emit_extaddgroupTerms(term,ExtGroupCompList1), + emit({"}"}); + _ -> + asn1ct_name:new(term), + emit({"{",{curr,term}}) + end, + emit({",",{next,bytes},"} = "}) end, case {Ext,Prop,is_optimized(Erule)} of @@ -967,11 +1013,24 @@ gen_dec_components_call1(Erule,TopType, {noext,mandatory} -> true; % generate nothing {noext,_} -> emit([";",nl,"0 ->"]), - gen_dec_component_no_val(TopType,Cname,Type,Prop,Tpos,Ext), + emit(["{"]), + gen_dec_component_no_val(Ext,Prop), + emit({",",{curr,bytes},"}",nl}), emit([nl,"end"]); _ -> emit([";",nl,"_ ->",nl]), - gen_dec_component_no_val(TopType,Cname,Type,Prop,Tpos,Ext), + emit(["{"]), + case Type of + #type{def=#'SEQUENCE'{ + extaddgroup=Number2, + components=ExtGroupCompList2}} when is_integer(Number2)-> + emit({"{extAddGroup,"}), + gen_dec_extaddGroup_no_val(Ext,ExtGroupCompList2), + emit({"}"}); + _ -> + gen_dec_component_no_val(Ext,Prop) + end, + emit({",",{curr,bytes},"}",nl}), emit([nl,"end"]) end, asn1ct_name:new(bytes), @@ -988,13 +1047,22 @@ gen_dec_components_call1(Erule,TopType, gen_dec_components_call1(_,_TopType,[],Pos,_OptTable,_,_,_,AccTerm,AccBytes,_NumberOfOptionals) -> {Pos,AccTerm,AccBytes}. - -gen_dec_component_no_val(_,_,_,{'DEFAULT',DefVal},_,_) -> - emit(["{",{asis,DefVal},",",{curr,bytes},"}",nl]); -gen_dec_component_no_val(_,_,_,'OPTIONAL',_,_) -> - emit({"{asn1_NOVALUE,",{curr,bytes},"}",nl}); -gen_dec_component_no_val(_,_,_,mandatory,_,{ext,_,_}) -> - emit({"{asn1_NOVALUE,",{curr,bytes},"}",nl}). +gen_dec_extaddGroup_no_val(Ext,[#'ComponentType'{prop=Prop}])-> + gen_dec_component_no_val(Ext,Prop), + ok; +gen_dec_extaddGroup_no_val(Ext,[#'ComponentType'{prop=Prop}|Rest])-> + gen_dec_component_no_val(Ext,Prop), + emit({","}), + gen_dec_extaddGroup_no_val(Ext,Rest); +gen_dec_extaddGroup_no_val(_, []) -> + ok. + +gen_dec_component_no_val(_,{'DEFAULT',DefVal}) -> + emit([{asis,DefVal}]); +gen_dec_component_no_val(_,'OPTIONAL') -> + emit({"asn1_NOVALUE"}); +gen_dec_component_no_val({ext,_,_},mandatory) -> + emit({"asn1_NOVALUE"}). gen_dec_line(Erule,TopType,Cname,Type,Pos,DecInfObj,Ext,Prop) -> @@ -1192,6 +1260,14 @@ gen_enc_choice_tag({C1,C2},_,_) -> N2 = get_name_list(C2), emit(["?RT_PER:set_choice(element(1,Val),", {asis,{N1,N2}},", ",{asis,{length(N1),length(N2)}},")"]); + +gen_enc_choice_tag({C1,C2,C3},_,_) -> + N1 = get_name_list(C1), + N2 = get_name_list(C2), + N3 = get_name_list(C3), + Root = N1 ++ N3, + emit(["?RT_PER:set_choice(element(1,Val),", + {asis,{Root,N2}},", ",{asis,{length(Root),length(N2)}},")"]); gen_enc_choice_tag(C,_,_) -> N = get_name_list(C), emit(["?RT_PER:set_choice(element(1,Val),", @@ -1208,6 +1284,8 @@ get_name_list([], 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). @@ -1279,6 +1357,9 @@ gen_dec_choice1(Erule,TopType,CompList,noext) -> gen_dec_choice1(Erule,TopType,{RootList,ExtList},Ext) -> NewList = RootList ++ ExtList, gen_dec_choice1(Erule,TopType, NewList, Ext); +gen_dec_choice1(Erule,TopType,{RootList,ExtList,RootList2},Ext) -> + NewList = RootList ++ RootList2 ++ ExtList, + gen_dec_choice1(Erule,TopType, NewList, Ext); gen_dec_choice1(Erule,TopType,CompList,{ext,ExtPos,ExtNum}) -> emit({"{Choice,",{curr,bytes}, "} = ?RT_PER:getchoice(",{prev,bytes},",", @@ -1347,6 +1428,18 @@ gen_encode_prim_wrapper(CtgenMod,Erule,Cont,DoTag,Value) -> CtgenMod:gen_encode_prim(Erule,Cont,DoTag,Value). % erase(component_type). +make_elements(I,Val,ExtCnames) -> + make_elements(I,Val,ExtCnames,[]). + +make_elements(I,Val,[ExtCname],Acc)-> % the last one, no comma needed + Element = make_element(I,Val,ExtCname), + make_elements(I+1,Val,[],[Element|Acc]); +make_elements(I,Val,[ExtCname|Rest],Acc)-> + Element = make_element(I,Val,ExtCname), + make_elements(I+1,Val,Rest,[", ",Element|Acc]); +make_elements(_I,_,[],Acc) -> + lists:reverse(Acc). + make_element(I,Val,Cname) -> case tuple_notation_allowed() of true -> @@ -1355,6 +1448,55 @@ make_element(I,Val,Cname) -> io_lib:format("element(~w,~s)",[I,Val]) end. +emit_extaddgroupTerms(VarSeries,[_]) -> + asn1ct_name:new(VarSeries), + emit({curr,VarSeries}), + ok; +emit_extaddgroupTerms(VarSeries,[_|Rest]) -> + asn1ct_name:new(VarSeries), + emit({{curr,VarSeries},","}), + emit_extaddgroupTerms(VarSeries,Rest); +emit_extaddgroupTerms(_,[]) -> + ok. +wrap_compList({Root1,Ext,Root2}) -> + {Root1,wrap_extensionAdditionGroups(Ext),Root2}; +wrap_compList({Root1,Ext}) -> + {Root1,wrap_extensionAdditionGroups(Ext)}; +wrap_compList(CompList) -> + CompList. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% Will convert all componentTypes following 'ExtensionAdditionGroup' +%% up to the matching 'ExtensionAdditionGroupEnd' into one componentType +%% of type SEQUENCE with the componentTypes as components +%% +wrap_extensionAdditionGroups(ExtCompList) -> + wrap_extensionAdditionGroups(ExtCompList,[],0). + +wrap_extensionAdditionGroups([{'ExtensionAdditionGroup',_Number}|Rest],Acc,0) -> + {ExtGroupCompList= + [#'ComponentType'{textual_order=TextPos}|_], + ['ExtensionAdditionGroupEnd'|Rest2]} = + lists:splitwith(fun(#'ComponentType'{}) -> true; + (_) -> false + end, + Rest), + wrap_extensionAdditionGroups(Rest2, + [#'ComponentType'{ + name='ExtAddGroup', % FIXME: handles ony one ExtAddGroup + typespec=#type{def=#'SEQUENCE'{ + extaddgroup=1,% FIXME: handles only one + components=ExtGroupCompList}}, + textual_order = TextPos, + prop='OPTIONAL'}|Acc],length(ExtGroupCompList)-1); +wrap_extensionAdditionGroups([H=#'ComponentType'{textual_order=Tord}|T],Acc,ExtAddGroupDiff) when is_integer(Tord) -> + wrap_extensionAdditionGroups(T,[H#'ComponentType'{ + textual_order=Tord - ExtAddGroupDiff}|Acc],ExtAddGroupDiff); +wrap_extensionAdditionGroups([H|T],Acc,ExtAddGroupDiff) -> + wrap_extensionAdditionGroups(T,[H|Acc],ExtAddGroupDiff); +wrap_extensionAdditionGroups([],Acc,_) -> + lists:reverse(Acc). + + tuple_notation_allowed() -> Options = get(encoding_options), not (lists:member(optimize,Options) orelse lists:member(uper_bin,Options)). diff --git a/lib/asn1/src/asn1ct_gen.erl b/lib/asn1/src/asn1ct_gen.erl index eab5fb4a2a..6b511a66da 100644 --- a/lib/asn1/src/asn1ct_gen.erl +++ b/lib/asn1/src/asn1ct_gen.erl @@ -536,14 +536,34 @@ gen_part_decode_funcs({primitive,bif},_TypeName, gen_part_decode_funcs(WhatKind,_TypeName,{_,Directive,_,_}) -> throw({error,{asn1,{"Not implemented yet",WhatKind," partial incomplete directive:",Directive}}}). + +extaddgroup2sequence(ExtList) -> + extaddgroup2sequence(ExtList,[]). + +extaddgroup2sequence([{'ExtensionAdditionGroup',Number0}|T],Acc) -> + Number = case Number0 of undefined -> 1; _ -> Number0 end, + {ExtGroupComps,['ExtensionAdditionGroupEnd'|T2]} = + lists:splitwith(fun(Elem) -> is_record(Elem,'ComponentType') end,T), + extaddgroup2sequence(T2,[#'ComponentType'{ + name='ExtAddGroup', + typespec=#type{def=#'SEQUENCE'{ + extaddgroup=Number, + components=ExtGroupComps}}, + prop='OPTIONAL'}|Acc]); +extaddgroup2sequence([C|T],Acc) -> + extaddgroup2sequence(T,[C|Acc]); +extaddgroup2sequence([],Acc) -> + lists:reverse(Acc). + + gen_types(Erules,Tname,{RootL1,ExtList,RootL2}) when is_list(RootL1), is_list(RootL2) -> gen_types(Erules,Tname,RootL1), - gen_types(Erules,Tname,ExtList), + gen_types(Erules,Tname,extaddgroup2sequence(ExtList)), gen_types(Erules,Tname,RootL2); gen_types(Erules,Tname,{RootList,ExtList}) when is_list(RootList) -> gen_types(Erules,Tname,RootList), - gen_types(Erules,Tname,ExtList); + gen_types(Erules,Tname,extaddgroup2sequence(ExtList)); gen_types(Erules,Tname,[{'EXTENSIONMARK',_,_}|Rest]) -> gen_types(Erules,Tname,Rest); gen_types(Erules,Tname,[ComponentType|Rest]) -> @@ -1543,19 +1563,18 @@ gen_record2(Name,SeqOrSet,Comps) -> gen_record2(_Name,_SeqOrSet,[],_Com,_Extension) -> true; -gen_record2(Name,SeqOrSet,[{'EXTENSIONMARK',_,_}|T],Com,Extension) -> - gen_record2(Name,SeqOrSet,T,Com,Extension); -gen_record2(_Name,_SeqOrSet,[H],Com,Extension) -> - #'ComponentType'{name=Cname} = H, +gen_record2(_Name,_SeqOrSet,[H = #'ComponentType'{name=Cname}],Com,Extension) -> emit(Com), emit({asis,Cname}), gen_record_default(H, Extension); -gen_record2(Name,SeqOrSet,[H|T],Com, Extension) -> - #'ComponentType'{name=Cname} = H, +gen_record2(Name,SeqOrSet,[H = #'ComponentType'{name=Cname}|T],Com, Extension) -> emit(Com), emit({asis,Cname}), gen_record_default(H, Extension), - gen_record2(Name,SeqOrSet,T,", ", Extension). + gen_record2(Name,SeqOrSet,T,", ", Extension); +gen_record2(Name,SeqOrSet,[_|T],Com,Extension) -> + %% skip EXTENSIONMARK, ExtensionAdditionGroup and other markers + gen_record2(Name,SeqOrSet,T,Com,Extension). gen_record_default(#'ComponentType'{prop='OPTIONAL'}, _)-> emit(" = asn1_NOVALUE"); diff --git a/lib/asn1/src/asn1ct_parser2.erl b/lib/asn1/src/asn1ct_parser2.erl index 46d7ad6fdb..224a535e87 100644 --- a/lib/asn1/src/asn1ct_parser2.erl +++ b/lib/asn1/src/asn1ct_parser2.erl @@ -417,10 +417,22 @@ parse_BuiltinType([{'CHARACTER',_},{'STRING',_}|Rest]) -> {#type{def='CHARACTER STRING'},Rest}; parse_BuiltinType([{'CHOICE',_},{'{',_}|Rest]) -> - {AlternativeTypeLists,Rest2} = parse_AlternativeTypeLists(Rest,get(extensiondefault)), + {AlternativeTypeLists,Rest2} = parse_AlternativeTypeLists(Rest), + AlternativeTypeLists1 = + lists:filter(fun(#'ExtensionAdditionGroup'{}) -> false; + ('ExtensionAdditionGroupEnd') -> false; + (_) -> true + end,AlternativeTypeLists), case Rest2 of [{'}',_}|Rest3] -> - {#type{def={'CHOICE',AlternativeTypeLists}},Rest3}; + AlternativeTypeLists2 = + case {[Ext||Ext = #'EXTENSIONMARK'{} <- AlternativeTypeLists1], + get(extensiondefault)} of + {[],'IMPLIED'} -> AlternativeTypeLists1 ++ [#'EXTENSIONMARK'{}]; + _ -> AlternativeTypeLists1 + end, + + {#type{def={'CHOICE',AlternativeTypeLists2}},Rest3}; _ -> throw({asn1_error,{get_line(hd(Rest2)),get(asn1_module), [got,get_token(hd(Rest2)),expected,'}']}}) @@ -479,16 +491,19 @@ parse_BuiltinType([{'REAL',_}|Rest]) -> {#type{def='REAL'},Rest}; parse_BuiltinType([{'RELATIVE-OID',_}|Rest]) -> {#type{def='RELATIVE-OID'},Rest}; -parse_BuiltinType([{'SEQUENCE',_},{'{',_},{'...',Line},{'}',_}|Rest]) -> - {#type{def=#'SEQUENCE'{components=[{'EXTENSIONMARK',Line,undefined}]}}, +parse_BuiltinType([{'SEQUENCE',_},{'{',_},{'}',_}|Rest]) -> + {#type{def=#'SEQUENCE'{components=[]}}, Rest}; +parse_BuiltinType([{'SEQUENCE',_},{'{',_},{'...',Line},{'}',_}|Rest]) -> + {#type{def=#'SEQUENCE'{components=[#'EXTENSIONMARK'{pos = Line}]}},Rest}; parse_BuiltinType([{'SEQUENCE',_},{'{',_},{'...',Line},{'!',_}|Rest]) -> {ExceptionIdentification,Rest2} = parse_ExceptionIdentification(Rest), case Rest2 of [{'}',_}|Rest3] -> - {#type{def=#'SEQUENCE'{components=[{'EXTENSIONMARK', - Line, - ExceptionIdentification}]}}, + {#type{def=#'SEQUENCE'{ + components=[#'EXTENSIONMARK'{ + pos = Line, + val = ExceptionIdentification}]}}, Rest3}; _ -> {ComponentTypeLists,Rest3}= @@ -537,13 +552,14 @@ parse_BuiltinType([{'SEQUENCE',_},{'OF',_}|Rest]) -> parse_BuiltinType([{'SET',_},{'{',_},{'...',Line},{'}',_}|Rest]) -> - {#type{def=#'SET'{components=[{'EXTENSIONMARK',Line,undefined}]}},Rest}; + {#type{def=#'SET'{components=[#'EXTENSIONMARK'{pos = Line}]}},Rest}; parse_BuiltinType([{'SET',_},{'{',_},{'...',Line},{'!',_}|Rest]) -> {ExceptionIdentification,Rest2} = parse_ExceptionIdentification(Rest), case Rest2 of [{'}',_}|Rest3] -> {#type{def=#'SET'{components= - [{'EXTENSIONMARK',Line,ExceptionIdentification}]}}, + [#'EXTENSIONMARK'{pos = Line, + val = ExceptionIdentification}]}}, Rest3}; _ -> throw({asn1_error,{get_line(hd(Rest2)),get(asn1_module), @@ -2323,101 +2339,197 @@ to_set(V) when is_list(V) -> to_set(V) -> ordsets:from_list([V]). +parse_AlternativeTypeLists(Tokens) -> + parse_AlternativeTypeLists(Tokens,[]). -parse_AlternativeTypeLists(Tokens,ExtensionDefault) -> - {AltTypeList,Rest1} = parse_AlternativeTypeList(Tokens), - {ExtensionAndException,Rest2} = - case Rest1 of - [{',',_},{'...',L1},{'!',_}|Rest12] -> - {_,Rest13} = parse_ExceptionIdentification(Rest12), - %% Exception info is currently thrown away - {[#'EXTENSIONMARK'{pos=L1}],Rest13}; - [{',',_},{'...',L1}|Rest12] -> - {[#'EXTENSIONMARK'{pos=L1}],Rest12}; - _ -> - {[],Rest1} - end, - {AltTypeList2,Rest5} = - case ExtensionAndException of - [] -> - {AltTypeList,Rest2}; - _ -> - {ExtensionAddition,Rest3} = - case Rest2 of - [{',',_}|Rest23] -> - parse_ExtensionAdditionAlternativeList(Rest23); - _ -> - {[],Rest2} - end, - {OptionalExtensionMarker,Rest4} = - case Rest3 of - [{',',_},{'...',L3}|Rest31] -> - {[#'EXTENSIONMARK'{pos=L3}],Rest31}; - _ -> - {[],Rest3} - end, - {AltTypeList ++ ExtensionAndException ++ - ExtensionAddition ++ OptionalExtensionMarker, Rest4} - end, - AltTypeList3 = - case [X || X=#'EXTENSIONMARK'{} <- AltTypeList2] of - [] when ExtensionDefault == 'IMPLIED' -> - AltTypeList2 ++ [#'EXTENSIONMARK'{}]; - _ -> - AltTypeList2 - end, - {AltTypeList3,Rest5}. - +parse_AlternativeTypeLists(Tokens = [{identifier,_,_}|_Rest0],Clist) -> + {CompList,Rest1} = parse_AlternativeTypeList(Tokens,[]), + parse_AlternativeTypeLists(Rest1,Clist++CompList); +parse_AlternativeTypeLists([{'...',L1},{'!',_}|Rest02],Clist0) -> + {_,Rest03} = parse_ExceptionIdentification(Rest02), + %% Exception info is currently thrown away + parse_AlternativeTypeLists2(Rest03,Clist0++[#'EXTENSIONMARK'{pos=L1}]); +parse_AlternativeTypeLists([{',',L1},{'...',_},{'!',_}|Rest02],Clist0) when Clist0 =/= []-> + {_,Rest03} = parse_ExceptionIdentification(Rest02), + %% Exception info is currently thrown away + parse_AlternativeTypeLists2(Rest03,Clist0++[#'EXTENSIONMARK'{pos=L1}]); + +parse_AlternativeTypeLists([{',',_},{'...',L1}|Rest02],Clist0) when Clist0 =/= []-> + parse_AlternativeTypeLists2(Rest02,Clist0++[#'EXTENSIONMARK'{pos=L1}]); +parse_AlternativeTypeLists([{'...',L1}|Rest02],Clist0) -> + parse_AlternativeTypeLists2(Rest02,Clist0++[#'EXTENSIONMARK'{pos=L1}]); +parse_AlternativeTypeLists(Tokens = [{'}',_L1}|_Rest02],Clist0) -> + {Clist0,Tokens}. + +parse_AlternativeTypeLists2(Tokens,Clist) -> + {ExtAdd,Rest} = parse_ExtensionAdditionAlternatives(Tokens,Clist), + {Clist2,Rest2} = parse_OptionalExtensionMarker(Rest,lists:flatten(ExtAdd)), + case Rest2 of + [{',',_}|Rest3] -> + {CompList,Rest4} = parse_AlternativeTypeList(Rest3,[]), + {Clist2 ++ CompList,Rest4}; + _ -> + {Clist2,Rest2} + end. -parse_AlternativeTypeList(Tokens) -> - parse_AlternativeTypeList(Tokens,[]). -parse_AlternativeTypeList(Tokens,Acc) -> - {NamedType,Rest} = parse_NamedType(Tokens), + +parse_AlternativeTypeList([{',',_},Id = {identifier,_,_}|Rest],Acc) when Acc =/= [] -> + {AlternativeType,Rest2} = parse_NamedType([Id|Rest]), + parse_AlternativeTypeList(Rest2,[AlternativeType|Acc]); +parse_AlternativeTypeList(Tokens = [{'}',_}|_],Acc) -> + {lists:reverse(Acc),Tokens}; +parse_AlternativeTypeList(Tokens = [{']',_},{']',_}|_],Acc) -> + {lists:reverse(Acc),Tokens}; +parse_AlternativeTypeList(Tokens = [{',',_},{'...',_}|_],Acc) -> + {lists:reverse(Acc),Tokens}; +parse_AlternativeTypeList(Tokens,[]) -> + {AlternativeType,Rest} = parse_NamedType(Tokens), + parse_AlternativeTypeList(Rest,[AlternativeType]); +parse_AlternativeTypeList(Tokens,_) -> + throw({asn1_error, + {get_line(hd(Tokens)),get(asn1_module), + [got,[get_token(hd(Tokens)),get_token(hd(tl(Tokens)))], + expected,['}',', identifier']]}}). + +parse_ExtensionAdditionAlternatives(Tokens =[{',',_}|_],Clist) -> + {ExtAddList,Rest2} = parse_ExtensionAdditionAlternativesList(Tokens,[]), + {Clist++lists:flatten(ExtAddList),Rest2}; +parse_ExtensionAdditionAlternatives(Tokens,Clist) -> + %% Empty + {Clist,Tokens}. + +parse_ExtensionAdditionAlternativesList([{',',_},Id = {identifier,_,_}|Rest],Acc) -> + {AlternativeType,Rest2} = parse_NamedType([Id|Rest]), + parse_ExtensionAdditionAlternativesList(Rest2,[AlternativeType|Acc]); +parse_ExtensionAdditionAlternativesList([{',',_},C1 = {'[',_},C2 = {'[',_}|Rest],Acc) -> + {ExtAddGroup,Rest2} = parse_ExtensionAdditionAlternativesGroup([C1,C2|Rest],[]), + parse_ExtensionAdditionAlternativesList(Rest2,[ExtAddGroup|Acc]); +parse_ExtensionAdditionAlternativesList(Tokens = [{'}',_}|_],Acc) -> + {lists:reverse(Acc),Tokens}; +parse_ExtensionAdditionAlternativesList(Tokens = [{',',_},{'...',_}|_],Acc) -> + {lists:reverse(Acc),Tokens}; +parse_ExtensionAdditionAlternativesList(Tokens,_) -> + throw({asn1_error, + {get_line(hd(Tokens)),get(asn1_module), + [got,[get_token(hd(Tokens)),get_token(hd(tl(Tokens)))], + expected,['}',', identifier']]}}). + + +parse_ExtensionAdditionAlternativesGroup([ {'[',_},{'[',_},_VsnNr = {number,_,Num},{':',_}|Rest],[]) -> + parse_ExtensionAdditionAlternativesGroup2(Rest,Num); +parse_ExtensionAdditionAlternativesGroup([ {'[',_},{'[',_}|Rest],[]) -> + parse_ExtensionAdditionAlternativesGroup2(Rest,undefined); +parse_ExtensionAdditionAlternativesGroup(Tokens,_) -> + throw({asn1_error, + {get_line(hd(Tokens)),get(asn1_module), + [got,[get_token(hd(Tokens)),get_token(hd(tl(Tokens)))], + expected,['[[']]}}). + + +parse_ExtensionAdditionAlternativesGroup2(Tokens,Num) -> + {CompTypeList,Rest} = parse_AlternativeTypeList(Tokens,[]), case Rest of - [{',',_},Id = {identifier,_,_}|Rest2] -> - parse_AlternativeTypeList([Id|Rest2],[NamedType|Acc]); + [{']',_},{']',_}|Rest2] -> + {[{'ExtensionAdditionGroup',Num}|CompTypeList] ++ + ['ExtensionAdditionGroupEnd'],Rest2}; _ -> - {lists:reverse([NamedType|Acc]),Rest} - end. - + throw({asn1_error,{get_line(hd(Rest)),get(asn1_module), + [got,get_token(hd(Rest)),expected,[']]']]}}) + end. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%% parse_AlternativeTypeLists(Tokens,ExtensionDefault) -> +%% {AltTypeList,Rest1} = parse_AlternativeTypeList(Tokens), +%% {ExtensionAndException,Rest2} = +%% case Rest1 of +%% [{',',_},{'...',L1},{'!',_}|Rest12] -> +%% {_,Rest13} = parse_ExceptionIdentification(Rest12), +%% %% Exception info is currently thrown away +%% {[#'EXTENSIONMARK'{pos=L1}],Rest13}; +%% [{',',_},{'...',L1}|Rest12] -> +%% {[#'EXTENSIONMARK'{pos=L1}],Rest12}; +%% _ -> +%% {[],Rest1} +%% end, +%% {AltTypeList2,Rest5} = +%% case ExtensionAndException of +%% [] -> +%% {AltTypeList,Rest2}; +%% _ -> +%% {ExtensionAddition,Rest3} = +%% case Rest2 of +%% [{',',_}|Rest23] -> +%% parse_ExtensionAdditionAlternativeList(Rest23); +%% _ -> +%% {[],Rest2} +%% end, +%% {OptionalExtensionMarker,Rest4} = +%% case Rest3 of +%% [{',',_},{'...',L3}|Rest31] -> +%% {[#'EXTENSIONMARK'{pos=L3}],Rest31}; +%% _ -> +%% {[],Rest3} +%% end, +%% {AltTypeList ++ ExtensionAndException ++ +%% ExtensionAddition ++ OptionalExtensionMarker, Rest4} +%% end, +%% AltTypeList3 = +%% case [X || X=#'EXTENSIONMARK'{} <- AltTypeList2] of +%% [] when ExtensionDefault == 'IMPLIED' -> +%% AltTypeList2 ++ [#'EXTENSIONMARK'{}]; +%% _ -> +%% AltTypeList2 +%% end, +%% {AltTypeList3,Rest5}. -parse_ExtensionAdditionAlternativeList(Tokens) -> - parse_ExtensionAdditionAlternativeList(Tokens,[]). +%% parse_AlternativeTypeList(Tokens) -> +%% parse_AlternativeTypeList(Tokens,[]). + +%% parse_AlternativeTypeList(Tokens,Acc) -> +%% {NamedType,Rest} = parse_NamedType(Tokens), +%% case Rest of +%% [{',',_},Id = {identifier,_,_}|Rest2] -> +%% parse_AlternativeTypeList([Id|Rest2],[NamedType|Acc]); +%% _ -> +%% {lists:reverse([NamedType|Acc]),Rest} +%% end. + -parse_ExtensionAdditionAlternativeList(Tokens,Acc) -> - {Element,Rest0} = - case Tokens of - [{identifier,_,_}|_Rest] -> - parse_NamedType(Tokens); - [{'[',_},{'[',_}|_] -> - parse_ExtensionAdditionAlternatives(Tokens) - end, - case Rest0 of - [{',',_}|Rest01] -> - parse_ExtensionAdditionAlternativeList(Rest01,[Element|Acc]); - _ -> - {lists:reverse([Element|Acc]),Rest0} - end. -parse_ExtensionAdditionAlternatives([{'[',_},{'[',_}|Rest]) -> - parse_ExtensionAdditionAlternatives(Rest,[]); -parse_ExtensionAdditionAlternatives(Tokens) -> - throw({asn1_error,{get_line(hd(Tokens)),get(asn1_module), - [got,get_token(hd(Tokens)),expected,'[[']}}). +%% parse_ExtensionAdditionAlternativeList(Tokens) -> +%% parse_ExtensionAdditionAlternativeList(Tokens,[]). + +%% parse_ExtensionAdditionAlternativeList([{'[[',_}|Rest],Acc) -> +%% parse_ExtensionAdditionAlternativeList(Rest,Acc); +%% parse_ExtensionAdditionAlternativeList(Tokens = [{identifier,_,_}|_Rest],Acc) -> +%% {Element,Rest0} = parse_NamedType(Tokens); +%% case Rest0 of +%% [{',',_}|Rest01] -> +%% parse_ExtensionAdditionAlternativeList(Rest01,[Element|Acc]); +%% _ -> +%% {lists:reverse([Element|Acc]),Rest0} +%% end. -parse_ExtensionAdditionAlternatives([Id = {identifier,_,_}|Rest],Acc) -> - {NamedType, Rest2} = parse_NamedType([Id|Rest]), - case Rest2 of - [{',',_}|Rest21] -> - parse_ExtensionAdditionAlternatives(Rest21,[NamedType|Acc]); - [{']',_},{']',_}|Rest21] -> - {lists:reverse(Acc),Rest21}; - _ -> - throw({asn1_error,{get_line(hd(Rest2)),get(asn1_module), - [got,get_token(hd(Rest2)),expected,[',',']]']]}}) - end. +%% parse_ExtensionAdditionAlternatives([{'[[',_}|Rest]) -> +%% parse_ExtensionAdditionAlternatives(Rest,[]); +%% parse_ExtensionAdditionAlternatives(Tokens) -> +%% throw({asn1_error,{get_line(hd(Tokens)),get(asn1_module), +%% [got,get_token(hd(Tokens)),expected,'[[']}}). + +%% parse_ExtensionAdditionAlternatives([Id = {identifier,_,_}|Rest],Acc) -> +%% {NamedType, Rest2} = parse_NamedType([Id|Rest]), +%% case Rest2 of +%% [{',',_}|Rest21] -> +%% parse_ExtensionAdditionAlternatives(Rest21,[NamedType|Acc]); +%% [{']]',_}|Rest21] -> +%% {lists:reverse(Acc),Rest21}; +%% _ -> +%% throw({asn1_error,{get_line(hd(Rest2)),get(asn1_module), +%% [got,get_token(hd(Rest2)),expected,[',',']]']]}}) +%% end. parse_NamedType([{identifier,L1,Idname}|Rest]) -> {Type,Rest2} = parse_Type(Rest), @@ -2428,144 +2540,123 @@ parse_NamedType(Tokens) -> parse_ComponentTypeLists(Tokens) -> -% Resulting tuple {ComponentTypeList,Rest1} is returned - case Tokens of - [{identifier,_,_}|_Rest0] -> - {Clist,Rest01} = parse_ComponentTypeList(Tokens), - case Rest01 of - [{',',_}|Rest02] -> - parse_ComponentTypeLists(Rest02,Clist); % 5 - 13 - _ -> - {Clist,Rest01} - end; - [{'COMPONENTS',_},{'OF',_}|_Rest] -> - {Clist,Rest01} = parse_ComponentTypeList(Tokens), - case Rest01 of - [{',',_}|Rest02] -> - parse_ComponentTypeLists(Rest02,Clist); - _ -> - {Clist,Rest01} - end; + parse_ComponentTypeLists(Tokens,[]). + +parse_ComponentTypeLists(Tokens = [{identifier,_,_}|_Rest0],Clist) -> + {CompList,Rest1} = parse_ComponentTypeList(Tokens,[]), + parse_ComponentTypeLists(Rest1,Clist++CompList); +parse_ComponentTypeLists(Tokens = [{'COMPONENTS',_},{'OF',_}|_Rest],Clist) -> + {CompList,Rest1} = parse_ComponentTypeList(Tokens,[]), + parse_ComponentTypeLists(Rest1,Clist++CompList); +parse_ComponentTypeLists([{'...',L1},{'!',_}|Rest02],Clist0) -> + {_,Rest03} = parse_ExceptionIdentification(Rest02), + %% Exception info is currently thrown away + parse_ComponentTypeLists2(Rest03,Clist0++[#'EXTENSIONMARK'{pos=L1}]); +parse_ComponentTypeLists([{',',L1},{'...',_},{'!',_}|Rest02],Clist0) when Clist0 =/= []-> + {_,Rest03} = parse_ExceptionIdentification(Rest02), + %% Exception info is currently thrown away + parse_ComponentTypeLists2(Rest03,Clist0++[#'EXTENSIONMARK'{pos=L1}]); + + parse_ComponentTypeLists([{',',_},{'...',L1}|Rest02],Clist0) when Clist0 =/= []-> + parse_ComponentTypeLists2(Rest02,Clist0++[#'EXTENSIONMARK'{pos=L1}]); +parse_ComponentTypeLists([{'...',L1}|Rest02],Clist0) -> + parse_ComponentTypeLists2(Rest02,Clist0++[#'EXTENSIONMARK'{pos=L1}]); +parse_ComponentTypeLists(Tokens = [{'}',_L1}|_Rest02],Clist0) -> + {Clist0,Tokens}. + +parse_ComponentTypeLists2(Tokens,Clist) -> + {ExtAdd,Rest} = parse_ExtensionAdditions(Tokens,Clist), + {Clist2,Rest2} = parse_OptionalExtensionMarker(Rest,lists:flatten(ExtAdd)), + case Rest2 of + [{',',_}|Rest3] -> + {CompList,Rest4} = parse_ComponentTypeList(Rest3,[]), + {Clist2 ++ CompList,Rest4}; _ -> - parse_ComponentTypeLists(Tokens,[]) + {Clist2,Rest2} end. -parse_ComponentTypeLists([{'...',L1},{'!',_}|Rest],Clist1) -> - {_,Rest2} = parse_ExceptionIdentification(Rest), - %% Exception info is currently thrown away - parse_ComponentTypeLists2(Rest2,Clist1++[#'EXTENSIONMARK'{pos=L1}]); -parse_ComponentTypeLists([{'...',L1}|Rest],Clist1) -> %% first Extensionmark - parse_ComponentTypeLists2(Rest,Clist1++[#'EXTENSIONMARK'{pos=L1}]); -parse_ComponentTypeLists(Tokens,Clist1) -> - {Clist1,Tokens}. - - -parse_ComponentTypeLists2(Tokens,Clist1) -> - {ExtensionAddition,Rest2} = - case Tokens of - [{',',_}|Rest1] -> - parse_ExtensionAdditionList(Rest1); - _ -> - {[],Tokens} - end, - {OptionalExtensionMarker,Rest3} = - case Rest2 of - [{',',_},{'...',L2}|Rest21] -> - {[#'EXTENSIONMARK'{pos=L2}],Rest21}; - _ -> - {[],Rest2} - end, - {RootComponentTypeList,Rest4} = - case Rest3 of - [{',',_}|Rest31] -> - parse_ComponentTypeList(Rest31); - _ -> - {[],Rest3} - end, - {Clist1 ++ ExtensionAddition ++ OptionalExtensionMarker ++ RootComponentTypeList, Rest4}. - +parse_OptionalExtensionMarker([{',',_},{'...',L1}|Rest],Clist)-> + {Clist++[#'EXTENSIONMARK'{pos=L1}],Rest}; +parse_OptionalExtensionMarker(Tokens,Clist) -> + {Clist,Tokens}. -parse_ComponentTypeList(Tokens) -> - parse_ComponentTypeList(Tokens,[]). -parse_ComponentTypeList(Tokens,Acc) -> +parse_ComponentTypeList([{',',_},Id = {identifier,_,_}|Rest],Acc) when Acc =/= [] -> + {ComponentType,Rest2} = parse_ComponentType([Id|Rest]), + parse_ComponentTypeList(Rest2,[ComponentType|Acc]); +parse_ComponentTypeList([{',',_},C1={'COMPONENTS',_},C2={'OF',_}|Rest],Acc) when Acc =/= [] -> + {ComponentType,Rest2} = parse_ComponentType([C1,C2|Rest]), + parse_ComponentTypeList(Rest2,[ComponentType|Acc]); +parse_ComponentTypeList(Tokens = [{'}',_}|_],Acc) -> + {lists:reverse(Acc),Tokens}; +parse_ComponentTypeList(Tokens = [{']',_},{']',_}|_],Acc) -> + {lists:reverse(Acc),Tokens}; +parse_ComponentTypeList(Tokens = [{',',_},{'...',_}|_],Acc) -> + {lists:reverse(Acc),Tokens}; +parse_ComponentTypeList(Tokens,[]) -> {ComponentType,Rest} = parse_ComponentType(Tokens), + parse_ComponentTypeList(Rest,[ComponentType]); +parse_ComponentTypeList(Tokens,_) -> + throw({asn1_error, + {get_line(hd(Tokens)),get(asn1_module), + [got,[get_token(hd(Tokens)),get_token(hd(tl(Tokens)))], + expected,['}',', identifier']]}}). + +parse_ExtensionAdditions(Tokens=[{',',_}|_],Clist) -> + {ExtAddList,Rest2} = parse_ExtensionAdditionList(Tokens,[]), + {Clist++ExtAddList,Rest2}; +parse_ExtensionAdditions(Tokens,Clist) -> + %% Empty + {Clist,Tokens}. + +parse_ExtensionAdditionList([{',',_},Id = {identifier,_,_}|Rest],Acc) -> + {ComponentType,Rest2} = parse_ComponentType([Id|Rest]), + parse_ExtensionAdditionList(Rest2,[ComponentType|Acc]); +parse_ExtensionAdditionList([{',',_},C1={'COMPONENTS',_},C2={'OF',_}|Rest],Acc) -> + {ComponentType,Rest2} = parse_ComponentType([C1,C2|Rest]), + parse_ExtensionAdditionList(Rest2,[ComponentType|Acc]); +parse_ExtensionAdditionList([{',',_},C1 = {'[',_},C2 = {'[',_}|Rest],Acc) -> + {ExtAddGroup,Rest2} = parse_ExtensionAdditionGroup([C1,C2|Rest],[]), + parse_ExtensionAdditionList(Rest2,[ExtAddGroup|Acc]); +parse_ExtensionAdditionList(Tokens = [{'}',_}|_],Acc) -> + {lists:reverse(Acc),Tokens}; +parse_ExtensionAdditionList(Tokens = [{',',_},{'...',_}|_],Acc) -> + {lists:reverse(Acc),Tokens}; +parse_ExtensionAdditionList(Tokens,_) -> + throw({asn1_error, + {get_line(hd(Tokens)),get(asn1_module), + [got,[get_token(hd(Tokens)),get_token(hd(tl(Tokens)))], + expected,['}',', identifier']]}}). + + +parse_ExtensionAdditionGroup([ {'[',_},{'[',_},_VsnNr = {number,_,Num},{':',_}|Rest],[]) -> + parse_ExtensionAdditionGroup2(Rest,Num); +parse_ExtensionAdditionGroup([ {'[',_},{'[',_}|Rest],[]) -> + parse_ExtensionAdditionGroup2(Rest,undefined); +parse_ExtensionAdditionGroup(Tokens,_) -> + throw({asn1_error, + {get_line(hd(Tokens)),get(asn1_module), + [got,[get_token(hd(Tokens)),get_token(hd(tl(Tokens)))], + expected,['[[']]}}). + + +parse_ExtensionAdditionGroup2(Tokens,Num) -> + {CompTypeList,Rest} = parse_ComponentTypeList(Tokens,[]), case Rest of - [{',',_},Id = {identifier,_,_}|Rest2] -> - parse_ComponentTypeList([Id|Rest2],[ComponentType|Acc]); - [{',',_},C1={'COMPONENTS',_},C2={'OF',_}|Rest2] -> - parse_ComponentTypeList([C1,C2|Rest2],[ComponentType|Acc]); -% _ -> -% {lists:reverse([ComponentType|Acc]),Rest} - [{'}',_}|_] -> - {lists:reverse([ComponentType|Acc]),Rest}; -% [{',',_},{'...',_},{'}',_}|_] -> -% {lists:reverse([ComponentType|Acc]),Rest}; - [{',',_},{'...',_}|_] ->%% here comes the dubble ellipse - {lists:reverse([ComponentType|Acc]),Rest}; + [{']',_},{']',_}|Rest2] -> + {[{'ExtensionAdditionGroup',Num}|CompTypeList] ++ + ['ExtensionAdditionGroupEnd'],Rest2}; _ -> - throw({asn1_error, - {get_line(hd(Tokens)),get(asn1_module), - [got,[get_token(hd(Rest)),get_token(hd(tl(Rest)))], - expected,['}',', identifier']]}}) - end. - - -parse_ExtensionAdditionList(Tokens) -> - parse_ExtensionAdditionList(Tokens,[]). - -parse_ExtensionAdditionList(Tokens,Acc) -> - {Element,Rest0} = - case Tokens of - [{identifier,_,_}|_Rest] -> - parse_ComponentType(Tokens); - [{'[',_},{'[',_}|_] -> - parse_ExtensionAdditions(Tokens); - [{'...',L1}|_Rest] -> - {#'EXTENSIONMARK'{pos=L1},Tokens}; - _ -> - throw({asn1_error,{get_line(hd(Tokens)),get(asn1_module), - [got,get_token(hd(Tokens)),expected, - [identifier,'[[']]}}) - end, - case Rest0 of - [{',',_}|Rest01] -> - parse_ExtensionAdditionList(Rest01,[Element|Acc]); - [{'...',_}|Rest01] -> - {lists:reverse([Element|Acc]),Rest01}; - _ -> - {lists:reverse([Element|Acc]),Rest0} + throw({asn1_error,{get_line(hd(Rest)),get(asn1_module), + [got,get_token(hd(Rest)),expected,[']]']]}}) end. -parse_ExtensionAdditions([{'[',_},{'[',_}|Rest]) -> - parse_ExtensionAdditions(Rest,[]); -parse_ExtensionAdditions(Tokens) -> - throw({asn1_error,{get_line(hd(Tokens)),get(asn1_module), - [got,get_token(hd(Tokens)),expected,'[[']}}). - -parse_ExtensionAdditions([_VsnNr = {number,_,_},{':',_}|Rest],Acc) -> - %% ignor version number for now - parse_ExtensionAdditions(Rest,Acc); -parse_ExtensionAdditions([Id = {identifier,_,_}|Rest],Acc) -> - {ComponentType, Rest2} = parse_ComponentType([Id|Rest]), - case Rest2 of - [{',',_}|Rest21] -> - parse_ExtensionAdditions(Rest21,[ComponentType|Acc]); - [{']',_},{']',_}|Rest21] -> - {lists:reverse(Acc),Rest21}; - _ -> - throw({asn1_error,{get_line(hd(Rest2)),get(asn1_module), - [got,get_token(hd(Rest2)),expected,[',',']]']]}}) - end; -parse_ExtensionAdditions(Tokens,_) -> - throw({asn1_error,{get_line(hd(Tokens)),get(asn1_module), - [got,get_token(hd(Tokens)),expected,identifier]}}). parse_ComponentType([{'COMPONENTS',_},{'OF',_}|Rest]) -> {Type,Rest2} = parse_Type(Rest), {{'COMPONENTS OF',Type},Rest2}; parse_ComponentType(Tokens) -> - {NamedType,Rest} = parse_NamedType(Tokens), + Result = {NamedType,Rest} = parse_NamedType(Tokens), case Rest of [{'OPTIONAL',_}|Rest2] -> {NamedType#'ComponentType'{prop='OPTIONAL'},Rest2}; @@ -2573,7 +2664,7 @@ parse_ComponentType(Tokens) -> {Value,Rest21} = parse_Value(Rest2), {NamedType#'ComponentType'{prop={'DEFAULT',Value}},Rest21}; _ -> - {NamedType,Rest} + Result end. diff --git a/lib/asn1/src/asn1ct_tok.erl b/lib/asn1/src/asn1ct_tok.erl index f0ce31bdb2..85199c65ec 100644 --- a/lib/asn1/src/asn1ct_tok.erl +++ b/lib/asn1/src/asn1ct_tok.erl @@ -21,7 +21,7 @@ %% Tokenize ASN.1 code (input to parser generated with yecc) --export([get_name/2,tokenise/2, file/1]). +-export([get_name/2,tokenise/4, file/1]). file(File) -> @@ -29,12 +29,9 @@ file(File) -> {error, Reason} -> {error,{File,file:format_error(Reason)}}; {ok,Stream} -> - process0(Stream) + process(Stream,0,[]) end. -process0(Stream) -> - process(Stream,0,[]). - process(Stream,Lno,R) -> process(io:get_line(Stream, ''), Stream,Lno+1,R). @@ -45,131 +42,128 @@ process(eof, Stream,Lno,R) -> process(L, Stream,Lno,R) when is_list(L) -> %%io:format('read:~s',[L]), - case catch tokenise(L,Lno) of + case catch tokenise(Stream,L,Lno,[]) of {'ERR',Reason} -> io:format("Tokeniser error on line: ~w ~w~n",[Lno,Reason]), exit(0); - {multiline_comment,NestingLevel} -> - {RestL,Lno2} = process_skip_multiline_comment(Stream,Lno,NestingLevel), - process(RestL,Stream,Lno2,R); - T -> + {NewLno,T} -> %%io:format('toks:~w~n',[T]), - process(Stream,Lno,[T|R]) + process(Stream,NewLno,[T|R]) end. -process_skip_multiline_comment(Stream,Lno,NestingLevel) -> - process_skip_multiline_comment(io:get_line(Stream, ''), - Stream, Lno + 1, NestingLevel). -process_skip_multiline_comment(eof,_Stream,Lno,_NestingLevel) -> - io:format("Tokeniser error on line: ~w, premature end of multiline comment~n",[Lno]), - exit(0); -process_skip_multiline_comment(Line,Stream,Lno,NestingLevel) -> - case catch skip_multiline_comment(Line,NestingLevel) of - {multiline_comment,NestingLevel2} -> - process_skip_multiline_comment(Stream,Lno,NestingLevel2); - T -> - {T,Lno} - end. - -tokenise([H|T],Lno) when $a =< H , H =< $z -> +tokenise(Stream,[H|T],Lno,R) when $a =< H , H =< $z -> {X, T1} = get_name(T, [H]), - [{identifier,Lno, list_to_atom(X)}|tokenise(T1,Lno)]; + tokenise(Stream,T1,Lno,[{identifier,Lno, list_to_atom(X)}|R]); -tokenise([$&,H|T],Lno) when $A =< H , H =< $Z -> +tokenise(Stream,[$&,H|T],Lno,R) when $A =< H , H =< $Z -> {Y, T1} = get_name(T, [H]), X = list_to_atom(Y), - [{typefieldreference, Lno, X} | tokenise(T1, Lno)]; + tokenise(Stream,T1,Lno,[{typefieldreference, Lno, X} | R]); -tokenise([$&,H|T],Lno) when $a =< H , H =< $z -> +tokenise(Stream,[$&,H|T],Lno,R) when $a =< H , H =< $z -> {Y, T1} = get_name(T, [H]), X = list_to_atom(Y), - [{valuefieldreference, Lno, X} | tokenise(T1, Lno)]; + tokenise(Stream,T1,Lno,[{valuefieldreference, Lno, X} | R]); -tokenise([H|T],Lno) when $A =< H , H =< $Z -> +tokenise(Stream,[H|T],Lno,R) when $A =< H , H =< $Z -> {Y, T1} = get_name(T, [H]), X = list_to_atom(Y), case reserved_word(X) of true -> - [{X,Lno}|tokenise(T1,Lno)]; + tokenise(Stream,T1,Lno,[{X,Lno}|R]); false -> - [{typereference,Lno,X}|tokenise(T1,Lno)]; + tokenise(Stream,T1,Lno,[{typereference,Lno,X}|R]); rstrtype -> - [{restrictedcharacterstringtype,Lno,X}|tokenise(T1,Lno)] + tokenise(Stream,T1,Lno,[{restrictedcharacterstringtype,Lno,X}|R]) end; -tokenise([$-,H|T],Lno) when $0 =< H , H =< $9 -> +tokenise(Stream,[$-,H|T],Lno,R) when $0 =< H , H =< $9 -> {X, T1} = get_number(T, [H]), - [{number,Lno,-1 * list_to_integer(X)}|tokenise(T1,Lno)]; + tokenise(Stream,T1,Lno,[{number,Lno,-1 * list_to_integer(X)}|R]); -tokenise([H|T],Lno) when $0 =< H , H =< $9 -> +tokenise(Stream,[H|T],Lno,R) when $0 =< H , H =< $9 -> {X, T1} = get_number(T, [H]), - [{number,Lno,list_to_integer(X)}|tokenise(T1,Lno)]; + tokenise(Stream,T1,Lno,[{number,Lno,list_to_integer(X)}|R]); -tokenise([$-,$-|T],Lno) -> - tokenise(skip_comment(T),Lno); +tokenise(Stream,[$-,$-|T],Lno,R) -> + tokenise(Stream,skip_comment(T),Lno,R); -tokenise([$/,$*|T],Lno) -> - tokenise(skip_multiline_comment(T,0),Lno); +tokenise(Stream,[$/,$*|T],Lno,R) -> + {NewLno,T1} = skip_multiline_comment(Stream,T,Lno,0), + tokenise(Stream,T1,NewLno,R); -tokenise([$:,$:,$=|T],Lno) -> - [{'::=',Lno}|tokenise(T,Lno)]; +tokenise(Stream,[$:,$:,$=|T],Lno,R) -> + tokenise(Stream,T,Lno,[{'::=',Lno}|R]); -tokenise([$'|T],Lno) -> +tokenise(Stream,[$'|T],Lno,R) -> case catch collect_quoted(T,Lno,[]) of {'ERR',_} -> throw({'ERR','bad_quote'}); {Thing, T1} -> - [Thing|tokenise(T1,Lno)] + tokenise(Stream,T1,Lno,[Thing|R]) end; -tokenise([$"|T],Lno) -> - collect_string(T,Lno); +tokenise(Stream,[$"|T],Lno,R) -> + {Str,T1} = collect_string(T,Lno), + tokenise(Stream,T1,Lno,[Str|R]); + +tokenise(Stream,[${|T],Lno,R) -> + tokenise(Stream,T,Lno,[{'{',Lno}|R]); + +tokenise(Stream,[$}|T],Lno,R) -> + tokenise(Stream,T,Lno,[{'}',Lno}|R]); -tokenise([${|T],Lno) -> - [{'{',Lno}|tokenise(T,Lno)]; +%% tokenise(Stream,[$],$]|T],Lno,R) -> +%% tokenise(Stream,T,Lno,[{']]',Lno}|R]); -tokenise([$}|T],Lno) -> - [{'}',Lno}|tokenise(T,Lno)]; +%% Even though x.680 specify '[[' and ']]' as lexical items +%% it does not work to have them as such since the single [ and ] can +%% be used beside each other in the SYNTAX OF in x.681 +%% the solution chosen here , i.e. to have them as separate lexical items +%% will not detect the cases where there is white space between them +%% which would be an error in the use in ExtensionAdditionGroups -tokenise([$]|T],Lno) -> - [{']',Lno}|tokenise(T,Lno)]; +%% tokenise(Stream,[$[,$[|T],Lno,R) -> +%% tokenise(Stream,T,Lno,[{'[[',Lno}|R]); -tokenise([$[|T],Lno) -> - [{'[',Lno}|tokenise(T,Lno)]; +tokenise(Stream,[$]|T],Lno,R) -> + tokenise(Stream,T,Lno,[{']',Lno}|R]); -tokenise([$,|T],Lno) -> - [{',',Lno}|tokenise(T,Lno)]; +tokenise(Stream,[$[|T],Lno,R) -> + tokenise(Stream,T,Lno,[{'[',Lno}|R]); -tokenise([$(|T],Lno) -> - [{'(',Lno}|tokenise(T,Lno)]; -tokenise([$)|T],Lno) -> - [{')',Lno}|tokenise(T,Lno)]; +tokenise(Stream,[$,|T],Lno,R) -> + tokenise(Stream,T,Lno,[{',',Lno}|R]); -tokenise([$.,$.,$.|T],Lno) -> - [{'...',Lno}|tokenise(T,Lno)]; +tokenise(Stream,[$(|T],Lno,R) -> + tokenise(Stream,T,Lno,[{'(',Lno}|R]); +tokenise(Stream,[$)|T],Lno,R) -> + tokenise(Stream,T,Lno,[{')',Lno}|R]); -tokenise([$.,$.|T],Lno) -> - [{'..',Lno}|tokenise(T,Lno)]; +tokenise(Stream,[$.,$.,$.|T],Lno,R) -> + tokenise(Stream,T,Lno,[{'...',Lno}|R]); -tokenise([$.|T],Lno) -> - [{'.',Lno}|tokenise(T,Lno)]; -tokenise([$^|T],Lno) -> - [{'^',Lno}|tokenise(T,Lno)]; -tokenise([$!|T],Lno) -> - [{'!',Lno}|tokenise(T,Lno)]; -tokenise([$||T],Lno) -> - [{'|',Lno}|tokenise(T,Lno)]; +tokenise(Stream,[$.,$.|T],Lno,R) -> + tokenise(Stream,T,Lno,[{'..',Lno}|R]); +tokenise(Stream,[$.|T],Lno,R) -> + tokenise(Stream,T,Lno,[{'.',Lno}|R]); +tokenise(Stream,[$^|T],Lno,R) -> + tokenise(Stream,T,Lno,[{'^',Lno}|R]); +tokenise(Stream,[$!|T],Lno,R) -> + tokenise(Stream,T,Lno,[{'!',Lno}|R]); +tokenise(Stream,[$||T],Lno,R) -> + tokenise(Stream,T,Lno,[{'|',Lno}|R]); -tokenise([H|T],Lno) -> +tokenise(Stream,[H|T],Lno,R) -> case white_space(H) of true -> - tokenise(T,Lno); + tokenise(Stream,T,Lno,R); false -> - [{list_to_atom([H]),Lno}|tokenise(T,Lno)] + tokenise(Stream,T,Lno,[{list_to_atom([H]),Lno}|R]) end; -tokenise([],_) -> - []. +tokenise(_Stream,[],Lno,R) -> + {Lno,lists:reverse(R)}. collect_string(L,Lno) -> @@ -181,7 +175,7 @@ collect_string([],_,_) -> collect_string([H|T],Lno,Str) -> case H of $" -> - [{cstring,1,lists:reverse(Str)}|tokenise(T,Lno)]; + {{cstring,1,lists:reverse(Str)},T}; Ch -> collect_string(T,Lno,[Ch|Str]) end. @@ -252,17 +246,23 @@ skip_comment([_|T]) -> skip_comment(T). -skip_multiline_comment([],L) -> - throw({multiline_comment,L}); -skip_multiline_comment([$*,$/|T],0) -> - T; -skip_multiline_comment([$*,$/|T],Level) -> - skip_multiline_comment(T,Level - 1); -skip_multiline_comment([$/,$*|T],Level) -> - skip_multiline_comment(T,Level + 1); -skip_multiline_comment([_|T],Level) -> - skip_multiline_comment(T,Level). - +skip_multiline_comment(Stream,[],Lno,Level) -> + case io:get_line(Stream,'') of + eof -> + io:format("Tokeniser error on line: ~w~n" + "premature end of multiline comment~n",[Lno]), + exit(0); + Line -> + skip_multiline_comment(Stream,Line,Lno+1,Level) + end; +skip_multiline_comment(_Stream,[$*,$/|T],Lno,0) -> + {Lno,T}; +skip_multiline_comment(Stream,[$*,$/|T],Lno,Level) -> + skip_multiline_comment(Stream,T,Lno,Level - 1); +skip_multiline_comment(Stream,[$/,$*|T],Lno,Level) -> + skip_multiline_comment(Stream,T,Lno,Level + 1); +skip_multiline_comment(Stream,[_|T],Lno,Level) -> + skip_multiline_comment(Stream,T,Lno,Level). collect_quoted([$',$B|T],Lno, L) -> case check_bin(L) of diff --git a/lib/asn1/test/Makefile b/lib/asn1/test/Makefile index 5014eb902b..e8f65ec70b 100644 --- a/lib/asn1/test/Makefile +++ b/lib/asn1/test/Makefile @@ -189,27 +189,16 @@ release_spec: opt release_tests_spec: opt $(INSTALL_DIR) $(RELSYSDIR) - $(INSTALL_DATA) asn1.spec $(EMAKEFILE) $(ERL_FILES) $(HRL_FILES) $(RELSYSDIR) - chmod -f -R u+w $(RELSYSDIR) - @tar cf - *_SUITE_data | (cd $(RELSYSDIR); tar xf -) + $(INSTALL_DIR) $(RELSYSDIR)/asn1_SUITE_data $(INSTALL_DIR) $(RELSYSDIR)/asn1_bin_SUITE_data - @(cd asn1_SUITE_data; tar cf - *) | (cd $(RELSYSDIR)/asn1_bin_SUITE_data; tar xf -) $(INSTALL_DIR) $(RELSYSDIR)/asn1_bin_v2_SUITE_data - @(cd asn1_SUITE_data; tar cf - *) | (cd $(RELSYSDIR)/asn1_bin_v2_SUITE_data; tar xf -) - + $(INSTALL_DATA) $(ERL_FILES) $(HRL_FILES) $(RELSYSDIR) + $(INSTALL_DATA) asn1.spec $(INSTALL_PROGS) $(RELSYSDIR) + chmod -f -R u+w $(RELSYSDIR) + cd asn1_SUITE_data; tar cfh $(RELSYSDIR)/asn1_SUITE_data.tar * + cd $(RELSYSDIR)/asn1_SUITE_data; tar xf $(RELSYSDIR)/asn1_SUITE_data.tar + cd $(RELSYSDIR)/asn1_bin_SUITE_data; tar xf $(RELSYSDIR)/asn1_SUITE_data.tar + cd $(RELSYSDIR)/asn1_bin_v2_SUITE_data; tar xf $(RELSYSDIR)/asn1_SUITE_data.tar + rm $(RELSYSDIR)/asn1_SUITE_data.tar release_docs_spec: - - - - - - - - - - - - - - diff --git a/lib/asn1/test/asn1_SUITE.erl.src b/lib/asn1/test/asn1_SUITE.erl.src index ca73d259af..f0228546a5 100644 --- a/lib/asn1/test/asn1_SUITE.erl.src +++ b/lib/asn1/test/asn1_SUITE.erl.src @@ -74,6 +74,7 @@ all(suite) -> [compile,parse,default_per,default_ber,default_per_opt,per, testSeqTypeRefPrim, testSeqTypeRefSeq, testSeqTypeRefSet, testSeqOf, testSeqOfIndefinite, testSeqOfCho, testSeqOfExternal, testSetDefault, testSetExtension, + testExtensionAdditionGroup, testSetExternal, testSeqOfTag, testSetOptional, testSetPrim, testSetTag, testSetTypeRefCho, testSetTypeRefPrim, testSetTypeRefSeq, testSetTypeRefSet, testSetOf, testSetOfCho, @@ -95,7 +96,7 @@ all(suite) -> [compile,parse,default_per,default_ber,default_per_opt,per, testSSLspecs, testNortel,test_undecoded_rest, test_inline, testTcapsystem, testNBAPsystem, test_compile_options,testDoubleEllipses, test_modified_x420, - testX420, test_x691,ticket_6143 + testX420, test_x691,ticket_6143, testExtensionAdditionGroup ] ++ common() ++ particular(). %all(suite) -> [test_inline,testNBAPsystem,test_compile_options,ticket_6143]. @@ -1036,7 +1037,6 @@ testSetExtension_cases(Rules) -> ?line testSetExtension:main(Rules). - testSetExternal(suite) -> []; testSetExternal(Config) -> ?line true = code:add_patha(?config(priv_dir,Config)), @@ -2292,6 +2292,21 @@ ticket_6143(suite) -> []; ticket_6143(Config) -> ?line ok = test_compile_options:ticket_6143(Config). +testExtensionAdditionGroup(suite) -> []; +testExtensionAdditionGroup(Config) -> + ?line DataDir = ?config(data_dir,Config), + ?line PrivDir = ?config(priv_dir,Config), + ?line Path = code:get_path(), + ?line code:add_patha(PrivDir), + DoIt = fun(Erule) -> + ?line ok = asn1ct:compile(filename:join(DataDir,"Extension-Addition-Group"),[Erule,{outdir,PrivDir}]), + ?line {ok,_M} = compile:file(filename:join(DataDir,"extensionAdditionGroup"),[{i,PrivDir},{outdir,PrivDir},debug_info]), + ?line ok = extensionAdditionGroup:run(Erule) + end, + ?line [DoIt(Rule)|| Rule <- [per_bin,uper_bin,ber_bin]], + ?line code:set_path(Path). + + % parse_modules() -> % ["ImportsFrom"]. diff --git a/lib/asn1/test/asn1_SUITE_data/AA2.asn1db b/lib/asn1/test/asn1_SUITE_data/AA2.asn1db Binary files differindex 3bf2c1b89d..163dbb032d 100644 --- a/lib/asn1/test/asn1_SUITE_data/AA2.asn1db +++ b/lib/asn1/test/asn1_SUITE_data/AA2.asn1db diff --git a/lib/asn1/test/asn1_SUITE_data/Extension-Addition-Group.asn b/lib/asn1/test/asn1_SUITE_data/Extension-Addition-Group.asn new file mode 100644 index 0000000000..b985c970ac --- /dev/null +++ b/lib/asn1/test/asn1_SUITE_data/Extension-Addition-Group.asn @@ -0,0 +1,66 @@ +-- +-- %CopyrightBegin% +-- +-- Copyright Ericsson AB 2001-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% + +Extension-Addition-Group DEFINITIONS AUTOMATIC TAGS ::= + +BEGIN + +-- fetched from ITU-T Rec. X691 (07/2002) + +Ax ::= SEQUENCE { + a INTEGER (250..253), + b BOOLEAN, + c CHOICE { + d INTEGER, + ..., + + [[ + e BOOLEAN, + f IA5String + ]], + ... + }, + ..., + [[ + g NumericString (SIZE(3)), + h BOOLEAN OPTIONAL + ]] +, + ..., + i BMPString OPTIONAL, + j PrintableString OPTIONAL + +} + +-- valAx Ax ::= { a 253, b TRUE, c e: TRUE, g "123", h TRUE } +Ax2 ::= SEQUENCE { + a INTEGER (250..253), + b BOOLEAN, + ..., + ug NumericString + +} +END + +-- The value { a 253, b TRUE, c e: TRUE, g "123", h TRUE } +-- is encoded in PER as +-- Hexadecimal view +-- 9E000180 010291A4 + +-- is encoded in Unaligned PER as +-- 9E000600 040A4690 diff --git a/lib/asn1/test/asn1_SUITE_data/extensionAdditionGroup.erl b/lib/asn1/test/asn1_SUITE_data/extensionAdditionGroup.erl new file mode 100644 index 0000000000..79e200f561 --- /dev/null +++ b/lib/asn1/test/asn1_SUITE_data/extensionAdditionGroup.erl @@ -0,0 +1,43 @@ +%%%------------------------------------------------------------------- +%%% File : extensionAdditionGroup.erl +%%% Author : Kenneth Lundin +%%% Description : +%%% +%%% Created : 18 May 2010 by kenneth +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2001-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(extensionAdditionGroup). +-include("Extension-Addition-Group.hrl"). + + +-compile(export_all). + +run(Erule) -> + Val = #'Ax'{a=253, b = true, c= {e,true}, g="123", h = true}, + io:format("~p:~p~n",[Erule,Val]), + {ok,List}= asn1rt:encode('Extension-Addition-Group','Ax',Val), + Enc = iolist_to_binary(List), + io:format("~p~n",[Enc]), + {ok,Val2} = asn1rt:decode('Extension-Addition-Group','Ax',Enc), + io:format("~p~n",[Val2]), + case Val2 of + Val -> ok; + _ -> exit({expected,Val, got, Val2}) + end. diff --git a/lib/asn1/test/test_compile_options.erl b/lib/asn1/test/test_compile_options.erl index 83f38c5e6d..5e027cdedb 100644 --- a/lib/asn1/test/test_compile_options.erl +++ b/lib/asn1/test/test_compile_options.erl @@ -132,7 +132,7 @@ verbose(Config) when is_list(Config) -> ?line ok = asn1ct:compile(Asn1File, [{i,DataDir},{outdir,OutDir},noobj,verbose]), ?line test_server:capture_stop(), ?line [Line0|_] = test_server:capture_get(), - ?line lists:prefix("Erlang ASN.1 version", Line0), + ?line true = lists:prefix("Erlang ASN.1 version", Line0), %% Test non-verbose compile ?line test_server:capture_start(), diff --git a/lib/asn1/vsn.mk b/lib/asn1/vsn.mk index b7e91e42a0..c0393f84fe 100644 --- a/lib/asn1/vsn.mk +++ b/lib/asn1/vsn.mk @@ -1,323 +1,2 @@ #next version number to use is 1.6.15 | 1.7 | 2.0 ASN1_VSN = 1.6.14 - -TICKETS = OTP-8565 \ - OTP-8516 - -TICKETS_1.6.14 = \ - OTP-8565 \ - OTP-8516 - -TICKETS_1.6.13 = \ - OTP-8463 - -TICKETS_1.6.12 = \ - OTP-8256 - -TICKETS_1.6.11 = \ - OTP-8136 \ - OTP-8047 \ - OTP-8046 \ - OTP-8043 \ - OTP-7972 - -TICKETS_1.6.10 = \ - OTP-7954 \ - OTP-7953 - -TICKETS_1.6.10 = \ - OTP-7954 \ - OTP-7953 - -TICKETS_1.6.9 = \ - OTP-7909 \ - OTP-7904 - -TICKETS_1.6.8.1 = \ - OTP-7900 \ - OTP-7910 - -TICKETS_1.6.8 = \ - OTP-7876 - -TICKETS_1.6.7 = \ - OTP-7801 \ - OTP-7806 - -TICKETS_1.6.6 = \ - OTP-7759 \ - OTP-7763 - -TICKETS_1.6.5 = \ - OTP-7734 - -TICKETS_1.6.4 = \ - OTP-7708 - -TICKETS_1.6.3 = \ - OTP-7681 \ - OTP-7678 - -TICKETS_1.6.2 = \ - OTP-7608 - -TICKETS_1.6.1 = \ - OTP-7602 \ - OTP-7533 \ - OTP-7476 \ - OTP-7334 \ - OTP-7332 \ - OTP-7322 \ - OTP-7306 \ - OTP-7299 \ - OTP-7295 \ - OTP-7204 \ - OTP-7174 \ - OTP-7166 - -TICKETS_1.6 = \ - OTP-7407 \ - OTP-7403 \ - OTP-7400 \ - OTP-7375 \ - OTP-7374 \ - OTP-7335 - -TICKETS_1.5.2 = \ - OTP-7263 \ - OTP-7264 \ - OTP-7268 \ - OTP-7269 \ - OTP-7273 - -TICKETS_1.5.1 = \ - OTP-7149 \ - OTP-7151 \ - OTP-7154 \ - OTP-7155 \ - OTP-7169 \ - OTP-7171 \ - OTP-7193 \ - OTP-7199 - -TICKETS_1.5 = \ - OTP-6835 \ - OTP-6882 - -TICKETS_1.4.7 = \ - OTP-6828 - -TICKETS_1.4.6 = \ - OTP-5067 \ - OTP-6763 \ - OTP-6769 \ - OTP-6770 \ - OTP-6786 - -TICKETS_1.4.5 = \ - OTP-6493 \ - OTP-6601 \ - OTP-6695 \ - OTP-6698 \ - OTP-6702 \ - OTP-6707 \ - OTP-6717 - -TICKETS_1.4.4.14 = \ - OTP-6462 \ - OTP-6506 - -TICKETS_1.4.4.13 = \ - OTP-6405 - -TICKETS_1.4.4.12 = \ - OTP-6314 - -TICKETS_1.4.4.11 = \ - OTP-6143 - -TICKETS_1.4.4.10 = \ - OTP-6111 \ - OTP-5932 - -TICKETS_1.4.4.9 = \ - OTP-5783 \ - OTP-5788 \ - OTP-5812 \ - OTP-5831 \ - OPT-5832 - -TICKETS_1.4.4.8 = \ - OTP-5687 \ - OTP-5688 \ - OTP-5689 \ - OTP-5701 \ - OTP-5710 - -TICKETS_1.4.4.7 = \ - OTP-5477 \ - OTP-5509 \ - OTP-5511 \ - OTP-5602 \ - OTP-5616 - -TICKETS_1.4.4.6 = \ - OTP-5457 \ - OTP-5466 - -TICKETS_1.4.4.5 = \ - OTP-5302 \ - OTP-5378 - -TICKETS_1.4.4.4 = \ - OTP-5240 \ - OTP-5243 - -TICKETS_1.4.4.3 = \ - OTP-5103 \ - OTP-5104 - -TICKETS_1.4.4.2 = \ - OTP-5022 - -TICKETS_1.4.4.1 = \ - OTP-4970 - -TICKETS_1.4.4 = \ - OTP-4893 \ - OTP-4894 \ - OTP-4895 \ - OTP-4917 \ - OTP-4918 \ - OTP-4919 \ - OTP-4944 \ - OTP-4953 \ - OTP-4955 \ - OTP-4957 \ - OTP-4965 - -TICKETS_1.4.3.1 = \ - OTP-4866 \ - OTP-4869 \ - OTP-4872 - -TICKETS_1.4.3 = \ - OTP-4832 \ - OTP-4833 \ - OTP-4835 \ - OTP-4856 - -TICKETS_1.4.2.1 = \ - OTP-4773 \ - OTP-4791 \ - OTP-4792 \ - OTP-4797 \ - OTP-4798 \ - OTP-4799 \ - OTP-4809 - -# OTP R9C -TICKETS_1.4.2 = \ - OTP-4693 \ - OTP-4744 - -TICKETS_1.4.1.1 = \ - OTP-4663 \ - OTP-4665 \ - OTP-4666 - -TICKETS_1.4.1 = \ - OTP-4559 \ - OTP-4560 \ - OTP-4590 \ - OTP-4591 \ - OTP-4592 \ - OTP-4631 \ - OTP-4633 - -TICKETS_1.4 = \ - OTP-3304 - -TICKETS_1.3.3.1 = \ - OTP-4353 \ - OTP-4354 \ - OTP-4390 \ - OTP-4395 - -TICKETS_1.3.3 = \ - OTP-4381 \ - OTP-4358 \ - OTP-4355 \ - OTP-4275 \ - OTP-4248 \ - OTP-4247 \ - OTP-4242 \ - OTP-4235 \ - OTP-4234 \ - OTP-4232 \ - OTP-4200 \ - OTP-4161 \ - OTP-4129 - -TICKETS_1.3.2 = \ - OTP-4094 \ - OTP-4103 \ - OTP-3980 \ - OTP-4073 - -TICKETS_1.3.1.1 = \ - OTP-4037 \ - OTP-4057 \ - OTP-4058 - -TICKETS_1.3.1 = \ - OTP-4025 \ - OTP-4026 - -TICKETS_1.3 = \ - OTP-3463 \ - OTP-3659 \ - OTP-3978 \ - OTP-3979 \ - OTP-3981 \ - OTP-3982 \ - OTP-3983 \ - OTP-3985 \ - OTP-3988 \ - OTP-3984 \ - OTP-3994 - -TICKETS_1.2.9.6 = \ - OTP-3830 - -TICKETS_1.2.9.5 = \ - OTP-3713 \ - OTP-3796 \ - OTP-3811 - -TICKETS_1.2.9.3 = \ - OTP-3700 \ - OTP-3701 - -TICKETS_1.2.9.2 = \ - OTP-xxxx - -TICKETS_1.2.9.1 = \ - OTP-xxxx - -TICKETS_1.2.9 = \ - OTP-3569 \ - OTP-3573 - -TICKETS_1.2.8 = \ - OTP-3496 - -TICKETS_1.2.7 = \ - OTP-3395 - -TICKETS_1.2.6 = \ - OTP-3352 - -TICKETS_1.2.5 = \ - OTP-3341 - diff --git a/lib/common_test/src/ct_logs.erl b/lib/common_test/src/ct_logs.erl index f8ae7202e6..3684ff462f 100644 --- a/lib/common_test/src/ct_logs.erl +++ b/lib/common_test/src/ct_logs.erl @@ -384,11 +384,14 @@ maybe_log_timestamp() -> [{"<i>~s</i>",[log_timestamp({MS,S,US})]}]}) end. -log_timestamp(Now) -> - put(log_timestamp,Now), - {_,{H,M,S}} = calendar:now_to_local_time(Now), - lists:flatten(io_lib:format("~2.2.0w:~2.2.0w:~2.2.0w", - [H,M,S])). +log_timestamp({MS,S,US}) -> + put(log_timestamp, {MS,S,US}), + {{Year,Month,Day}, {Hour,Min,Sec}} = + calendar:now_to_local_time({MS,S,US}), + MilliSec = trunc(US/1000), + lists:flatten(io_lib:format("~4.10.0B-~2.10.0B-~2.10.0B " + "~2.10.0B:~2.10.0B:~2.10.0B.~3.10.0B", + [Year,Month,Day,Hour,Min,Sec,MilliSec])). %%%----------------------------------------------------------------- %%% The logger server diff --git a/lib/compiler/src/compile.erl b/lib/compiler/src/compile.erl index ed7a9144a8..26da3ecad2 100644 --- a/lib/compiler/src/compile.erl +++ b/lib/compiler/src/compile.erl @@ -824,6 +824,10 @@ foldl_transform(St, [T|Ts]) -> {'EXIT',R} -> Es = [{St#compile.ifile,[{none,compile,{parse_transform,T,R}}]}], {error,St#compile{errors=St#compile.errors ++ Es}}; + {warning, Forms, Ws} -> + foldl_transform( + St#compile{code=Forms, + warnings=St#compile.warnings ++ Ws}, Ts); Forms -> foldl_transform(St#compile{code=Forms}, Ts) end; diff --git a/lib/cosEvent/vsn.mk b/lib/cosEvent/vsn.mk index 9f326b39b6..9c00a17100 100644 --- a/lib/cosEvent/vsn.mk +++ b/lib/cosEvent/vsn.mk @@ -1,15 +1 @@ - COSEVENT_VSN = 2.1.9 - -TICKETS = OTP-8543 - -TICKETS_2.1.8 = OTP-8355 \ - OTP-8409 - -TICKETS_2.1.7 = OTP-8201 - -TICKETS_2.1.6 = OTP-7987 - -TICKETS_2.1.5 = OTP-7837 - -TICKETS_2.1.4 = OTP-7595 diff --git a/lib/cosEventDomain/vsn.mk b/lib/cosEventDomain/vsn.mk index dceee34181..bd21133fe5 100644 --- a/lib/cosEventDomain/vsn.mk +++ b/lib/cosEventDomain/vsn.mk @@ -1,15 +1 @@ - COSEVENTDOMAIN_VSN = 1.1.9 - -TICKETS = OTP-8543 - -TICKETS_1.1.8 = OTP-8353 \ - OTP-8355 - -TICKETS_1.1.7 = OTP-8201 - -TICKETS_1.1.6 = OTP-7987 - -TICKETS_1.1.5 = OTP-7837 - -TICKETS_1.1.4 = OTP-7595 diff --git a/lib/cosFileTransfer/vsn.mk b/lib/cosFileTransfer/vsn.mk index 2700ecb3e3..ef8ee53c5e 100644 --- a/lib/cosFileTransfer/vsn.mk +++ b/lib/cosFileTransfer/vsn.mk @@ -1,16 +1 @@ COSFILETRANSFER_VSN = 1.1.10 - -TICKETS = \ - OTP-8355 \ - OTP-8374 - - -TICKETS_1.1.9 = OTP-8201 - -TICKETS_1.1.8 = OTP-7987 - -TICKETS_1.1.7 = OTP-7837 - -TICKETS_1.1.6 = \ - OTP-7595 \ - OTP-7599
\ No newline at end of file diff --git a/lib/cosNotification/vsn.mk b/lib/cosNotification/vsn.mk index a19facffd5..c03f0ef161 100644 --- a/lib/cosNotification/vsn.mk +++ b/lib/cosNotification/vsn.mk @@ -1,18 +1 @@ COSNOTIFICATION_VSN = 1.1.14 - -TICKETS = OTP-8489 \ - OTP-8543 - -TICKETS_1.1.13 = OTP-8353 \ - OTP-8354 \ - OTP-8355 - -TICKETS_1.1.12 = OTP-8201 - -TICKETS_1.1.11 = OTP-7987 - -TICKETS_1.1.10 = OTP-7837 - -TICKETS_1.1.9 = OTP-7595 - -TICKETS_1.1.8 = OTP-7553 diff --git a/lib/cosProperty/vsn.mk b/lib/cosProperty/vsn.mk index 3d594a8329..ca9a7ca77e 100644 --- a/lib/cosProperty/vsn.mk +++ b/lib/cosProperty/vsn.mk @@ -1,13 +1 @@ COSPROPERTY_VSN = 1.1.12 - -TICKETS = OTP-8543 - -TICKETS_1.1.11 = OTP-8355 - -TICKETS_1.1.10 = OTP-8201 - -TICKETS_1.1.9 = OTP-7987 - -TICKETS_1.1.8 = OTP-7837 - -TICKETS_1.1.7 = OTP-7595 diff --git a/lib/cosTime/vsn.mk b/lib/cosTime/vsn.mk index 9d8057e8db..429613fb61 100644 --- a/lib/cosTime/vsn.mk +++ b/lib/cosTime/vsn.mk @@ -1,13 +1 @@ COSTIME_VSN = 1.1.9 - -TICKETS = OTP-8543 - -TICKETS_1.1.8 = OTP-8355 - -TICKETS_1.1.7 = OTP-8201 - -TICKETS_1.1.6 = OTP-7987 - -TICKETS_1.1.5 = OTP-7837 - -TICKETS_1.1.4 = OTP-7595 diff --git a/lib/cosTransactions/vsn.mk b/lib/cosTransactions/vsn.mk index 34775be7e4..82e46f51dd 100644 --- a/lib/cosTransactions/vsn.mk +++ b/lib/cosTransactions/vsn.mk @@ -1,14 +1 @@ COSTRANSACTIONS_VSN = 1.2.10 - -TICKETS = OTP-8489 \ - OTP-8543 - -TICKETS_1.2.9 = OTP-8355 - -TICKETS_1.2.8 = OTP-8201 - -TICKETS_1.2.7 = OTP-7987 - -TICKETS_1.2.6 = OTP-7837 - -TICKETS_1.2.5 = OTP-7595 diff --git a/lib/crypto/c_src/Makefile.in b/lib/crypto/c_src/Makefile.in index e728db18eb..040adcfd09 100644 --- a/lib/crypto/c_src/Makefile.in +++ b/lib/crypto/c_src/Makefile.in @@ -68,13 +68,13 @@ RELSYSDIR = $(RELEASE_PATH)/lib/crypto-$(VSN) # ---------------------------------------------------- # Misc Macros # ---------------------------------------------------- -OBJS = $(OBJDIR)/crypto.o +OBJS = $(OBJDIR)/crypto$(TYPEMARKER).o NIF_MAKEFILE = $(PRIVDIR)/Makefile ifeq ($(findstring win32,$(TARGET)), win32) -NIF_LIB = $(LIBDIR)/crypto.dll +NIF_LIB = $(LIBDIR)/crypto$(TYPEMARKER).dll else -NIF_LIB = $(LIBDIR)/crypto.so +NIF_LIB = $(LIBDIR)/crypto$(TYPEMARKER).so endif ifeq ($(HOST_OS),) @@ -102,20 +102,30 @@ $(OBJDIR): $(LIBDIR): -@mkdir -p $(LIBDIR) -$(OBJDIR)/%.o: %.c +$(OBJDIR)/%$(TYPEMARKER).o: %.c $(INSTALL_DIR) $(OBJDIR) $(CC) -c -o $@ $(ALL_CFLAGS) $< -$(LIBDIR)/crypto.so: $(OBJS) +$(LIBDIR)/crypto$(TYPEMARKER).so: $(OBJS) $(INSTALL_DIR) $(LIBDIR) $(LD) $(LDFLAGS) -o $@ $^ $(LDLIBS) $(CRYPTO_LINK_LIB) -$(LIBDIR)/crypto.dll: $(OBJS) +$(LIBDIR)/crypto$(TYPEMARKER).dll: $(OBJS) $(INSTALL_DIR) $(LIBDIR) $(LD) $(LDFLAGS) -o $@ $(SSL_DED_LD_RUNTIME_LIBRARY_PATH) -L$(SSL_LIBDIR) $(OBJS) -llibeay32 clean: - rm -f $(NIF_LIB) $(OBJS) +ifeq ($(findstring win32,$(TARGET)), win32) + rm -f $(LIBDIR)/crypto.dll + rm -f $(LIBDIR)/crypto.debug.dll +else + rm -f $(LIBDIR)/crypto.so + rm -f $(LIBDIR)/crypto.debug.so + rm -f $(LIBDIR)/crypto.valgrind.so +endif + rm -f $(OBJDIR)/crypto.o + rm -f $(OBJDIR)/crypto.debug.o + rm -f $(OBJDIR)/crypto.valgrind.o rm -f core *~ docs: diff --git a/lib/crypto/c_src/crypto.c b/lib/crypto/c_src/crypto.c index 68079f06c7..85614a84c2 100644 --- a/lib/crypto/c_src/crypto.c +++ b/lib/crypto/c_src/crypto.c @@ -64,8 +64,8 @@ # define ERL_VALGRIND_ASSERT_MEM_DEFINED(ptr,size) \ ((void) ((VALGRIND_CHECK_MEM_IS_DEFINED(ptr,size) == 0) ? 1 : \ - (fprintf(stderr,"\r\n####### VALGRIND_ASSSERT(%p,%d) failed at %s:%d\r\n",\ - (ptr),(size), __FILE__, __LINE__), abort(), 0))) + (fprintf(stderr,"\r\n####### VALGRIND_ASSSERT(%p,%ld) failed at %s:%d\r\n",\ + (ptr),(long)(size), __FILE__, __LINE__), abort(), 0))) #else # define ERL_VALGRIND_MAKE_MEM_DEFINED(ptr,size) # define ERL_VALGRIND_ASSERT_MEM_DEFINED(ptr,size) @@ -706,12 +706,13 @@ static int get_bn_from_mpint(ErlNifEnv* env, ERL_NIF_TERM term, BIGNUM** bnp) static ERL_NIF_TERM rand_uniform_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) {/* (Lo,Hi) */ - BIGNUM *bn_from, *bn_to, *bn_rand; + BIGNUM *bn_from = NULL, *bn_to, *bn_rand; unsigned char* data; unsigned dlen; ERL_NIF_TERM ret; if (!get_bn_from_mpint(env, argv[0], &bn_from) || !get_bn_from_mpint(env, argv[1], &bn_rand)) { + if (bn_from) BN_free(bn_from); return enif_make_badarg(env); } @@ -770,7 +771,7 @@ static int inspect_mpint(ErlNifEnv* env, ERL_NIF_TERM term, ErlNifBinary* bin) static ERL_NIF_TERM dss_verify(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) {/* (DigestType,Data,Signature,Key=[P, Q, G, Y]) */ ErlNifBinary data_bin, sign_bin; - BIGNUM *dsa_p, *dsa_q, *dsa_g, *dsa_y; + BIGNUM *dsa_p = NULL, *dsa_q = NULL, *dsa_g = NULL, *dsa_y = NULL; unsigned char hmacbuf[SHA_DIGEST_LENGTH]; ERL_NIF_TERM head, tail; DSA *dsa; @@ -786,6 +787,11 @@ static ERL_NIF_TERM dss_verify(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv || !enif_get_list_cell(env, tail, &head, &tail) || !get_bn_from_mpint(env, head, &dsa_y) || !enif_is_empty_list(env,tail)) { + badarg: + if (dsa_p) BN_free(dsa_p); + if (dsa_q) BN_free(dsa_q); + if (dsa_g) BN_free(dsa_g); + if (dsa_y) BN_free(dsa_y); return enif_make_badarg(env); } if (argv[0] == atom_sha && inspect_mpint(env, argv[1], &data_bin)) { @@ -796,7 +802,7 @@ static ERL_NIF_TERM dss_verify(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv memcpy(hmacbuf, data_bin.data, SHA_DIGEST_LENGTH); } else { - return enif_make_badarg(env); + goto badarg; } dsa = DSA_new(); @@ -950,7 +956,7 @@ static ERL_NIF_TERM rc4_encrypt_with_state(ErlNifEnv* env, int argc, const ERL_N RC4(rc4_key, data.size, data.data, enif_make_new_binary(env, data.size, &new_data)); - return enif_make_tuple2(env,argv[0],new_data); + return enif_make_tuple2(env,new_state,new_data); } static ERL_NIF_TERM rc2_40_cbc_crypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) @@ -1119,7 +1125,7 @@ static ERL_NIF_TERM rsa_public_crypt(ErlNifEnv* env, int argc, const ERL_NIF_TER enif_alloc_binary(RSA_size(rsa), &ret_bin); if (argv[3] == atom_true) { - ERL_VALGRIND_ASSERT_MEM_DEFINED(buf+i,data_len); + ERL_VALGRIND_ASSERT_MEM_DEFINED(data_bin.data,data_bin.size); i = RSA_public_encrypt(data_bin.size, data_bin.data, ret_bin.data, rsa, padding); if (i > 0) { @@ -1139,6 +1145,7 @@ static ERL_NIF_TERM rsa_public_crypt(ErlNifEnv* env, int argc, const ERL_NIF_TER return enif_make_binary(env,&ret_bin); } else { + enif_release_binary(&ret_bin); return atom_error; } } @@ -1167,7 +1174,7 @@ static ERL_NIF_TERM rsa_private_crypt(ErlNifEnv* env, int argc, const ERL_NIF_TE enif_alloc_binary(RSA_size(rsa), &ret_bin); if (argv[3] == atom_true) { - ERL_VALGRIND_ASSERT_MEM_DEFINED(buf+i,data_len); + ERL_VALGRIND_ASSERT_MEM_DEFINED(data_bin.data,data_bin.size); i = RSA_private_encrypt(data_bin.size, data_bin.data, ret_bin.data, rsa, padding); if (i > 0) { @@ -1187,6 +1194,7 @@ static ERL_NIF_TERM rsa_private_crypt(ErlNifEnv* env, int argc, const ERL_NIF_TE return enif_make_binary(env,&ret_bin); } else { + enif_release_binary(&ret_bin); return atom_error; } } @@ -1266,7 +1274,7 @@ static ERL_NIF_TERM dh_generate_key_nif(ErlNifEnv* env, int argc, const ERL_NIF_ || !enif_get_list_cell(env, tail, &head, &tail) || !get_bn_from_mpint(env, head, &dh_params->g) || !enif_is_empty_list(env, tail)) { - + DH_free(dh_params); return enif_make_badarg(env); } @@ -1293,7 +1301,7 @@ static ERL_NIF_TERM dh_generate_key_nif(ErlNifEnv* env, int argc, const ERL_NIF_ static ERL_NIF_TERM dh_compute_key_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) {/* (OthersPublicKey, MyPrivateKey, DHParams=[P,G]) */ DH* dh_params = DH_new(); - BIGNUM* pubkey; + BIGNUM* pubkey = NULL; int i; ErlNifBinary ret_bin; ERL_NIF_TERM ret, head, tail; @@ -1321,6 +1329,7 @@ static ERL_NIF_TERM dh_compute_key_nif(ErlNifEnv* env, int argc, const ERL_NIF_T ret = atom_error; } } + if (pubkey) BN_free(pubkey); DH_free(dh_params); return ret; } diff --git a/lib/crypto/src/crypto.erl b/lib/crypto/src/crypto.erl index 19fa495b7d..71fd91cafd 100644 --- a/lib/crypto/src/crypto.erl +++ b/lib/crypto/src/crypto.erl @@ -93,22 +93,42 @@ -define(CRYPTO_NIF_VSN,101). on_load() -> - LibName = "crypto", + LibBaseName = "crypto", PrivDir = code:priv_dir(crypto), - Lib1 = filename:join([PrivDir, "lib", LibName]), - Status = case erlang:load_nif(Lib1, ?CRYPTO_NIF_VSN) of + LibName = case erlang:system_info(build_type) of + opt -> + LibBaseName; + Type -> + LibTypeName = LibBaseName ++ "." ++ atom_to_list(Type), + case (filelib:wildcard( + filename:join( + [PrivDir, + "lib", + LibTypeName ++ "*"])) /= []) orelse + (filelib:wildcard( + filename:join( + [PrivDir, + "lib", + erlang:system_info(system_architecture), + LibTypeName ++ "*"])) /= []) of + true -> LibTypeName; + false -> LibBaseName + end + end, + Lib = filename:join([PrivDir, "lib", LibName]), + Status = case erlang:load_nif(Lib, ?CRYPTO_NIF_VSN) of ok -> ok; {error, {load_failed, _}}=Error1 -> - LibDir2 = + ArchLibDir = filename:join([PrivDir, "lib", erlang:system_info(system_architecture)]), Candidate = - filelib:wildcard(filename:join([LibDir2,LibName ++ "*" ])), + filelib:wildcard(filename:join([ArchLibDir,LibName ++ "*" ])), case Candidate of [] -> Error1; _ -> - Lib2 = filename:join([LibDir2, LibName]), - erlang:load_nif(Lib2, ?CRYPTO_NIF_VSN) + ArchLib = filename:join([ArchLibDir, LibName]), + erlang:load_nif(ArchLib, ?CRYPTO_NIF_VSN) end; Error1 -> Error1 end, @@ -119,7 +139,6 @@ on_load() -> "OpenSSL might not be installed on this system.~n",[E,Str]), Status end. - nif_stub_error(Line) -> erlang:nif_error({nif_not_loaded,module,?MODULE,line,Line}). diff --git a/lib/crypto/test/crypto_SUITE.erl b/lib/crypto/test/crypto_SUITE.erl index 576949d38d..06b284d50d 100644 --- a/lib/crypto/test/crypto_SUITE.erl +++ b/lib/crypto/test/crypto_SUITE.erl @@ -54,6 +54,7 @@ dh/1, exor_test/1, rc4_test/1, + rc4_stream_test/1, blowfish_cfb64/1, smp/1, cleanup/1]). @@ -89,6 +90,7 @@ all(suite) -> dh, exor_test, rc4_test, + rc4_stream_test, mod_exp_test, blowfish_cfb64, smp], @@ -979,6 +981,21 @@ rc4_test(Config) when is_list(Config) -> CT2 = binary_to_list(crypto:rc4_encrypt(K, R2)), ok. +rc4_stream_test(doc) -> + ["Test rc4 stream encryption ."]; +rc4_stream_test(suite) -> + []; +rc4_stream_test(Config) when is_list(Config) -> + CT1 = <<"hej">>, + CT2 = <<" p� dig">>, + K = "apaapa", + State0 = crypto:rc4_set_key(K), + {State1, R1} = crypto:rc4_encrypt_with_state(State0, CT1), + {_State2, R2} = crypto:rc4_encrypt_with_state(State1, CT2), + R = list_to_binary([R1, R2]), + <<71,112,14,44,140,33,212,144,155,47>> = R, + ok. + blowfish_cfb64(doc) -> ["Test Blowfish encrypt/decrypt."]; blowfish_cfb64(suite) -> []; blowfish_cfb64(Config) when is_list(Config) -> @@ -1029,7 +1046,7 @@ worker_loop(0, _) -> worker_loop(N, Config) -> Funcs = { md5, md5_update, md5_mac, md5_mac_io, sha, sha_update, des_cbc, aes_cfb, aes_cbc, des_cbc_iter, rand_uniform_test, - rsa_verify_test, exor_test, rc4_test, mod_exp_test }, + rsa_verify_test, exor_test, rc4_test, rc4_stream_test, mod_exp_test }, F = element(random:uniform(size(Funcs)),Funcs), %%io:format("worker ~p calling ~p\n",[self(),F]), diff --git a/lib/docbuilder/src/docb_edoc_xml_cb.erl b/lib/docbuilder/src/docb_edoc_xml_cb.erl index f5cfc0fe18..90491bc007 100644 --- a/lib/docbuilder/src/docb_edoc_xml_cb.erl +++ b/lib/docbuilder/src/docb_edoc_xml_cb.erl @@ -340,9 +340,7 @@ otp_xmlify_e(#xmlElement{name=code} = E) -> % 4) [E#xmlElement{content=Content}] end; otp_xmlify_e(#xmlElement{name=Tag} = E) % 5a - when Tag==h1; Tag==h2; Tag==h3; Tag==h4; Tag==h5; - Tag==center; - Tag==font -> + when Tag==h1; Tag==h2; Tag==h3; Tag==h4; Tag==h5 -> Content = text_only(E#xmlElement.content), [E#xmlElement{name=b, content=Content}]; otp_xmlify_e(#xmlElement{name=Tag} = E) % 5b-c) @@ -354,21 +352,16 @@ otp_xmlify_e(#xmlElement{name=table} = E) -> % 6) module -> otp_xmlify_table(E#xmlElement.content); overview -> - case get_attrval(border, E) of - "" -> % implies border="0" - [{p, otp_xmlify_table(E#xmlElement.content)}]; - "0" -> - [{p, otp_xmlify_table(E#xmlElement.content)}]; - _Val -> - Content0 = otp_xmlify_e(E#xmlElement.content), - Summary = #xmlText{value=get_attrval(summary, E)}, - TCaption = E#xmlElement{name=tcaption, - attributes=[], - content=[Summary]}, - Content = Content0 ++ [TCaption], - [E#xmlElement{attributes=[], content=Content}] - end + Content0 = otp_xmlify_e(E#xmlElement.content), + Summary = #xmlText{value=get_attrval(summary, E)}, + TCaption = E#xmlElement{name=tcaption, + attributes=[], + content=[Summary]}, + Content = Content0 ++ [TCaption], + [E#xmlElement{attributes=[], content=Content}] end; +otp_xmlify_e(#xmlElement{name=tbody} = E) -> + otp_xmlify_e(E#xmlElement.content); otp_xmlify_e(#xmlElement{name=sup} = E) -> % 7) Text = get_text(E), [#xmlText{parents = E#xmlElement.parents, diff --git a/lib/docbuilder/vsn.mk b/lib/docbuilder/vsn.mk index 2852ebcc8b..5bb92fd209 100644 --- a/lib/docbuilder/vsn.mk +++ b/lib/docbuilder/vsn.mk @@ -1,14 +1 @@ DOCB_VSN = 0.9.8.7 - -TICKETS = OTP-8343 - -TICKETS_0.9.8.6 = OTP-8201 - -TICKETS_0.9.8.5 = OTP-7851 - -TICKETS_0.9.8.4 = OTP-7236 - -TICKETS_0.9.8.1 = OTP-7236 - - - diff --git a/lib/erl_docgen/priv/xsl/db_html.xsl b/lib/erl_docgen/priv/xsl/db_html.xsl index 5614b02bb7..bba0f97645 100644 --- a/lib/erl_docgen/priv/xsl/db_html.xsl +++ b/lib/erl_docgen/priv/xsl/db_html.xsl @@ -1157,6 +1157,7 @@ </xsl:template> + <xsl:template match="name"> <xsl:variable name="tmpstring"> @@ -1208,6 +1209,9 @@ </xsl:variable> <a name="{$fname}-{$arity}"><span class="bold_code"><xsl:value-of select="."/></span></a><br/> </xsl:when> + <xsl:otherwise> + <span class="bold_code"><xsl:value-of select="."/></span> + </xsl:otherwise> </xsl:choose> </xsl:template> diff --git a/lib/erl_docgen/vsn.mk b/lib/erl_docgen/vsn.mk index 5b14051034..33d8c1f708 100644 --- a/lib/erl_docgen/vsn.mk +++ b/lib/erl_docgen/vsn.mk @@ -1,22 +1 @@ -# -# %CopyrightBegin% -# -# Copyright Ericsson AB 2009-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% -# - ERL_DOCGEN_VSN = 0.2.1 - -TICKETS = diff --git a/lib/erl_interface/doc/src/ei_connect.xml b/lib/erl_interface/doc/src/ei_connect.xml index 927395d1bf..36dfb149cc 100644 --- a/lib/erl_interface/doc/src/ei_connect.xml +++ b/lib/erl_interface/doc/src/ei_connect.xml @@ -116,7 +116,7 @@ int n = 0; struct in_addr addr; ei_cnode ec; -addr = inet_addr("150.236.14.75"); +addr.s_addr = inet_addr("150.236.14.75"); if (ei_connect_xinit(&ec, "chivas", "madonna", @@ -132,7 +132,7 @@ if (ei_connect_xinit(&ec, </p> <code type="none"><![CDATA[ if (ei_connect_init(&ec, "madonna", "cookie...", n++) < 0) { - fprintf("ERROR when initializing: %d",erl_errno); + fprintf(stderr,"ERROR when initializing: %d",erl_errno); exit(-1); } ]]></code> @@ -177,7 +177,7 @@ int fd = ei_connect(&ec, NODE); /*** Variant 2 ***/ struct in_addr addr; -addr = inet_addr(IP_ADDR); +addr.s_addr = inet_addr(IP_ADDR); fd = ei_xconnect(&ec, &addr, ALIVE); ]]></code> </desc> diff --git a/lib/erl_interface/src/connect/ei_connect.c b/lib/erl_interface/src/connect/ei_connect.c index b1b79aa0e5..e191f3fbf0 100644 --- a/lib/erl_interface/src/connect/ei_connect.c +++ b/lib/erl_interface/src/connect/ei_connect.c @@ -502,10 +502,14 @@ int ei_connect_init(ei_cnode* ec, const char* this_node_name, return ERL_ERROR; } - if (this_node_name == NULL) + if (this_node_name == NULL) { sprintf(thisalivename, "c%d", (int) getpid()); - else + } else if (strlen(this_node_name) >= sizeof(thisalivename)) { + EI_TRACE_ERR0("ei_connect_init","ERROR: this_node_name too long"); + return ERL_ERROR; + } else { strcpy(thisalivename, this_node_name); + } if ((hp = ei_gethostbyname(thishostname)) == 0) { /* Looking up IP given hostname fails. We must be on a standalone diff --git a/lib/erl_interface/src/epmd/epmd_port.c b/lib/erl_interface/src/epmd/epmd_port.c index 663b38d2d4..cf6122fafa 100644 --- a/lib/erl_interface/src/epmd/epmd_port.c +++ b/lib/erl_interface/src/epmd/epmd_port.c @@ -106,6 +106,12 @@ static int ei_epmd_r3_port (struct in_addr *addr, const char *alive, char ntoabuf[32]; #endif + if (len > sizeof(buf) - 3) + { + erl_errno = ERANGE; + return -1; + } + put16be(s,len); put8(s,EI_EPMD_PORT_REQ); strcpy(s,alive); @@ -164,6 +170,12 @@ static int ei_epmd_r4_port (struct in_addr *addr, const char *alive, #if defined(VXWORKS) char ntoabuf[32]; #endif + + if (len > sizeof(buf) - 3) + { + erl_errno = ERANGE; + return -1; + } put16be(s,len); put8(s,EI_EPMD_PORT2_REQ); diff --git a/lib/et/doc/src/et.xml b/lib/et/doc/src/et.xml index 9b170dd7d9..5e3453c348 100644 --- a/lib/et/doc/src/et.xml +++ b/lib/et/doc/src/et.xml @@ -29,6 +29,7 @@ <checked></checked> <date></date> <rev>%VSN%</rev> + <file>et</file> </header> <module>et</module> <modulesummary>Main API of the Event Trace (ET) application</modulesummary> diff --git a/lib/et/doc/src/et_collector.xml b/lib/et/doc/src/et_collector.xml index 88c478c89a..e9885dcbb3 100644 --- a/lib/et/doc/src/et_collector.xml +++ b/lib/et/doc/src/et_collector.xml @@ -29,6 +29,7 @@ <checked></checked> <date></date> <rev>%VSN%</rev> + <file>et_collector.xml</file> </header> <module>et_collector</module> <modulesummary>Collect trace events and provide a backing storage appropriate for iteration </modulesummary> diff --git a/lib/et/doc/src/et_selector.xml b/lib/et/doc/src/et_selector.xml index dd12166d85..34203306bb 100644 --- a/lib/et/doc/src/et_selector.xml +++ b/lib/et/doc/src/et_selector.xml @@ -29,6 +29,7 @@ <checked></checked> <date></date> <rev>%VSN%</rev> + <file>et_selector.xml</file> </header> <module>et_selector</module> <modulesummary>Define event transforms and trace patterns</modulesummary> diff --git a/lib/et/doc/src/et_tutorial.xmlsrc b/lib/et/doc/src/et_tutorial.xmlsrc index c72234a587..b0e2bf4af6 100644 --- a/lib/et/doc/src/et_tutorial.xmlsrc +++ b/lib/et/doc/src/et_tutorial.xmlsrc @@ -29,6 +29,7 @@ <checked></checked> <date></date> <rev>%VSN%</rev> + <file>et_tutorial.xml</file> </header> <section> diff --git a/lib/et/doc/src/et_viewer.xml b/lib/et/doc/src/et_viewer.xml index c16e5b8869..d4cfbdfa31 100644 --- a/lib/et/doc/src/et_viewer.xml +++ b/lib/et/doc/src/et_viewer.xml @@ -29,6 +29,7 @@ <checked></checked> <date></date> <rev>%VSN%</rev> + <file>et_viewer.xml</file> </header> <module>et_viewer</module> <modulesummary>Displays a sequence chart for trace events (messages/actions)</modulesummary> diff --git a/lib/et/vsn.mk b/lib/et/vsn.mk index b7d65b12a2..04ecb8c82e 100644 --- a/lib/et/vsn.mk +++ b/lib/et/vsn.mk @@ -1,24 +1 @@ -# This is an -*-makefile-*- file. -# %CopyrightBegin% -# -# Copyright Ericsson AB 2002-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% - ET_VSN = 1.4 -TICKETS = OTP-8058 - -TICKETS_1_3_3 = OTP-8201 -TICKETS_1_3_2 = OTP-8078 -TICKETS_1_3_1 = OTP-7830 diff --git a/lib/hipe/cerl/erl_bif_types.erl b/lib/hipe/cerl/erl_bif_types.erl index 1f0247a040..6eeeab3610 100644 --- a/lib/hipe/cerl/erl_bif_types.erl +++ b/lib/hipe/cerl/erl_bif_types.erl @@ -1638,7 +1638,6 @@ type(erlang, system_info, 1, Xs) -> t_non_neg_integer()])])); ['allocator'] -> t_tuple([t_sup([t_atom('undefined'), - t_atom('elib_malloc'), t_atom('glibc')]), t_list(t_integer()), t_list(t_atom()), @@ -1659,9 +1658,8 @@ type(erlang, system_info, 1, Xs) -> t_binary(); ['dist_ctrl'] -> t_list(t_tuple([t_atom(), t_sup([t_pid(), t_port])])); - ['elib_malloc'] -> - t_sup([t_atom('false'), - t_list(t_tuple([t_atom(), t_any()]))]); + %% elib_malloc is intentionally not included, + %% because it scheduled for removal in R15. ['endian'] -> t_endian(); ['fullsweep_after'] -> diff --git a/lib/hipe/icode/hipe_icode_exceptions.erl b/lib/hipe/icode/hipe_icode_exceptions.erl index 787fb05415..3c8f7b5712 100644 --- a/lib/hipe/icode/hipe_icode_exceptions.erl +++ b/lib/hipe/icode/hipe_icode_exceptions.erl @@ -344,6 +344,16 @@ pop_catch(Cs) -> pop_catch_1([[_|C] | Cs]) -> [C | pop_catch_1(Cs)]; +pop_catch_1([[] | Cs]) -> + %% The elements in the list represent different possible incoming + %% stacks of catch handlers to this BB. Before the fixpoint has + %% been found these elements are underapproximations of the true + %% stacks, therefore it's possible for these elements to be too + %% short for the number of pops implied by the code in the BB. + %% We must not fail in that case, so we set pop([]) = []. + %% This fixes find_catches_crash.erl and compiler_tests in the + %% HiPE test suite. + [[] | pop_catch_1(Cs)]; pop_catch_1([]) -> []. diff --git a/lib/hipe/main/hipe.erl b/lib/hipe/main/hipe.erl index ed722fecba..c80fb6a0a2 100644 --- a/lib/hipe/main/hipe.erl +++ b/lib/hipe/main/hipe.erl @@ -274,7 +274,7 @@ load(Mod, BeamFileName) when is_list(BeamFileName) -> Architecture = erlang:system_info(hipe_architecture), ChunkName = hipe_unified_loader:chunk_name(Architecture), case beam_lib:chunks(BeamFileName, [ChunkName]) of - {ok,{_,[{_,Bin}]}} when is_binary(Bin) -> do_load(Mod, Bin, Bin); + {ok,{_,[{_,Bin}]}} when is_binary(Bin) -> do_load(Mod, Bin, BeamFileName); Error -> {error, Error} end. @@ -913,7 +913,7 @@ do_load(Mod, Bin, WholeModule) -> %% In this case, the emulated code for the module must be loaded. {module, Mod} = code:ensure_loaded(Mod), code:load_native_partial(Mod, Bin); - BinCode when is_binary(BinCode) -> + BeamBinOrPath when is_binary(BeamBinOrPath) orelse is_list(BeamBinOrPath) -> case code:is_sticky(Mod) of true -> %% We unpack and repack the Beam binary as a workaround to diff --git a/lib/ic/vsn.mk b/lib/ic/vsn.mk index 4aa2a04b60..074d0b3d39 100644 --- a/lib/ic/vsn.mk +++ b/lib/ic/vsn.mk @@ -1,20 +1 @@ IC_VSN = 4.2.25 - -TICKETS = OTP-8639 - -TICKETS_4.2.24 = OTP-8307 \ - OTP-8353 \ - OTP-8354 \ - OTP-8355 - -TICKETS_4.2.23 = OTP-8201 - -TICKETS_4.2.22 = OTP-8088 - -TICKETS_4.2.21 = OTP-7982 - -TICKETS_4.2.20 = OTP-7837 - -TICKETS_4.2.19 = OTP-7595 - -TICKETS_4.2.18 = OTP-7313 diff --git a/lib/inets/doc/src/http_client.xml b/lib/inets/doc/src/http_client.xml index 510c30eb35..ea8053cafa 100644 --- a/lib/inets/doc/src/http_client.xml +++ b/lib/inets/doc/src/http_client.xml @@ -4,7 +4,7 @@ <chapter> <header> <copyright> - <year>2004</year><year>2009</year> + <year>2004</year><year>2010</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -56,8 +56,8 @@ <pre> [{inets, [{services, [{httpc, PropertyList}]}]}] </pre> - <p>For valid properties see <seealso - marker="http">http(3)</seealso></p> + <p>For valid properties see + <seealso marker="http">httpc(3)</seealso>. </p> </section> <section> @@ -71,67 +71,66 @@ but not for requests to localhost. This will apply to all subsequent requests</p> <code type="erl"> - 2 > http:set_options([{proxy, {{"www-proxy.mycompany.com", 8000}, + 2 > httpc:set_options([{proxy, {{"www-proxy.mycompany.com", 8000}, ["localhost"]}}]). ok </code> <p>An ordinary synchronous request. </p> <code type="erl"> 3 > {ok, {{Version, 200, ReasonPhrase}, Headers, Body}} = - http:request(get, {"http://www.erlang.org", []}, [], []). + httpc:request(get, {"http://www.erlang.org", []}, [], []). </code> <p>With all default values, as above, a get request can also be written like this.</p> <code type="erl"> 4 > {ok, {{Version, 200, ReasonPhrase}, Headers, Body}} = - http:request("http://www.erlang.org"). + httpc:request("http://www.erlang.org"). </code> <p>An ordinary asynchronous request. The result will be sent to the calling process on the form {http, {ReqestId, Result}}</p> <code type="erl"> 5 > {ok, RequestId} = - http:request(get, {"http://www.erlang.org", []}, [], [{sync, false}]). + httpc:request(get, {"http://www.erlang.org", []}, [], [{sync, false}]). </code> <p>In this case the calling process is the shell, so we receive the result.</p> <code type="erl"> - 6 > receive {http, {RequestId, Result}} -> ok after 500 -> error end. + 6 > receive {http, {RequestId, Result}} -> ok after 500 -> error end. ok </code> <p>Send a request with a specified connection header. </p> <code type="erl"> 7 > {ok, {{NewVersion, 200, NewReasonPhrase}, NewHeaders, NewBody}} = - http:request(get, {"http://www.erlang.org", [{"connection", "close"}]}, + httpc:request(get, {"http://www.erlang.org", [{"connection", "close"}]}, [], []). </code> <p>Start a HTTP client profile. </p> <code><![CDATA[ - 8 > {ok, Pid} = inets:start(httpc, [{profile, foo}]). + 8 > {ok, Pid} = inets:start(httpc, [{profile, foo}]). {ok, <0.45.0>} ]]></code> <p>The new profile has no proxy settings so the connection will be refused</p> <code type="erl"> - 9 > http:request("http://www.erlang.org", foo). - {error,econnrefused} + 9 > httpc:request("http://www.erlang.org", foo). + {error, econnrefused} </code> <p>Stop a HTTP client profile. </p> <code type="erl"> - 10 > inets:stop(httpc, foo). + 10 > inets:stop(httpc, foo). ok </code> <p>Alternatively:</p> <code type="erl"> - 10 > inets:stop(httpc, Pid). + 10 > inets:stop(httpc, Pid). ok </code> - </section> </chapter> diff --git a/lib/inets/doc/src/inets.xml b/lib/inets/doc/src/inets.xml index 81dfe7e944..c367d7fa77 100644 --- a/lib/inets/doc/src/inets.xml +++ b/lib/inets/doc/src/inets.xml @@ -13,12 +13,12 @@ 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>inets</title> @@ -40,13 +40,13 @@ <title>COMMON DATA TYPES </title> <p>Type definitions that are used more than once in this module: </p> - <p><c> service() = ftpc | tfptd | httpc | httpd</c></p> + <p><c> service() = ftpc | tftp | httpc | httpd</c></p> <p><c> property() = atom() </c></p> </section> <funcs> <func> <name>services() -> [{Service, Pid}]</name> - <fsummary>Returns a list of currently running services. </fsummary> + <fsummary>Returns a list of currently running services. </fsummary> <type> <v>Service = service()</v> <v>Pid = pid()</v> @@ -97,7 +97,7 @@ <name>start(Type) -> ok | {error, Reason}</name> <fsummary>Starts the Inets application. </fsummary> <type> - <v>Type = permanent | transient | temporary</v> + <v>Type = permanent | transient | temporary</v> </type> <desc> <p>Starts the Inets application. Default type @@ -115,11 +115,9 @@ </func> <func> <name>start(Service, ServiceConfig) -> {ok, Pid} | {error, Reason}</name> - <name>start(Service, ServiceConfig, How) -> {ok, Pid} | - {error, Reason}</name> + <name>start(Service, ServiceConfig, How) -> {ok, Pid} | {error, Reason}</name> <fsummary>Dynamically starts an inets - service after the inets application has been - started. </fsummary> + service after the inets application has been started. </fsummary> <type> <v>Service = service()</v> <v>ServiceConfig = [{Option, Value}]</v> @@ -153,9 +151,9 @@ <fsummary>Stops a started service of the inets application or takes down a "stand_alone-service" gracefully.</fsummary> <type> - <v>Service = service() | stand_alone</v> + <v>Service = service() | stand_alone</v> <v>Reference = pid() | term() - service specified reference</v> - <v>Reason = term()</v> + <v>Reason = term()</v> </type> <desc> <p>Stops a started service of the inets application or takes @@ -169,7 +167,7 @@ <section> <title>SEE ALSO</title> <p><seealso marker="ftp">ftp(3)</seealso>, - <seealso marker="http">http(3)</seealso>, + <seealso marker="httpc">httpc(3)</seealso>, <seealso marker="httpd">httpd(3)</seealso>, <seealso marker="tftp">tftp(3)</seealso></p> </section> diff --git a/lib/inets/src/http_client/httpc_handler.erl b/lib/inets/src/http_client/httpc_handler.erl index c34b641b7b..8af6613fa2 100644 --- a/lib/inets/src/http_client/httpc_handler.erl +++ b/lib/inets/src/http_client/httpc_handler.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% +%% %% Copyright Ericsson AB 2002-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% %% %% @@ -605,24 +605,29 @@ handle_info({ssl_error, _, _} = Reason, State) -> %% Internally, to a request handling process, a request timeout is %% seen as a canceled request. handle_info({timeout, RequestId}, - #state{request = #request{id = RequestId} = Request, - canceled = Canceled} = State) -> + #state{request = #request{id = RequestId} = Request, + canceled = Canceled, + profile_name = ProfileName} = State) -> ?hcri("timeout of current request", [{id, RequestId}]), httpc_response:send(Request#request.from, httpc_response:error(Request, timeout)), + httpc_manager:request_done(RequestId, ProfileName), ?hcrv("response (timeout) sent - now terminate", []), {stop, normal, State#state{request = Request#request{from = answer_sent}, canceled = [RequestId | Canceled]}}; -handle_info({timeout, RequestId}, #state{canceled = Canceled} = State) -> +handle_info({timeout, RequestId}, + #state{canceled = Canceled, + profile_name = ProfileName} = State) -> ?hcri("timeout", [{id, RequestId}]), Filter = fun(#request{id = Id, from = From} = Request) when Id =:= RequestId -> ?hcrv("found request", [{id, Id}, {from, From}]), %% Notify the owner - Response = httpc_response:error(Request, timeout), - httpc_response:send(From, Response), + httpc_response:send(From, + httpc_response:error(Request, timeout)), + httpc_manager:request_done(RequestId, ProfileName), ?hcrv("response (timeout) sent", []), [Request#request{from = answer_sent}]; (_) -> diff --git a/lib/inets/src/http_client/httpc_manager.erl b/lib/inets/src/http_client/httpc_manager.erl index d5d6376369..1e1bde220b 100644 --- a/lib/inets/src/http_client/httpc_manager.erl +++ b/lib/inets/src/http_client/httpc_manager.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% +%% %% Copyright Ericsson AB 2002-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% %% %% @@ -66,15 +66,6 @@ state % State of the handler: initiating | started | operational | canceled }). -%% Entries in the handler / request cross-ref table -%% -record(request_info, -%% { -%% id, % Id of the request -%% handler, % Pid of the handler process -%% from, % The From value for the caller -%% mref % Monitor ref for the caller -%% }). - %%==================================================================== %% Internal Application API @@ -577,7 +568,9 @@ handle_info({'EXIT', Pid, Reason}, #state{handler_db = HandlerDb} = State) -> handle_info({'DOWN', _, _, Pid, _}, State) -> %% - %% Check what happens to waiting requests! Chall we not send a reply? + %% Normally this should have been cleaned up already + %% (when receiving {request_done, PequestId}), but + %% just in case there is a glitch, cleanup anyway. %% Pattern = #handler_info{handler = Pid, _ = '_'}, @@ -649,7 +642,16 @@ get_handler_info(Tab) -> Acc end, Handlers2 = lists:foldl(F, [], Handlers1), - Handlers3 = [{Pid, State, httpc_handler:info(Pid)} || + Handlers3 = [{Pid, State, + case (catch httpc_handler:info(Pid)) of + {'EXIT', _} -> + %% Why would this crash? + %% Only if the process has died, but we don't + %% know about it? + []; + Else -> + Else + end} || {Pid, State} <- Handlers2], Handlers3. @@ -666,6 +668,10 @@ handle_started(StarterPid, ReqId, HandlerPid, case ets:lookup(HandlerDb, ReqId) of [#handler_info{state = initiating} = HandlerInfo] -> ?hcri("received started ack for initiating handler", []), + %% As a last resort, make sure we know when it exits, + %% in case it forgets to notify us. + %% We dont need to know the ref id? + erlang:monitor(process, HandlerPid), HandlerInfo2 = HandlerInfo#handler_info{handler = HandlerPid, state = started}, ets:insert(HandlerDb, HandlerInfo2), diff --git a/lib/inets/src/inets_app/inets.erl b/lib/inets/src/inets_app/inets.erl index f1fa5fd997..054468e445 100644 --- a/lib/inets/src/inets_app/inets.erl +++ b/lib/inets/src/inets_app/inets.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% +%% %% Copyright Ericsson AB 2006-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% %% %% @@ -57,7 +57,7 @@ start(Type) -> %% Function: start(Service, ServiceConfig [, How]) -> {ok, Pid} | %% {error, Reason} %% -%% Service = - ftpc | tftpd | httpc | httpd +%% Service = - ftpc | tftpd | tftpc | tftp | httpc | httpd %% ServiceConfig = ConfPropList | ConfFile %% ConfPropList = [{Property, Value}] according to service %% ConfFile = Path - when service is httpd @@ -100,7 +100,7 @@ stop() -> %%-------------------------------------------------------------------- %% Function: stop(Service, Pid) -> ok %% -%% Service - ftp | tftpd | http | httpd | stand_alone +%% Service - ftpc | ftp | tftpd | tftpc | tftp | httpc | httpd | stand_alone %% %% Description: Stops a started service of the inets application or takes %% down a stand alone "service" gracefully. @@ -382,7 +382,7 @@ key1search(Key, Vals, Def) -> %% Description: Returns a list of supported services %%------------------------------------------------------------------- service_names() -> - [ftpc, tftpd, httpc, httpd]. + [ftpc, tftp, httpc, httpd]. %%----------------------------------------------------------------- @@ -725,8 +725,8 @@ call_service(Service, Call, Args) -> service_module(tftpd) -> tftp; -service_module(httpc) -> - httpc; +service_module(tftpc) -> + tftp; service_module(ftpc) -> ftp; service_module(Service) -> diff --git a/lib/inets/test/ftp_macosx_x86_test.erl b/lib/inets/test/ftp_macosx_x86_test.erl index c59a992421..5566d4feaa 100644 --- a/lib/inets/test/ftp_macosx_x86_test.erl +++ b/lib/inets/test/ftp_macosx_x86_test.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2005-2009. All Rights Reserved. +%% Copyright Ericsson AB 2005-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 @@ -108,7 +108,7 @@ passive_pwd(X) -> ?LIB_MOD:passive_pwd(X). passive_cd(X) -> ?LIB_MOD:passive_cd(X). passive_lcd(X) -> ?LIB_MOD:passive_lcd(X). passive_ls(X) -> ?LIB_MOD:passive_ls(X). -passive_nlist(X) -> ?LIB_MOD:passive_nlist(X). +passive_nlist(X) -> ?LIB_MOD:passive_nlist([{wildcard_support, false} | X]). passive_rename(X) -> ?LIB_MOD:passive_rename(X). passive_delete(X) -> ?LIB_MOD:passive_delete(X). passive_mkdir(X) -> ?LIB_MOD:passive_mkdir(X). @@ -129,7 +129,7 @@ active_pwd(X) -> ?LIB_MOD:active_pwd(X). active_cd(X) -> ?LIB_MOD:active_cd(X). active_lcd(X) -> ?LIB_MOD:active_lcd(X). active_ls(X) -> ?LIB_MOD:active_ls(X). -active_nlist(X) -> ?LIB_MOD:active_nlist(X). +active_nlist(X) -> ?LIB_MOD:active_nlist([{wildcard_support, false} | X]). active_rename(X) -> ?LIB_MOD:active_rename(X). active_delete(X) -> ?LIB_MOD:active_delete(X). active_mkdir(X) -> ?LIB_MOD:active_mkdir(X). diff --git a/lib/inets/test/ftp_suite_lib.erl b/lib/inets/test/ftp_suite_lib.erl index 5e27bc3a86..c539b7c17c 100644 --- a/lib/inets/test/ftp_suite_lib.erl +++ b/lib/inets/test/ftp_suite_lib.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% +%% %% Copyright Ericsson AB 2005-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% %% %% @@ -508,7 +508,8 @@ passive_nlist(suite) -> []; passive_nlist(Config) when is_list(Config) -> Pid = ?config(ftp, Config), - do_nlist(Pid). + WildcardSupport = ?config(wildcard_support, Config), + do_nlist(Pid, WildcardSupport). %%------------------------------------------------------------------------- @@ -768,7 +769,8 @@ active_nlist(suite) -> []; active_nlist(Config) when is_list(Config) -> Pid = ?config(ftp, Config), - do_nlist(Pid). + WildcardSupport = ?config(wildcard_support, Config), + do_nlist(Pid, WildcardSupport). %%------------------------------------------------------------------------- @@ -1242,16 +1244,20 @@ do_ls(Pid) -> {ok, _} = ftp:ls(Pid, "incom*"), ok. -do_nlist(Pid) -> +do_nlist(Pid, WildcardSupport) -> {ok, _} = ftp:nlist(Pid), {ok, _} = ftp:nlist(Pid, "incoming"), %% neither nlist nor ls operates on a directory %% they operate on a pathname, which *can* be a %% directory, but can also be a filename or a group %% of files (including wildcards). - {ok, _} = ftp:nlist(Pid, "incom*"), -%% {error, epath} = ftp:nlist(Pid, ?BAD_DIR), - ok. + case WildcardSupport of + true -> + {ok, _} = ftp:nlist(Pid, "incom*"), + ok; + _ -> + ok + end. do_rename(Pid, Config) -> PrivDir = ?config(priv_dir, Config), diff --git a/lib/inets/test/httpc_SUITE.erl b/lib/inets/test/httpc_SUITE.erl index b5fd896001..902e440c80 100644 --- a/lib/inets/test/httpc_SUITE.erl +++ b/lib/inets/test/httpc_SUITE.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% +%% %% Copyright Ericsson AB 2004-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% %% %% @@ -306,7 +306,8 @@ tickets(suite) -> otp_8106, otp_8056, otp_8352, - otp_8371 + otp_8371, + otp_8739 ]. @@ -2561,7 +2562,78 @@ otp_8371(Config) when is_list(Config) -> ok. +%%------------------------------------------------------------------------- +otp_8739(doc) -> + ["OTP-8739"]; +otp_8739(suite) -> + []; +otp_8739(Config) when is_list(Config) -> + {_DummyServerPid, Port} = otp_8739_dummy_server(), + URL = ?URL_START ++ integer_to_list(Port) ++ "/dummy.html", + Method = get, + Request = {URL, []}, + HttpOptions = [{connect_timeout, 500}, {timeout, 1}], + Options = [{sync, true}], + case http:request(Method, Request, HttpOptions, Options) of + {error, timeout} -> + %% And now we check the size of the handler db + Info = httpc:info(), + tsp("Info: ~p", [Info]), + {value, {handlers, Handlers}} = + lists:keysearch(handlers, 1, Info), + case Handlers of + [] -> + ok; + _ -> + tsf({unexpected_handlers, Handlers}) + end; + Unexpected -> + tsf({unexpected, Unexpected}) + end. + + +otp_8739_dummy_server() -> + Parent = self(), + Pid = spawn_link(fun() -> otp_8739_dummy_server_init(Parent) end), + receive + {port, Port} -> + {Pid, Port} + end. + +otp_8739_dummy_server_init(Parent) -> + {ok, ListenSocket} = + gen_tcp:listen(0, [binary, inet, {packet, 0}, + {reuseaddr,true}, + {active, false}]), + {ok, Port} = inet:port(ListenSocket), + Parent ! {port, Port}, + otp_8739_dummy_server_main(Parent, ListenSocket). + +otp_8739_dummy_server_main(Parent, ListenSocket) -> + case gen_tcp:accept(ListenSocket) of + {ok, Sock} -> + %% Ignore the request, and simply wait for the socket to close + receive + {tcp_closed, Sock} -> + (catch gen_tcp:close(ListenSocket)), + exit(normal); + {tcp_error, Sock, Reason} -> + tsp("socket error: ~p", [Reason]), + (catch gen_tcp:close(ListenSocket)), + exit(normal) + after 10000 -> + %% Just in case + (catch gen_tcp:close(Sock)), + (catch gen_tcp:close(ListenSocket)), + exit(timeout) + end; + Error -> + exit(Error) + end. + + + %%-------------------------------------------------------------------- %% Internal functions %%-------------------------------------------------------------------- diff --git a/lib/inets/vsn.mk b/lib/inets/vsn.mk index 57c87e7036..b53d47d99c 100644 --- a/lib/inets/vsn.mk +++ b/lib/inets/vsn.mk @@ -1,118 +1,4 @@ -#-*-makefile-*- ; force emacs to enter makefile-mode - -# %CopyrightBegin% -# -# Copyright Ericsson AB 1997-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% - APPLICATION = inets INETS_VSN = 5.4 PRE_VSN = APP_VSN = "$(APPLICATION)-$(INETS_VSN)$(PRE_VSN)" - -TICKETS = OTP-7907 OTP-8564 OTP-8573 - -TICKETS_5_3_3 = \ - OTP-8609 \ - OTP-8610 \ - OTP-8624 - -TICKETS_5_3_2 = \ - OTP-8542 \ - OTP-8607 - -TICKETS_5_3_1 = \ - OTP-8508 \ - OTP-8509 - -TICKETS_5_3 = \ - OTP-8016 \ - OTP-8056 \ - OTP-8103 \ - OTP-8106 \ - OTP-8312 \ - OTP-8315 \ - OTP-8327 \ - OTP-8349 \ - OTP-8351 \ - OTP-8352 \ - OTP-8359 \ - OTP-8371 - -TICKETS_5_2 = \ - OTP-8204 \ - OTP-8206 \ - OTP-8247 \ - OTP-8248 \ - OTP-8249 \ - OTP-8258 \ - OTP-8280 - -TICKETS_5_1_3 = OTP-8154 - -TICKETS_5_1_2 = OTP-7298 OTP-8101 OTP-8118 - -TICKETS_5_1_1 = OTP-8052 OTP-8069 - -TICKETS_5_1 = OTP-7994 OTP-7998 OTP-8001 OTP-8004 OTP-8005 - -TICKETS_5_0_14 = OTP-7882 OTP-7883 OTP-7888 OTP-7950 OTP-7976 - -TICKETS_5.0.13 = \ - OTP-7723 \ - OTP-7724 \ - OTP-7726 \ - OTP-7463 \ - OTP-7815 \ - OTP-7857 - -# TICKETS_5.0.12 = \ -# OTP-7636 -# -# TICKETS_5.0.11 = \ -# OTP-7574 \ -# OTP-7597 \ -# OTP-7598 \ -# OTP-7605 -# -# TICKETS_5.0.10 = \ -# OTP-7450 \ -# OTP-7454 \ -# OTP-7490 \ -# OTP-7512 -# -# TICKETS_5.0.9 = \ -# OTP-7257 \ -# OTP-7323 \ -# OTP-7341 -# -# TICKETS_5.0.8 = \ -# OTP-7315 \ -# OTP-7321 -# -# TICKETS_5.0.7 = \ -# OTP-7304 -# -# TICKETS_5.0.6 = \ -# OTP-7266 -# -# TICKETS_5.0.5 = \ -# OTP-7220 \ -# OTP-7221 -# -# TICKETS_5.0.4 = \ -# OTP-7173 -# - diff --git a/lib/jinterface/test/Makefile b/lib/jinterface/test/Makefile new file mode 100644 index 0000000000..36955d1e91 --- /dev/null +++ b/lib/jinterface/test/Makefile @@ -0,0 +1,84 @@ +# +# %CopyrightBegin% +# +# Copyright Ericsson AB 2004-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% +# +include $(ERL_TOP)/make/target.mk +include $(ERL_TOP)/make/$(TARGET)/otp.mk + +# ---------------------------------------------------- +# Application version +# ---------------------------------------------------- +include ../vsn.mk + +# ---------------------------------------------------- +# Release directory specification +# ---------------------------------------------------- +RELSYSDIR = $(RELEASE_PATH)/jinterface_test + +# ---------------------------------------------------- +# Target Specs +# ---------------------------------------------------- +TEST_SPEC_FILE = jinterface.dynspec + +MODULES = nc_SUITE \ + jinterface_SUITE + +GEN_MODULES = jitu + +ERL_FILES = $(MODULES:%=%.erl) $(GEN_MODULES:%=%.erl) + +GEN_TARGET_FILES = $(GEN_MODULES:%=%.$(EMULATOR)) + +SUITE_TARGET_FILES = $(MODULES:%=%.$(EMULATOR)) + +TARGET_FILES = \ + $(GEN_TARGET_FILES) \ + $(SUITE_TARGET_FILES) + +# ---------------------------------------------------- +# PROGRAMS +# ---------------------------------------------------- + +# ---------------------------------------------------- +# Targets +# ---------------------------------------------------- +tests debug opt: + +clean: + rm -f $(TARGET_FILES) + rm -f errs core *~ + +docs: + +# ---------------------------------------------------- +# Special Targets +# ---------------------------------------------------- + + +# ---------------------------------------------------- +# Release Targets +# ---------------------------------------------------- +include $(ERL_TOP)/make/otp_release_targets.mk + +release_spec: + +release_docs_spec: + +release_tests_spec: tests + $(INSTALL_DIR) $(RELSYSDIR) + $(INSTALL_DATA) $(TEST_SPEC_FILE) $(ERL_FILES) $(RELSYSDIR) + @tar cf - *_SUITE_data | (cd $(RELSYSDIR); tar xf -) diff --git a/lib/jinterface/test/jinterface.dynspec b/lib/jinterface/test/jinterface.dynspec new file mode 100644 index 0000000000..44712521df --- /dev/null +++ b/lib/jinterface/test/jinterface.dynspec @@ -0,0 +1,32 @@ +%% -*- erlang -*- +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2006-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% +%% +%% You can test this file using this command. +%% file:script("jinterface.dynspec", [{'Os',"Unix"}]). + +case case code:priv_dir(jinterface) of + {error,bad_name} -> false; + P -> filelib:is_dir(P) end of + true -> + []; + false -> + NoApp = "No jinterface application", + [{skip,{nc_SUITE,NoApp}}, + {skip,{jinterface_SUITE,NoApp}}] +end. diff --git a/lib/jinterface/test/jinterface_SUITE.erl b/lib/jinterface/test/jinterface_SUITE.erl new file mode 100644 index 0000000000..ea097680dd --- /dev/null +++ b/lib/jinterface/test/jinterface_SUITE.erl @@ -0,0 +1,761 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2004-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(jinterface_SUITE). + +-export([all/1, init_per_suite/1, end_per_suite/1, + init_per_testcase/2, end_per_testcase/2]). + +-export([nodename/1, register_and_whereis/1, get_names/1, boolean_atom/1, + node_ping/1, mbox_ping/1, + java_erlang_send_receive/1, + java_internal_send_receive_same_node/1, + java_internal_send_receive_different_nodes/1, + java_internal_send_receive_self/1, + java_link_and_exit/1, erl_link_and_exit/1, + erl_link_java_exit/1, java_link_erl_exit/1, + internal_link_linking_exits/1, internal_link_linked_exits/1, + internal_unlink_linking_exits/1, internal_unlink_linked_exits/1, + normal_exit/1, kill_mbox/1, kill_erl_proc_from_java/1, + kill_mbox_from_erlang/1, erl_exit_with_reason_any_term/1, + java_exit_with_reason_any_term/1, + status_handler_localStatus/1, status_handler_remoteStatus/1, + status_handler_connAttempt/1]). + +-include("test_server.hrl"). +-include("test_server_line.hrl"). + +-define(debug,true). +-ifdef(debug). +-define(dbg(Str,Args), io:format(Str,Args)). +-else. +-define(dbg(Str,Args), ok). +-endif. + +-define(link_test_reason,link_test_reason). + +%% Test cases in MboxSendReceive.java +-define(java_erlang_send_receive,1). +-define(java_internal_send_receive_same_node,2). +-define(java_internal_send_receive_different_nodes,3). +-define(java_internal_send_receive_self,4). + +%% Test cases in MboxLinkUnlink.java +-define(java_link_and_exit, 1). +-define(erl_link_and_exit, 2). +-define(erl_link_java_exit, 3). +-define(java_link_erl_exit, 4). +-define(internal_link_linking_exits, 5). +-define(internal_link_linked_exits, 6). +-define(internal_unlink_linking_exits,7). +-define(internal_unlink_linked_exits,8). +-define(normal_exit,9). +-define(kill_mbox,10). +-define(kill_erl_proc_from_java,11). +-define(kill_mbox_from_erlang,12). +-define(erl_exit_with_reason_any_term,13). +-define(java_exit_with_reason_any_term,14). + + +%% Test cases in NodeStatusHandler.java +-define(status_handler_localStatus,1). +-define(status_handler_remoteStatus,2). +-define(status_handler_connAttempt,3). + +%%%----------------------------------------------------------------- +%%% INIT/END +%%%----------------------------------------------------------------- +all(suite) -> + lists:append([ + fundamental(), + ping(), + send_receive(), + link_unlink(), + status_handler() + ]). + +fundamental() -> + [ + nodename, % Nodename.java + register_and_whereis, % RegisterAndWhereis.java + get_names, % GetNames.java + boolean_atom % BooleanAtom.java + ]. + +ping() -> + [ + %% Implemented in NodePing.java + node_ping, + + %% Implemented in MboxPing.java + mbox_ping + ]. + + +send_receive() -> + [ + %% Implemented in MboxSendReceive.java + java_erlang_send_receive, + java_internal_send_receive_same_node, + java_internal_send_receive_different_nodes, + java_internal_send_receive_self + ]. + +%% Note: +%% +%% The test cases in MboxLinkUnlink.java and in +%% NodePing.java, all uses default cookie, and if there +%% is a problem with having the same default cookie in +%% erlang vs jinterface, e.g because the home directory +%% does not get the same in some cases on Windows +%% - they will all fail. + +link_unlink() -> + [ + %% Implemented in MboxLinkUnlink.java + java_link_and_exit, + erl_link_and_exit, + erl_link_java_exit, + java_link_erl_exit, + internal_link_linking_exits, + internal_link_linked_exits, + internal_unlink_linking_exits, + internal_unlink_linked_exits, + normal_exit, + kill_mbox, + kill_erl_proc_from_java, + kill_mbox_from_erlang, + erl_exit_with_reason_any_term, + java_exit_with_reason_any_term + ]. + +status_handler() -> + [ + %% Implemented in NodeStatusHandler.java + status_handler_localStatus, + status_handler_remoteStatus, + status_handler_connAttempt + ]. + + +init_per_suite(Config) when is_list(Config) -> + jitu:init_all(Config). + +end_per_suite(Config) when is_list(Config) -> + jitu:finish_all(Config). + +init_per_testcase(_Case,Config) -> + Dog = ?t:timetrap({seconds,10}), + [{watch_dog,Dog}|Config]. + +end_per_testcase(_Case,Config) -> + ?t:timetrap_cancel(?config(watch_dog,Config)), + ok. + + +%%%----------------------------------------------------------------- +%%% TEST CASES +%%%----------------------------------------------------------------- +nodename(doc) -> + ["Nodename.java: " + "Test OtpNode.node(), OtpNode.alive() and OtpNode.host()"]; +nodename(suite) -> + []; +nodename(Config) when is_list(Config) -> + [_,Host] = string:tokens(atom_to_list(node()),"@"), + ok = jitu:java(?config(java, Config), + ?config(data_dir, Config), + "Nodename", + [list_to_atom(Host)]). + +%%%----------------------------------------------------------------- +register_and_whereis(doc) -> + ["RegisterAndWhereis.java: " + "Test OtpNode.registerName(...), OtpMbox.registerName(...) and " + "OtpNode.whereis(...)"]; +register_and_whereis(suite) -> + []; +register_and_whereis(Config) when is_list(Config) -> + ok = jitu:java(?config(java, Config), + ?config(data_dir, Config), + "RegisterAndWhereis", + []). + +%%%----------------------------------------------------------------- +get_names(doc) -> + ["GetNames.java: " + "Test OtpNode.getNames()"]; +get_names(suite) -> + []; +get_names(Config) when is_list(Config) -> + ok = jitu:java(?config(java, Config), + ?config(data_dir, Config), + "GetNames", + []). + +%%%----------------------------------------------------------------- +boolean_atom(doc) -> + ["BooleanAtom.java: " + "Test OtpErlangAtom.booleanValue()"]; +boolean_atom(suite) -> + []; +boolean_atom(Config) when is_list(Config) -> + ok = jitu:java(?config(java, Config), + ?config(data_dir, Config), + "BooleanAtom", + []). + +%%%----------------------------------------------------------------- +node_ping(doc) -> + ["NodePing.java: " + "Test OtpNode.ping(java.lang.String node, long timeout)"]; +node_ping(suite) -> + []; +node_ping(Config) when is_list(Config) -> + ok = jitu:java(?config(java, Config), + ?config(data_dir, Config), + "NodePing", + [erlang:get_cookie(),node()]). + +%%%----------------------------------------------------------------- +mbox_ping(doc) -> + ["MboxPing.java: " + "Test OtpNode.createMbox(...) and OtpMbox.ping(...)"]; +mbox_ping(suite) -> + []; +mbox_ping(Config) when is_list(Config) -> + ok = jitu:java(?config(java, Config), + ?config(data_dir, Config), + "MboxPing", + [erlang:get_cookie(),node()]). + +%%%----------------------------------------------------------------- +java_erlang_send_receive(doc) -> + ["Test sending/receiving of erlang messages between erlang and java"]; +java_erlang_send_receive(suite) -> + []; +java_erlang_send_receive(Config) when is_list(Config) -> + send_receive(?java_erlang_send_receive, fun echo_loop/0, Config). + +echo_loop() -> + receive + {From,Msg} -> + ?dbg("erl_send_receive_server received ~p",[{From,Msg}]), + ?dbg("erl_send_receive_server sending ~p",[Msg]), + From ! Msg, + echo_loop(); + done -> + ok + end. + + +%%%----------------------------------------------------------------- +java_internal_send_receive_same_node(doc) -> + ["MboxSendReceive.java: " + "Test sending/receiving of erlang messages between mboxes " + "on the same java node."]; +java_internal_send_receive_same_node(suite) -> + []; +java_internal_send_receive_same_node(Config) when is_list(Config) -> + send_receive(?java_internal_send_receive_same_node, + fun() -> receive done -> ok end end, + Config). + +%%%----------------------------------------------------------------- +java_internal_send_receive_different_nodes(doc) -> + ["MboxSendReceive.java: " + "Test sending/receiving of erlang messages between mboxes " + "on different java nodes."]; +java_internal_send_receive_different_nodes(suite) -> + []; +java_internal_send_receive_different_nodes(Config) when is_list(Config) -> + send_receive(?java_internal_send_receive_different_nodes, + fun() -> receive done -> ok end end, + Config). + +%%%----------------------------------------------------------------- +java_internal_send_receive_self(doc) -> + ["MboxSendReceive.java: " + "Test sending/receiving of erlang messages from an mbox to itself"]; +java_internal_send_receive_self(suite) -> + []; +java_internal_send_receive_self(Config) when is_list(Config) -> + send_receive(?java_internal_send_receive_self, + fun() -> receive done -> ok end end, + Config). + +%%%----------------------------------------------------------------- +java_link_and_exit(doc) -> + ["MboxLinkUnlink.java: " + "Test link between erlang process and java mailbox." + "Java mailbox links and exits"]; +java_link_and_exit(suite) -> + []; +java_link_and_exit(Config) when is_list(Config) -> + LinkFun = + fun(Mbox) -> + Mbox ! {?java_link_and_exit,self(),?link_test_reason}, + receive after infinity -> ok end + end, + erl_java_link(LinkFun,java_link_and_exit,Config). + + +%%%----------------------------------------------------------------- +erl_link_and_exit(doc) -> + ["MboxLinkUnlink.java: " + "Test link between erlang process and java mailbox." + "Erlang process links and exits"]; +erl_link_and_exit(suite) -> + []; +erl_link_and_exit(Config) when is_list(Config) -> + LinkFun = fun(Mbox) -> + link(Mbox), + Mbox ! {?erl_link_and_exit,self(),?link_test_reason}, + receive ok -> ok end, + exit(?link_test_reason) + end, + erl_java_link(LinkFun,erl_link_and_exit,Config). + +%%%----------------------------------------------------------------- +erl_link_java_exit(doc) -> + ["MboxLinkUnlink.java: " + "Test link between erlang process and java mailbox." + "Erlang process links and java mailbox exits"]; +erl_link_java_exit(suite) -> + []; +erl_link_java_exit(Config) when is_list(Config) -> + LinkFun = fun(Mbox) -> + link(Mbox), + Mbox ! {?erl_link_java_exit,self(),?link_test_reason}, + receive after infinity -> ok end + end, + erl_java_link(LinkFun,erl_link_java_exit,Config). + + +%%%----------------------------------------------------------------- +java_link_erl_exit(doc) -> + ["MboxLinkUnlink.java: " + "Test link between erlang process and java mailbox." + "Java mailbox links and erlang process exits"]; +java_link_erl_exit(suite) -> + []; +java_link_erl_exit(Config) when is_list(Config) -> + LinkFun = + fun(Mbox) -> + Mbox ! {?java_link_erl_exit,self(),?link_test_reason}, + receive ok -> ok end, + exit(?link_test_reason) + end, + erl_java_link(LinkFun,java_link_erl_exit,Config). + +%%%----------------------------------------------------------------- +internal_link_linking_exits(doc) -> + ["MboxLinkUnlink.java: " + "Test link between two java mailboxes." + "The mailbox which creates the link is the one exiting"]; +internal_link_linking_exits(suite) -> + []; +internal_link_linking_exits(Config) when is_list(Config) -> + internal_link_unlink(?internal_link_linking_exits, + internal_link_linking_exits, + Config). + +%%%----------------------------------------------------------------- +internal_link_linked_exits(doc) -> + ["MboxLinkUnlink.java: " + "Test link between two java mailboxes." + "The mailbox which dies not create the link is the one exiting"]; +internal_link_linked_exits(suite) -> + []; +internal_link_linked_exits(Config) when is_list(Config) -> + internal_link_unlink(?internal_link_linked_exits, + internal_link_linked_exits, + Config). + +%%%----------------------------------------------------------------- +internal_unlink_linking_exits(doc) -> + ["MboxLinkUnlink.java: " + "Test link and unlink between two java mailboxes. " + "Mailbox1 creates a link to mailbox2 and removes it. " + "Then it creates another link and mailbox2 removes is. " + "Finally mailbox1 exits - mailbox2 must survive"]; +internal_unlink_linking_exits(suite) -> + []; +internal_unlink_linking_exits(Config) when is_list(Config) -> + internal_link_unlink(?internal_unlink_linking_exits, + internal_unlink_linking_exits, + Config). + +%%%----------------------------------------------------------------- +internal_unlink_linked_exits(doc) -> + ["MboxLinkUnlink.java: " + "Test link and unlink between two java mailboxes. " + "Mailbox1 creates a link to mailbox2 and removes it. " + "Then it creates another link and mailbox2 removes is. " + "Finally mailbox2 exits - mailbox1 must survive"]; +internal_unlink_linked_exits(suite) -> + []; +internal_unlink_linked_exits(Config) when is_list(Config) -> + internal_link_unlink(?internal_unlink_linked_exits, + internal_unlink_linked_exits, + Config). + +%%%----------------------------------------------------------------- +normal_exit(doc) -> + ["MboxLinkUnlink.java: " + "Test that mbox.close() uses exit reason 'normal', i.e. " + "that linked processes are not terminated."]; +normal_exit(suite) -> + []; +normal_exit(Config) when is_list(Config) -> + Fun = + fun() -> + register(erl_link_server,self()), + process_flag(trap_exit,true), + receive + {Main,Mbox} when is_pid(Main), is_pid(Mbox) -> + ?dbg("Erlang sending \"~p\"",[normal_exit]), + link(Mbox), + Pid = spawn_link(fun() -> + link(Mbox), + Mbox ! {?normal_exit}, + receive after infinity -> ok end + end), + receive + {'EXIT',Mbox,normal} -> + %% Make sure that we don't get the + %% exit signal from Pid, and Pid + %% should still be alive. + receive + {'EXIT',Pid,Reason} -> + ?dbg("Got unexpected exit signal: ~p", + [{'EXIT',Pid,Reason}]), + exit({unexpected,{'EXIT',Pid,Reason}}) + after 500 -> + true = erlang:is_process_alive(Pid), + exit(Pid,kill) + end, + receive done -> Main ! done end + after 1000 -> + receive + Other -> + ?dbg("Got garbage when waiting for exit:" + " ~p", [Other]), + Main ! done, + exit({got_unexpected,Other}) + after 0 -> + ok + end + end; + Other -> + ?dbg("Got garbage: ~p",[Other]), + exit(Other) + end + end, + + spawn_link(Fun), + ok = jitu:java(?config(java, Config), + ?config(data_dir, Config), + "MboxLinkUnlink", + [erlang:get_cookie(),node()]). + + +%%%----------------------------------------------------------------- +kill_mbox(doc) -> + ["MboxLinkUnlink.java: " + "Test that mbox.exit(new OtpErlangAtom(\"kill\") causes linked " + "processes to exit with reason 'killed', which can be trapped."]; +kill_mbox(suite) -> + {skip, "Not yet implemented"}; +kill_mbox(Config) when is_list(Config) -> + Fun = + fun() -> + register(erl_link_server,self()), + process_flag(trap_exit,true), + receive + {Main,Mbox} when is_pid(Main), is_pid(Mbox) -> + ?dbg("Erlang sending \"~p\"",[kill_mbox]), + Pid = spawn_link(fun() -> + process_flag(trap_exit,true), + link(Mbox), + Mbox ! {?kill_mbox}, + receive + {'EXIT',Mbox,killed} -> + exit(correct_reason); + {'EXIT',Mbox,R} -> + exit({faulty_reason,R}) + end + end), + receive + {'EXIT',Pid,{faulty_reason,Reason}} -> + receive done -> Main ! done end, + exit({faulty_reason,Reason}); + {'EXIT',Pid,im_killed} -> + receive done -> Main ! done end + after 1000 -> + receive + Other -> + ?dbg("Got garbage when waiting for exit:" + " ~p", [Other]), + Main ! done, + exit({got_unexpected,Other}) + after 0 -> + ok + end + end; + Other -> + ?dbg("Got garbage: ~p",[Other]), + exit(Other) + end + end, + + spawn_link(Fun), + ok = jitu:java(?config(java, Config), + ?config(data_dir, Config), + "MboxLinkUnlink", + [erlang:get_cookie(),node()]). + +%%%----------------------------------------------------------------- +kill_erl_proc_from_java(doc) -> + ["MboxLinkUnlink.java: " + "Test that mbox.exit(pid, new OtpErlangAtom(\"kill\") causes erlang " + "processes <pid> to be killed, even if trapping exits"]; +kill_erl_proc_from_java(suite) -> + []; +kill_erl_proc_from_java(Config) when is_list(Config) -> + LinkFun = fun(Mbox) -> + process_flag(trap_exit,true), + link(Mbox), + Mbox ! {?kill_erl_proc_from_java, self()}, + receive after infinity -> ok end + end, + erl_java_link(LinkFun,kill_erl_proc_from_java,killed,Config). + +%%%----------------------------------------------------------------- +kill_mbox_from_erlang(doc) -> + ["MboxLinkUnlink.java: " + "Test that exit(Mbox,kill) causes linked the Mbox to be killed, and" + "linked processes to exit with reason 'killed', even if trapping exits"]; +kill_mbox_from_erlang(suite) -> + {skip, "Not yet implemented"}; +kill_mbox_from_erlang(Config) when is_list(Config) -> + LinkFun = fun(Mbox) -> + link(Mbox), + Mbox ! {?kill_mbox_from_erlang}, + exit(Mbox,kill), + receive after infinity -> ok end + end, + erl_java_link(LinkFun,kill_mbox_from_erlang,killed,Config). + +%%%----------------------------------------------------------------- +erl_exit_with_reason_any_term(doc) -> + ["MboxLinkUnlink.java: " + "Test that any erlang term can be used as exit reason when erlang " + "process exits and is linked to an mbox."]; +erl_exit_with_reason_any_term(suite) -> + []; +erl_exit_with_reason_any_term(Config) when is_list(Config) -> + Reason = [hei,self(),{this,is,"a",[different,"reason"]}], + LinkFun = fun(Mbox) -> + link(Mbox), + Mbox ! {?erl_exit_with_reason_any_term,self(),Reason}, + receive ok -> ok end, + exit(Reason) + end, + erl_java_link(LinkFun,erl_exit_with_reason_any_term,Reason,Config). + +%%%----------------------------------------------------------------- +java_exit_with_reason_any_term(doc) -> + ["MboxLinkUnlink.java: " + "Test that any erlang term can be used as exit reason when mbox " + "exits and is linked to an erlang process."]; +java_exit_with_reason_any_term(suite) -> + []; +java_exit_with_reason_any_term(Config) when is_list(Config) -> + Reason = [hei,self(),{this,is,"a",[different,"reason"]}], + LinkFun = + fun(Mbox) -> + Mbox ! {?java_exit_with_reason_any_term,self(),Reason}, + receive after infinity -> ok end + end, + erl_java_link(LinkFun,java_exit_with_reason_any_term,Reason,Config). + + +%%%----------------------------------------------------------------- +status_handler_localStatus(doc) -> + ["NodeStatusHandler.java: " + "Test OtpNode.registerStatusHandler(...) and the callback " + "OtpNodeStatus.localStatus(...)"]; +status_handler_localStatus(suite) -> + []; +status_handler_localStatus(Config) when is_list(Config) -> + spawn_link(fun() -> + erl_status_server([{opt,{localStatus,"javanode1",true}}, + {localStatus,"javanode1",false}]) + end), + ok = jitu:java(?config(java, Config), + ?config(data_dir, Config), + "NodeStatusHandler", + [erlang:get_cookie(),node(),?status_handler_localStatus]). + +%%%----------------------------------------------------------------- +status_handler_remoteStatus(doc) -> + ["NodeStatusHandler.java: " + "Test OtpNode.registerStatusHandler(...) and the callback " + "OtpNodeStatus.remoteStatus(...)"]; +status_handler_remoteStatus(suite) -> + []; +status_handler_remoteStatus(Config) when is_list(Config) -> + spawn_link(fun() -> + erl_status_server([{opt,{localStatus,"javanode1",true}}, + {remoteStatus,"javanode2",true}, + {remoteStatus,"javanode2",false}]) + end), + ok = jitu:java(?config(java, Config), + ?config(data_dir, Config), + "NodeStatusHandler", + [erlang:get_cookie(),node(),?status_handler_remoteStatus]). + + +%%%----------------------------------------------------------------- +status_handler_connAttempt(doc) -> + ["NodeStatusHandler.java: " + "Test OtpNode.registerStatusHandler(...) and the callback " + "OtpNodeStatus.connAttempt(...)"]; +status_handler_connAttempt(suite) -> + []; +status_handler_connAttempt(Config) when is_list(Config) -> + spawn_link(fun() -> + erl_status_server([{opt,{localStatus,"javanode1",true}}, + {connAttempt,"unknown",true}, + {connAttempt,"javanode3",false}]) + end), + ok = jitu:java(?config(java, Config), + ?config(data_dir, Config), + "NodeStatusHandler", + [erlang:get_cookie(),node(),?status_handler_connAttempt]). + + +%%%----------------------------------------------------------------- +%%% INTERNAL FUNCTIONS +%%%----------------------------------------------------------------- +send_receive(TestCaseTag,Fun,Config) -> + spawn(fun() -> + register(erl_send_receive_server,self()), + receive + From when is_pid(From) -> + JavaNode = node(From), + [JavaNode] = nodes(hidden), + From ! {TestCaseTag,self()}, + Fun(), + unregister(erl_send_receive_server) + end + end), + ok = jitu:java(?config(java, Config), + ?config(data_dir, Config), + "MboxSendReceive", + [erlang:get_cookie(),node()]). + + +internal_link_unlink(Tag,Msg,Config) -> + Fun = + fun() -> + register(erl_link_server,self()), + process_flag(trap_exit,true), + receive + {Main,Mbox} when is_pid(Main), is_pid(Mbox) -> + ?dbg("Erlang sending \"~p\"",[Msg]), + Mbox ! {Tag,self(),?link_test_reason}, + receive done -> Main ! done end; + Other -> + ?dbg("Got garbage: ~p",[Other]), + exit(Other) + end + end, + + spawn_link(Fun), + ok = jitu:java(?config(java, Config), + ?config(data_dir, Config), + "MboxLinkUnlink", + [erlang:get_cookie(),node()]). + + +erl_java_link(LinkFun,Msg,Config) -> + erl_java_link(LinkFun,Msg,?link_test_reason,Config). + +erl_java_link(LinkFun,Msg,Reason,Config) -> + Fun = + fun() -> + register(erl_link_server,self()), + process_flag(trap_exit,true), + receive + {Main,Mbox} when is_pid(Mbox), is_pid(Mbox) -> + ?dbg("Erlang sending \"~p\"",[Msg]), + Pid = spawn_link(fun() -> LinkFun(Mbox) end), + receive + {'EXIT',Pid,Reason} -> + receive done -> Main ! done end + after 1000 -> + receive + Other -> + ?dbg("Got garbage when waiting for exit:" + " ~p", [Other]), + Main ! done, + exit({got_unexpected,Other}) + after 0 -> + ok + end + end; + Other -> + ?dbg("Got garbage: ~p",[Other]), + exit(Other) + end + end, + + spawn_link(Fun), + ok = jitu:java(?config(java, Config), + ?config(data_dir, Config), + "MboxLinkUnlink", + [erlang:get_cookie(),node()]). + +erl_status_server(List) -> + register(erl_status_server,self()), + erl_status_server(List,undefined). +erl_status_server([{opt,{Tag,NodeName,Up}},{Tag2,NodeName2,Up2}|Rest],_) -> + receive + {Tag,Node,Up,From} = M -> + ?dbg("erl_status_server got: ~p",[M]), + true = lists:prefix(NodeName,Node), + erl_status_server([{Tag2,NodeName2,Up2}|Rest],From); + {Tag2,Node2,Up2,From2} = M2 -> + ?dbg("erl_status_server got: ~p",[M2]), + true = lists:prefix(NodeName2,Node2), + erl_status_server(Rest,From2) + end; +erl_status_server([{Tag,NodeName,Up}|Rest],_) -> + receive + {Tag,Node,Up,From} = M -> + ?dbg("erl_status_server got: ~p",[M]), + true = lists:prefix(NodeName,Node), + erl_status_server(Rest,From); + Other -> + ?dbg("erl_status_server got garbage: ~p",[Other]), + exit(Other) + end; +erl_status_server([],From) -> + From ! done. diff --git a/lib/jinterface/test/jinterface_SUITE_data/BooleanAtom.java b/lib/jinterface/test/jinterface_SUITE_data/BooleanAtom.java new file mode 100644 index 0000000000..9554d50c9f --- /dev/null +++ b/lib/jinterface/test/jinterface_SUITE_data/BooleanAtom.java @@ -0,0 +1,46 @@ +/* + * %CopyrightBegin% + * + * Copyright Ericsson AB 2004-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% + */ + +import com.ericsson.otp.erlang.*; + +class BooleanAtom { + + /* + Implements test case jinterface_SUITE:boolean_atom/1 + + Test the function OtpErlangAtom.booleanValue() + */ + + public static void main(String argv[]) { + + OtpErlangAtom atom = new OtpErlangAtom("true"); + if (!atom.booleanValue()) fail(1); + + atom = new OtpErlangAtom("false"); + if (atom.booleanValue()) fail(2); + + atom = new OtpErlangAtom("somethingelse"); + if (atom.booleanValue()) fail(3); + + } + + private static void fail(int reason) { + System.exit(reason); + } +} diff --git a/lib/jinterface/test/jinterface_SUITE_data/GetNames.java b/lib/jinterface/test/jinterface_SUITE_data/GetNames.java new file mode 100644 index 0000000000..3d2bc4ac84 --- /dev/null +++ b/lib/jinterface/test/jinterface_SUITE_data/GetNames.java @@ -0,0 +1,68 @@ +/* + * %CopyrightBegin% + * + * Copyright Ericsson AB 2004-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% + */ + +import java.util.ArrayList; +import com.ericsson.otp.erlang.*; + +class GetNames { + + /* + Implements test case jinterface_SUITE:get_names/1 + + */ + + public static void main(String argv[]) { + + try { + OtpNode node = new OtpNode("javanode"); + OtpMbox mbox1 = node.createMbox(); + mbox1.registerName("mbox1"); + node.createMbox("mbox2"); + OtpMbox mbox3 = node.createMbox(); + node.registerName("mbox3",mbox3); + + ArrayList existing_names = new ArrayList(); + existing_names.add("mbox3"); + existing_names.add("mbox2"); + existing_names.add("mbox1"); + + String[] names = node.getNames(); + if (names.length != existing_names.size()) fail(1); + + for(int i=0; i<names.length; i++) { + System.out.println("" + names[i]); + existing_names.remove(names[i]); + } + + if (!existing_names.isEmpty()) fail(2); + } + catch (Exception e) { + fail("" + e, 3); + } + } + + private static void fail(int reason) { + System.exit(reason); + } + + private static void fail(String str, int reason) { + System.out.println(str); + System.exit(reason); + } +} diff --git a/lib/jinterface/test/jinterface_SUITE_data/Makefile.src b/lib/jinterface/test/jinterface_SUITE_data/Makefile.src new file mode 100644 index 0000000000..2a3dca463b --- /dev/null +++ b/lib/jinterface/test/jinterface_SUITE_data/Makefile.src @@ -0,0 +1,62 @@ +# +# %CopyrightBegin% +# +# Copyright Ericsson AB 2004-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% +# + +# Note: This file *must* work for both Unix and Windows +# +# We use both `rm' (Unix) and `del' (Windows) for removing files, but +# with a `-' in front so that the error in not finding `rm' (`del') on +# Windows (Unix) is ignored. +# +# VxWorks? XXX +# + +.SUFFIXES: +.SUFFIXES: .java + + +JAVAC = @JAVAC@ +ERLC = erlc + +JINTERFACE_CLASSPATH = @jinterface_classpath@ + +CLASSPATH = .@PS@$(JINTERFACE_CLASSPATH)@PS@ + +JAVA_FILES = \ + Nodename.java \ + RegisterAndWhereis.java \ + GetNames.java \ + BooleanAtom.java \ + NodePing.java \ + MboxPing.java \ + MboxSendReceive.java \ + MboxLinkUnlink.java \ + NodeStatusHandler.java + +CLASS_FILES = $(JAVA_FILES:.java=.class) + +all: $(CLASS_FILES) + +clean: + -rm -f $(CLASS_FILES) + -del /F /Q $(CLASS_FILES) + +$(CLASS_FILES) : $(JAVA_FILES) + $(JAVAC) -classpath $(CLASSPATH) $(JAVA_FILES) + +# diff --git a/lib/jinterface/test/jinterface_SUITE_data/MboxLinkUnlink.java b/lib/jinterface/test/jinterface_SUITE_data/MboxLinkUnlink.java new file mode 100644 index 0000000000..5d1d097cc8 --- /dev/null +++ b/lib/jinterface/test/jinterface_SUITE_data/MboxLinkUnlink.java @@ -0,0 +1,201 @@ +/* + * %CopyrightBegin% + * + * Copyright Ericsson AB 2004-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% + */ + +import com.ericsson.otp.erlang.*; + +class MboxLinkUnlink { + + /* + Implements test case jinterface_SUITE:mbox_link_unlink/1 + + + + */ + + private static final int java_link_and_exit = 1; + private static final int erl_link_and_exit = 2; + private static final int erl_link_java_exit = 3; + private static final int java_link_erl_exit = 4; + private static final int internal_link_linking_exits = 5; + private static final int internal_link_linked_exits = 6; + private static final int internal_unlink_linking_exits = 7; + private static final int internal_unlink_linked_exits = 8; + private static final int normal_exit = 9; + private static final int kill_mbox = 10; + private static final int kill_erl_proc_from_java = 11; + private static final int kill_mbox_from_erlang = 12; + private static final int erl_exit_with_reason_any_term = 13; + private static final int java_exit_with_reason_any_term = 14; + + private static boolean dbg = true; + + + public static void main(String argv[]) { + + + //String cookie = argv[0]; + String erlNode = argv[1]; + OtpErlangObject expected = null; + boolean waiting = false; + + try { // + OtpNode node = new OtpNode("javanode"); + OtpMbox mainMbox = node.createMbox(); + + try { + // Initiate and set up connection to erlang process + OtpMbox mbox = node.createMbox(); + OtpMbox mbox2; + + OtpErlangObject[] msg = {mainMbox.self(),mbox.self()}; + mbox.send("erl_link_server", erlNode, new OtpErlangTuple(msg)); + OtpErlangObject o = mbox.receive(1000); + if (o == null) System.exit(1); + OtpErlangTuple tuple = (OtpErlangTuple)o; + int tag = (int)((OtpErlangLong)tuple.elementAt(0)).longValue(); + + switch (tag) { + + case java_exit_with_reason_any_term: + case java_link_and_exit: + dbg("Java got \"java_link_and_exit\" or " + + "\"java_exit_with_reason_any_term\""); + mbox.link((OtpErlangPid)tuple.elementAt(1)); + mbox.send((OtpErlangPid)tuple.elementAt(1), + new OtpErlangAtom("ok")); + mbox.exit(tuple.elementAt(2)); + break; + case erl_exit_with_reason_any_term: + case erl_link_and_exit: + dbg("Java got \"erl_link_and_exit\" or " + + "\"erl_exit_with_reason_any_term\""); + mbox.send((OtpErlangPid)tuple.elementAt(1), + new OtpErlangAtom("ok")); + waiting = true; + expected = tuple.elementAt(2); + mbox.receive(1000); + System.exit(2); + case erl_link_java_exit: + dbg("Java got \"erl_link_java_exit\""); + mbox.exit(tuple.elementAt(2)); + break; + case java_link_erl_exit: + dbg("Java got \"java_link_erl_exit\""); + mbox.link((OtpErlangPid)tuple.elementAt(1)); + mbox.send((OtpErlangPid)tuple.elementAt(1), + new OtpErlangAtom("ok")); + waiting = true; + expected = tuple.elementAt(2); + mbox.receive(1000); + System.exit(3); + case internal_link_linking_exits: + dbg("Java got \"internal_link_linking_exits\""); + mbox2 = node.createMbox(); + mbox.link(mbox2.self()); + mbox.exit(tuple.elementAt(2)); + waiting = true; + expected = tuple.elementAt(2); + mbox2.receive(1000); // hanging waiting for exit + System.exit(4); // got someting other than exit + case internal_link_linked_exits: + dbg("Java got \"internal_link_linked_exits\""); + mbox2 = node.createMbox(); + mbox.link(mbox2.self()); + mbox2.exit(tuple.elementAt(2)); + waiting = true; + expected = tuple.elementAt(2); + mbox.receive(1000); // hanging waiting for exit + System.exit(5); // got someting other than exit + case internal_unlink_linking_exits: + dbg("Java got \"internal_unlink_linking_exits\""); + mbox2 = node.createMbox(); + mbox.link(mbox2.self()); + mbox.unlink(mbox2.self()); + mbox.link(mbox2.self()); + mbox2.unlink(mbox.self()); + mbox2.exit(tuple.elementAt(2)); + if (mbox.receive(500)!=null) System.exit(6); + break; + case internal_unlink_linked_exits: + dbg("Java got \"internal_unlink_linked_exits\""); + mbox2 = node.createMbox(); + mbox.link(mbox2.self()); + mbox.unlink(mbox2.self()); + mbox.link(mbox2.self()); + mbox2.unlink(mbox.self()); + mbox.exit(tuple.elementAt(2)); + if (mbox2.receive(500)!=null) System.exit(7); + break; + case normal_exit: + dbg("Java got \"normal_exit\""); + mbox.close(); + break; + case kill_mbox: + dbg("Java got \"kill_mbox\""); + mbox.exit("kill"); + break; + case kill_erl_proc_from_java: + dbg("Java got \"kill_erl_proc_from_java\""); + mbox.exit((OtpErlangPid)tuple.elementAt(1),"kill"); + break; + case kill_mbox_from_erlang: + dbg("Java got \"kill_mbox_from_erlang\""); + /* This will make the testcase successful, but it is + not the correct way to do it... + Mbox should probably just die when the kill signal is + received from erlang (or other mbox). + + try { + mbox.receive(1000); + System.exit(8); + } + catch (OtpErlangExit exit) { + if(!(exit.reason().equals(new OtpErlangAtom("kill")))) + System.exit(9); + mbox.exit("killed"); + } + */ + break; + } + } + catch (OtpErlangExit exit) { + dbg("Java got exit: " + exit.reason()); + if(!(waiting && exit.reason().equals(expected))) + System.exit(10); + } + + OtpErlangAtom done = new OtpErlangAtom("done"); + mainMbox.send("erl_link_server", erlNode, done); + OtpErlangObject o = mainMbox.receive(1000); + if (o == null) System.exit(11); + else if (!((OtpErlangAtom)o).equals(done)) + System.exit(12); + + } + catch (Exception e) { + System.out.println("EXCEPTION: " + e); + System.exit(13); + } + } + + private static void dbg(String str) { + if (dbg) System.out.println(str); + } + +} diff --git a/lib/jinterface/test/jinterface_SUITE_data/MboxPing.java b/lib/jinterface/test/jinterface_SUITE_data/MboxPing.java new file mode 100644 index 0000000000..3a8497028e --- /dev/null +++ b/lib/jinterface/test/jinterface_SUITE_data/MboxPing.java @@ -0,0 +1,50 @@ +/* + * %CopyrightBegin% + * + * Copyright Ericsson AB 2004-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% + */ + +import com.ericsson.otp.erlang.*; + +class MboxPing { + + /* + Implements test case jinterface_SUITE:mbox_ping/1 + + Creates an OtpNode object with an OtpMbox object. The test_server + node is pinged from the OtpMbox. + */ + + public static void main(String argv[]) { + + try { + OtpNode node = new OtpNode("javanode",argv[0]); + OtpMbox mbox = node.createMbox(); + if (mbox.ping(argv[1],2000)) { + System.out.println("OtpMbox.ping(" + argv[1] + ") -> true"); + } + else { + System.out.println("ERROR: OtpMbox.ping(" + argv[1] + + ") -> false"); + System.exit(1); + } + } + catch (Exception e) { + System.out.println("" + e); + System.exit(2); + } + } +} diff --git a/lib/jinterface/test/jinterface_SUITE_data/MboxSendReceive.java b/lib/jinterface/test/jinterface_SUITE_data/MboxSendReceive.java new file mode 100644 index 0000000000..2db71bb5cd --- /dev/null +++ b/lib/jinterface/test/jinterface_SUITE_data/MboxSendReceive.java @@ -0,0 +1,229 @@ +/* + * %CopyrightBegin% + * + * Copyright Ericsson AB 2004-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% + */ + +import com.ericsson.otp.erlang.*; + +class MboxSendReceive { + + /* + Implements test case jinterface_SUITE:mbox_send_receive/1 + + Test OtpMbox.send(...) and OtpMbox.receive(...) + */ + + private static final boolean dbg = true; + private static final int recTime = 2000; + + private static final int java_erlang_send_receive = 1; + private static final int java_internal_send_receive_same_node = 2; + private static final int java_internal_send_receive_different_nodes = 3; + private static final int java_internal_send_receive_self = 4; + + public static void main(String argv[]) { + + String cookie = argv[0]; + String erlNode = argv[1]; + + OtpErlangObject[] msgArray = new OtpErlangObject[2]; + msgArray[1] = new OtpErlangAtom("hello world"); + OtpErlangTuple msg = null; + + try { + // Initiate: create javanode and mboxes + OtpNode node = new OtpNode("javanode",cookie); + OtpMbox mbox = node.createMbox(); + OtpMbox mbox2 = node.createMbox("java_echo_server2"); + + // Send the pid of mbox to erlang and wait for test case + // instruction: {TestCaseTag, Pid} + mbox.send("erl_send_receive_server", erlNode, mbox.self()); + OtpErlangObject o = mbox.receive(recTime); + if (o == null) System.exit(1); + OtpErlangTuple testCase = (OtpErlangTuple)o; + dbg("mbox received " + testCase); + int tag = (int)((OtpErlangLong)testCase.elementAt(0)).longValue(); + OtpErlangPid erlangPid = (OtpErlangPid)testCase.elementAt(1); + + switch (tag) { + + case java_erlang_send_receive: + + // Test1 (happened during initiation): + // Send mbox pid to erlang process with registered name. + // Erlang process sent back its pid to the mbox pid. + + // Test2: Register name and sent it to the erlang pid. Erlang + // process shall send message back to my registered name. + + mbox.registerName("java_echo_server"); + msgArray[0] = getNameNode("java_echo_server",node); + msg = new OtpErlangTuple(msgArray); + + dbg("java_echo_server sending " + msg); + mbox.send(erlangPid,msg); + + o = mbox.receive(recTime); + dbg("java_echo_server received " + o); + if (o == null) System.exit(2); + if (!((OtpErlangAtom)o).equals(msgArray[1])) System.exit(3); + + // Test3: Same as Test2, but using a new mbox2 which + // got its name already when it is created - i.e. not + // using mbox.registerName + msgArray[0] = getNameNode("java_echo_server2",node); + msg = new OtpErlangTuple(msgArray); + + dbg("java_echo_server2 sending " + msg); + mbox2.send(erlangPid,msg); + + o = mbox2.receive(recTime); + dbg("java_echo_server received " + o); + if (o == null) System.exit(4); + if (!((OtpErlangAtom)o).equals(msgArray[1])) System.exit(5); + + break; + + case java_internal_send_receive_same_node: + + // Test1: Sending message between mboxes on same node + // given registered name and node without host. + mbox.send("java_echo_server2","javanode",msgArray[1]); + o = mbox2.receive(recTime); + dbg("Mbox at same node: " + o); + if (o == null) System.exit(6); + if(!((OtpErlangAtom)o).equals(msgArray[1])) System.exit(7); + + // Test2: Sending message between mboxes on same node + // given registered name and node with host. + mbox.send("java_echo_server2",mbox2.self().node(),msgArray[1]); + o = mbox2.receive(recTime); + dbg("Mbox at same node: " + o); + if (o == null) System.exit(8); + if(!((OtpErlangAtom)o).equals(msgArray[1])) System.exit(9); + + // Test3: Sending message between mboxes on same node + // given registered name but not node. + mbox.send("java_echo_server2",msgArray[1]); + o = mbox2.receive(recTime); + dbg("Mbox at same node: " + o); + if (o == null) System.exit(10); + if(!((OtpErlangAtom)o).equals(msgArray[1])) System.exit(11); + + // Test4: Sending message between mboxes on same node + // given pid. + mbox.send(mbox2.self(),msgArray[1]); + o = mbox2.receive(recTime); + dbg("Mbox at same node: " + o); + if (o == null) System.exit(12); + if(!((OtpErlangAtom)o).equals(msgArray[1])) System.exit(13); + + break; + + case java_internal_send_receive_different_nodes: + + OtpNode node2 = new OtpNode("javanode2", cookie); + OtpMbox mboxOtherNode = node2.createMbox("mboxOtherNode"); + + // Test1: Sending message between mboxes on different + // nodes given registered name and node without host. + mbox.send("mboxOtherNode","javanode2",msgArray[1]); + o = mboxOtherNode.receive(recTime); + dbg("Mbox at same node: " + o); + if (o == null) System.exit(14); + if(!((OtpErlangAtom)o).equals(msgArray[1])) System.exit(15); + + // Test2: Sending message between mboxes on different + // nodes given registered name and node with host. + mbox.send("mboxOtherNode",mboxOtherNode.self().node(), + msgArray[1]); + o = mboxOtherNode.receive(recTime); + dbg("Mbox at same node: " + o); + if (o == null) System.exit(16); + if(!((OtpErlangAtom)o).equals(msgArray[1])) System.exit(17); + + // Test3: Sending message between mboxes on different + // nodes given pid. + mbox.send(mboxOtherNode.self(),msgArray[1]); + o = mboxOtherNode.receive(recTime); + dbg("Mbox at same node: " + o); + if (o == null) System.exit(18); + if(!((OtpErlangAtom)o).equals(msgArray[1])) System.exit(19); + + break; + + + case java_internal_send_receive_self: + + // Test1: Sending message to myself given registered + // name and node without host. + mbox2.send("java_echo_server2","javanode",msgArray[1]); + o = mbox2.receive(recTime); + dbg("Self: " + o); + if (o == null) System.exit(18); + if(!((OtpErlangAtom)o).equals(msgArray[1])) System.exit(19); + + // Test2: Sending message to myself given registered + // name and node with host. + mbox2.send("java_echo_server2",mbox2.self().node(),msgArray[1]); + o = mbox2.receive(recTime); + dbg("Self: " + o); + if (o == null) System.exit(20); + if(!((OtpErlangAtom)o).equals(msgArray[1])) System.exit(21); + + // Test3: Sending message to myself given registered + // name but not host. + mbox2.send("java_echo_server2",msgArray[1]); + o = mbox2.receive(recTime); + dbg("Self: " + o); + if (o == null) System.exit(22); + if(!((OtpErlangAtom)o).equals(msgArray[1])) System.exit(23); + + // Test4: Sending message to myself given pid. + mbox2.send(mbox2.self(),msgArray[1]); + o = mbox2.receive(recTime); + dbg("Self: " + o); + if (o == null) System.exit(24); + if(!((OtpErlangAtom)o).equals(msgArray[1])) System.exit(25); + + break; + + } + + // Closing erl_send_receive_server by sending the atom 'done' to it. + mbox.send(erlangPid,new OtpErlangAtom("done")); + } + catch (Exception e) { + System.out.println("" + e); + System.exit(26); + } + } + + private static OtpErlangTuple getNameNode(String mboxName,OtpNode node) { + OtpErlangObject[] array = {new OtpErlangAtom(mboxName), + new OtpErlangAtom(node.node())}; + return new OtpErlangTuple(array); + + } + + private static void dbg(String str) { + if (dbg) System.out.println(str); + } + + +} diff --git a/lib/jinterface/test/jinterface_SUITE_data/NodePing.java b/lib/jinterface/test/jinterface_SUITE_data/NodePing.java new file mode 100644 index 0000000000..d0df5c46b5 --- /dev/null +++ b/lib/jinterface/test/jinterface_SUITE_data/NodePing.java @@ -0,0 +1,83 @@ +/* + * %CopyrightBegin% + * + * Copyright Ericsson AB 2004-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% + */ + +import com.ericsson.otp.erlang.*; + +class NodePing { + + /* + Implements test case jinterface_SUITE:node_ping/1 + + Creates three OtpNode objects. One with default cookie, one with + specified same cookie as the node running the test case and one + with a faulty cookie. From each OtpNode object the test_server + node is pinged. + + Also the default cookie node pings itself, and the node with the + specified cookie pings the node with default cookie. + */ + + public static void main(String argv[]) { + + String cookie = argv[0]; + String erlNode = argv[1]; + + try { + OtpNode node1 = new OtpNode("javanode1"); + ping(node1,erlNode,"Default cookie:",true,1); + ping(node1,node1.node(),"Self:",true,2); + ping(node1,"javanode1","Self:",true,3); + + OtpNode node2 = new OtpNode("javanode2",cookie); + ping(node2,erlNode,"Specified cookie:",true,4); + ping(node2,"javanode1","Javanode (no host):",true,5); + ping(node2,node1.node(),"Javanode:",true,6); + + OtpNode node3 = new OtpNode("javanode3","faultycookie"); + ping(node3,erlNode,"Faulty cookie:",false,7); + + // Test OtpNode.cookie() and OtpNode.setCookie(cookie) as well + if (!node3.cookie().equals("faultycookie")) + fail("Testing OtpNode.cookie()",8); + String old = node3.setCookie(cookie); + if (!old.equals("faultycookie")) + fail("Checking return of OtpNode.setCookie(cookie)",9); + ping(node3,erlNode,"setCookie:",true,10); + } + catch (Exception e) { + fail("" + e, 11); + } + } + + private static void ping(OtpNode node, String remote, String descr, + boolean expected, int reason) { + if ( node.ping(remote,2000) == expected ) { + System.out.println(descr + " ping(" + remote + ") -> " + expected); + } + else { + fail("ERROR: " + descr + " ping(" + remote +") -> " + !expected, + reason); + } + } + + private static void fail(String str, int reason) { + System.out.println(str); + System.exit(reason); + } +} diff --git a/lib/jinterface/test/jinterface_SUITE_data/NodeStatusHandler.java b/lib/jinterface/test/jinterface_SUITE_data/NodeStatusHandler.java new file mode 100644 index 0000000000..51ea15b5ef --- /dev/null +++ b/lib/jinterface/test/jinterface_SUITE_data/NodeStatusHandler.java @@ -0,0 +1,168 @@ +/* + * %CopyrightBegin% + * + * Copyright Ericsson AB 2004-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% + */ + +import com.ericsson.otp.erlang.*; + +public class NodeStatusHandler extends OtpNodeStatus { + /* + Implements java side of test cases in jinterface_SUITE.erl + + Test OtpNode.registerStatusHandler(...) and class OtpNodeStatus. + */ + + private static final boolean dbg = true; + private static final int recTime = 2000; + + private static String erlNode = null; + private static String cookie = null; + private static OtpMbox mbox = null; + + private static final int status_handler_localStatus = 1; + private static final int status_handler_remoteStatus = 2; + private static final int status_handler_connAttempt = 3; + + public static void main(String argv[]) { + + cookie = argv[0]; + erlNode = argv[1]; + + try { + OtpNode javaNode = new OtpNode("javanode", cookie); + mbox = javaNode.createMbox(); + } + catch (Exception e) { + dbg("EXCEPTION when creating javanode: " + e); + System.exit(1); + } + + try { + OtpNode node1 = new OtpNode("javanode1", cookie); + node1.registerStatusHandler(new NodeStatusHandler()); + + switch (Integer.parseInt(argv[2])) { + + case status_handler_localStatus: + dbg("java running test case \"status_handler_localStatus\""); + + Thread.sleep(200); // Give 'nodeup' message a chance + // before closing + node1.close(); + Thread.sleep(500); + break; + + case status_handler_remoteStatus: + dbg("java running test case \"status_handler_remoteStatus\""); + + OtpNode node2 = new OtpNode("javanode2", cookie); + node2.ping(node1.node(),2000); + node2.close(); + Thread.sleep(500); + break; + + case status_handler_connAttempt: + dbg("java running test case \"status_handler_connAttempt\""); + + OtpNode node3 = new OtpNode("javanode3","othercookie"); + node3.ping(node1.node(),2000); + node1.ping(node3.node(),2000); + break; + + } + + OtpErlangObject o = mbox.receive(recTime); + if (o == null) System.exit(2); + if (! ((OtpErlangAtom)o).atomValue().equals("done")) + System.exit(3); + + } + catch (Exception e) { + dbg("EXCEPTION: " + e); + System.exit(4); + } + + } + + + + public void remoteStatus(String node, boolean up, Object info) { + try { + dbg("Got remoteStatus: " + node + " " + up + " " + info); + OtpErlangObject[] msgArray = new OtpErlangObject[4]; + msgArray[0] = new OtpErlangAtom("remoteStatus"); + msgArray[1] = new OtpErlangString(node); + msgArray[2] = new OtpErlangBoolean(up); + msgArray[3] = mbox.self(); + OtpErlangTuple msg = new OtpErlangTuple(msgArray); + mbox.send("erl_status_server", erlNode, msg); + + } + catch (Exception e) { + dbg("EXCEPTION in remoteStatus: " + e + "\nArgs: " + + node + " " + up + " " + info); + System.exit(5); + } + } + + + public void localStatus(String node, boolean up, Object info) { + try { + dbg("Got localStatus: " + node + " " + up + " " + info); + OtpErlangObject[] msgArray = new OtpErlangObject[4]; + msgArray[0] = new OtpErlangAtom("localStatus"); + msgArray[1] = new OtpErlangString(node); + msgArray[2] = new OtpErlangBoolean(up); + msgArray[3] = mbox.self(); + OtpErlangTuple msg = new OtpErlangTuple(msgArray); + mbox.send("erl_status_server", erlNode, msg); + + } + catch (Exception e) { + dbg("EXCEPTION in localStatus: " + e + "\nArgs: " + + node + " " + up + " " + info); + System.exit(6); + } + } + + + + public void connAttempt(String node, boolean incoming, Object info) { + try { + dbg("Got connAttempt: " + node + " " + incoming + " " + info); + OtpErlangObject[] msgArray = new OtpErlangObject[4]; + msgArray[0] = new OtpErlangAtom("connAttempt"); + msgArray[1] = new OtpErlangString(node); + msgArray[2] = new OtpErlangBoolean(incoming); + msgArray[3] = mbox.self(); + OtpErlangTuple msg = new OtpErlangTuple(msgArray); + mbox.send("erl_status_server", erlNode, msg); + + } + catch (Exception e) { + dbg("EXCEPTION in connAttempt: " + e + "\nArgs: " + + node + " " + incoming + " " + info); + System.exit(7); + } + } + + + private static void dbg(String str) { + if (dbg) System.out.println(str); + } + +} diff --git a/lib/jinterface/test/jinterface_SUITE_data/Nodename.java b/lib/jinterface/test/jinterface_SUITE_data/Nodename.java new file mode 100644 index 0000000000..dc8cb9c49f --- /dev/null +++ b/lib/jinterface/test/jinterface_SUITE_data/Nodename.java @@ -0,0 +1,54 @@ +/* + * %CopyrightBegin% + * + * Copyright Ericsson AB 2004-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% + */ + +import com.ericsson.otp.erlang.*; + +class Nodename { + + /* + Implements test case jinterface_SUITE:nodename/1 + + */ + + public static void main(String argv[]) { + + String host = argv[0]; + + try { + OtpNode node = new OtpNode("javanode"); + System.out.println("Given host: " + host + + " Host: " + node.host() + + " Alive: " + node.alive() + + " Node: " + node.node()); + + if (!node.host().equals(host)) fail(1); + if (!node.alive().equals("javanode")) fail(2); + if (!node.node().equals("javanode@" + host)) fail(3); + } + catch (Exception e) { + System.out.println("" + e); + fail(4); + } + } + + private static void fail(int reason) { + System.exit(reason); + } + +} diff --git a/lib/jinterface/test/jinterface_SUITE_data/RegisterAndWhereis.java b/lib/jinterface/test/jinterface_SUITE_data/RegisterAndWhereis.java new file mode 100644 index 0000000000..9df01981b2 --- /dev/null +++ b/lib/jinterface/test/jinterface_SUITE_data/RegisterAndWhereis.java @@ -0,0 +1,79 @@ +/* + * %CopyrightBegin% + * + * Copyright Ericsson AB 2004-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% + */ + +import com.ericsson.otp.erlang.*; + +class RegisterAndWhereis { + + /* + Implements test case jinterface_SUITE:register_and_whereis/1 + + */ + + public static void main(String argv[]) { + + try { + OtpNode node = new OtpNode("javanode"); + OtpMbox mbox1 = node.createMbox(); + mbox1.registerName("mbox1"); + OtpMbox mbox2 = node.createMbox("mbox2"); + OtpMbox mbox3 = node.createMbox(); + node.registerName("mbox3",mbox3); + + OtpErlangPid pid1 = mbox1.self(); + OtpErlangPid pid2 = mbox2.self(); + OtpErlangPid pid3 = mbox3.self(); + + if (!pid1.equals(node.whereis("mbox1"))) fail(1); + if (!pid1.equals(mbox1.whereis("mbox1"))) fail(2); + if (!pid1.equals(mbox2.whereis("mbox1"))) fail(3); + if (!pid1.equals(mbox3.whereis("mbox1"))) fail(4); + if (!pid2.equals(node.whereis("mbox2"))) fail(5); + if (!pid2.equals(mbox2.whereis("mbox2"))) fail(6); + if (!pid3.equals(node.whereis("mbox3"))) fail(7); + if (!pid3.equals(mbox3.whereis("mbox3"))) fail(8); + + node.closeMbox(mbox1); + mbox2.close(); + + if (node.whereis("mbox1") != null) fail(9); + if (node.whereis("mbox2") != null) fail(10); + if (mbox3.whereis("mbox1") != null) fail(11); + if (mbox3.whereis("mbox2") != null) fail(12); + + mbox3.close(); + if (mbox2.whereis("mbox3") != null) fail(13); + + + + } + catch (Exception e) { + fail("" + e, 14); + } + } + + private static void fail(int reason) { + System.exit(reason); + } + + private static void fail(String str, int reason) { + System.out.println(str); + System.exit(reason); + } +} diff --git a/lib/jinterface/test/jitu.erl b/lib/jinterface/test/jitu.erl new file mode 100644 index 0000000000..c57fb9bfad --- /dev/null +++ b/lib/jinterface/test/jitu.erl @@ -0,0 +1,156 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2004-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% +%% + +%%---------------------------------------------------------------------- +%% JInterface Test Utils +%%---------------------------------------------------------------------- +-module(jitu). + + +-export([java/3, + java/4, + java/5, + init_all/1, + finish_all/1]). + +%% +%% Lots of stuff here are originating from java_client_erl_server_SUITE.erl +%% (ic) ... +%% + + + +java(Java, Dir, ClassAndArgs) -> + cmd(Java++" -classpath "++classpath(Dir)++" "++ClassAndArgs). + +java(Java, Dir, Class, Args) -> + java(Java, Dir, Class++" "++to_string(Args)). + +java(Java, Dir, Class, Args, Props) -> + java(Java, Dir, Props++" "++Class, Args). + + + + +init_all(Config) when list(Config) -> + case find_executable(["java"]) of + false -> {skip,"Found no Java VM"}; + Path -> [{java,Path}|Config] + end. + +finish_all(Config) -> Config. + +%% +%% Internal stuff... +%% + + +find_executable([]) -> + false; +find_executable([E|T]) -> + case os:find_executable(E) of + false -> find_executable(T); + Path -> Path + end. + +to_string([H|T]) when integer(H) -> + integer_to_list(H)++" "++to_string(T); +to_string([H|T]) when atom(H) -> + atom_to_list(H)++" "++to_string(T); +to_string([H|T]) when pid(H) -> + pid_to_list(H)++" "++to_string(T); +to_string([H|T]) when list(H) -> + lists:flatten(H)++" "++to_string(T); +to_string([]) -> []. + +% javac(Dir, File) -> +% cmd("javac -d "++Dir++" -classpath "++classpath(Dir)++" "++ +% filename:join(Dir, File)). + +classpath(Dir) -> + PS = + case os:type() of + {win32, _} -> ";"; + _ -> ":" + end, + Dir++PS++ + filename:join([code:lib_dir(jinterface),"priv","OtpErlang.jar"])++PS++ + case os:getenv("CLASSPATH") of + false -> ""; + Classpath -> Classpath + end. + + +cmd(Cmd) -> + PortOpts = [{line,80},eof,exit_status,stderr_to_stdout], + io:format("cmd: ~s~n", [Cmd]), + case catch open_port({spawn,Cmd}, PortOpts) of + Port when port(Port) -> + Result = cmd_loop(Port, []), + io:format("cmd res: ~w~n", [Result]), + case Result of + 0 -> ok; + ExitCode when integer(ExitCode) -> {error,ExitCode}; + Error -> Error + end; + {'EXIT',Reason} -> + {error,Reason} + end. + +cmd_loop(Port, Line) -> + receive + {Port,eof} -> + receive + {Port,{exit_status,ExitStatus}} -> + ExitStatus + after 1 -> + undefined + end; + {Port,{exit_status,ExitStatus}} -> + receive + {Port,eof} -> + ok after 1 -> ok end, + ExitStatus; + {Port,{data,{Tag,Data}}} -> + case Tag of + eol -> + io:put_chars([Line|cr_to_nl(Data)]), + io:nl(), + cmd_loop(Port, []); + noeol -> + cmd_loop(Port, [Line|cr_to_nl(Data)]) + end; + {'EXIT',Port,Reason} -> + {error,Reason}; + Other -> + io:format("WARNING: Unexpected at ~s:~p: ~p~n", + [?MODULE_STRING,?LINE,Other]), + cmd_loop(Port, Line) + end. + +%% Convert lonely CR to NL, and CRLF to NL +%% +cr_to_nl([$\r,$\n|T]) -> + [$\n|cr_to_nl(T)]; +cr_to_nl([$\r|T]) -> + [$\n|cr_to_nl(T)]; +cr_to_nl([C|T]) -> + [C|cr_to_nl(T)]; +cr_to_nl([]) -> + []. diff --git a/lib/jinterface/test/nc_SUITE.erl b/lib/jinterface/test/nc_SUITE.erl new file mode 100644 index 0000000000..82dd3c2535 --- /dev/null +++ b/lib/jinterface/test/nc_SUITE.erl @@ -0,0 +1,736 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2004-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(nc_SUITE). + + +-include("test_server.hrl"). +-include("test_server_line.hrl"). + + +-export([all/1, + init_per_suite/1, + end_per_suite/1, + init_per_testcase/2, + end_per_testcase/2]). + +-export([pid_roundtrip/1, + port_roundtrip/1, + ref_roundtrip/1, + new_float/1, + old_stuff/1, + binary_roundtrip/1, + decompress_roundtrip/1, + compress_roundtrip/1, + integer_roundtrip/1, + fun_roundtrip/1, + lists_roundtrip/1, + lists_roundtrip_2/1, + lists_iterator/1, + unicode/1, + unicode_list_to_string/1, + unicode_string_to_list/1, + connect/1]). + + +%% Top of cases + +all(doc) -> []; +all(suite) -> [pid_roundtrip, + port_roundtrip, + ref_roundtrip, + new_float, + old_stuff, + binary_roundtrip, + decompress_roundtrip, + compress_roundtrip, + integer_roundtrip, + fun_roundtrip, + lists_roundtrip, + lists_roundtrip_2, + lists_iterator, + unicode, + unicode_list_to_string, + unicode_string_to_list, + connect]. + + + + +init_per_suite(Config) when is_list(Config) -> + jitu:init_all(Config). + +end_per_suite(Config) -> + jitu:finish_all(Config). + + + +%% Add/remove watchdog before/after each test case. +%% +init_per_testcase(Case, Config) -> + T = case atom_to_list(Case) of + "unicode"++_ -> 240; + _ -> 20 + end, + WatchDog = test_server:timetrap(test_server:seconds(T)), + [{watchdog, WatchDog}| Config]. + +end_per_testcase(_Case, Config) -> + WatchDog = ?config(watchdog, Config), + test_server:timetrap_cancel(WatchDog). + + +%% +%% Test cases +%% + +pid_roundtrip(doc) -> []; +pid_roundtrip(suite) -> []; +pid_roundtrip(Config) when is_list(Config)-> + ThisNode = {node(), erlang:system_info(creation)}, + RemNode = {gurka@sallad, 2}, + do_echo([self(), + mk_pid(ThisNode, 4711, 4711), + mk_pid(ThisNode, 32767, 8191), + mk_pid(RemNode, 4711, 4711), + mk_pid(RemNode, 32767, 8191)], + Config). + +fun_roundtrip(doc) -> []; +fun_roundtrip(suite) -> []; +fun_roundtrip(Config) when is_list(Config)-> + do_echo([fun(A, B) -> A + B end, + fun(A) -> lists:reverse(A) end, + fun() -> ok end, + fun fun_roundtrip/1], + Config). + +port_roundtrip(doc) -> []; +port_roundtrip(suite) -> []; +port_roundtrip(Config) when is_list(Config)-> + ThisNode = {node(), erlang:system_info(creation)}, + RemNode = {gurka@sallad, 2}, + do_echo([hd(erlang:ports()), + mk_port(ThisNode, 4711), + mk_port(ThisNode, 268435455), + mk_port(RemNode, 4711), + mk_port(RemNode, 268435455)], + Config). + +ref_roundtrip(doc) -> []; +ref_roundtrip(suite) -> []; +ref_roundtrip(Config) when is_list(Config)-> + ThisNode = {node(), erlang:system_info(creation)}, + RemNode = {gurka@sallad, 2}, + do_echo([make_ref(), + mk_ref(ThisNode, [4711]), + mk_ref(ThisNode, [4711, 4711, 4711]), + mk_ref(ThisNode, [262143, 4294967295, 4294967295]), + mk_ref(RemNode, [4711]), + mk_ref(RemNode, [4711, 4711, 4711]), + mk_ref(RemNode, [262143, 4294967295, 4294967295])], + Config). + +new_float(doc) -> []; +new_float(suite) -> []; +new_float(Config) when is_list(Config)-> + Two16 = float(1 bsl 16), + X = math:sqrt(2), + Floats = lists:reverse(seq(1/X, 63, fun(Y) -> Y / Two16 end), + [0.0|seq(X, 63, fun(Y) -> Y * Two16 end)]), + io:format("~w", [Floats]), + do_echo(Floats, Config). + +old_stuff(doc) -> []; +old_stuff(suite) -> []; +old_stuff(Config) when is_list(Config)-> + Terms = [0.0,math:sqrt(2)], + OutTrans = + fun (D) -> + {self(),term_to_binary(D, [{minor_version,0}]),binary} + end, + InTrans = + fun (Echoer, D, {Echoer,D,binary}) -> + ok + end, + do_echo(Terms, Config, OutTrans, InTrans). + +binary_roundtrip(doc) -> []; +binary_roundtrip(suite) -> []; +binary_roundtrip(Config) when is_list(Config) -> + do_echo([<<17>>, + <<1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17>>, + <<3:2>>, + <<3,7:3>>, + <<>>], + Config). + +decompress_roundtrip(doc) -> []; +decompress_roundtrip(suite) -> []; +decompress_roundtrip(Config) when is_list(Config) -> + Terms = + [0.0, + math:sqrt(2), + <<1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,31:5>>, + make_ref()], + OutTrans = + fun (D) -> + {self(),term_to_binary(D, [compressed]),binary} + end, + InTrans = + fun (Echoer, D, {Echoer,D,binary}) -> + ok + end, + do_echo(Terms, Config, OutTrans, InTrans). + +compress_roundtrip(doc) -> []; +compress_roundtrip(suite) -> []; +compress_roundtrip(Config) when is_list(Config) -> + Terms = + [0.0, + math:sqrt(2), + <<1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,31:5>>, + make_ref()], + OutTrans = + fun (D) -> + {self(),D,compress} + end, + InTrans = + fun (Echoer, D, {Echoer,B,compress}) -> + D = binary_to_term(B) + end, + do_echo(Terms, Config, OutTrans, InTrans). + + + +integer_roundtrip(doc) -> []; +integer_roundtrip(suite) -> []; +integer_roundtrip(Config) when is_list(Config) -> + Xs = [1 bsl X || X <- [26,27,28,29,30,31,32,33, + 62,63,64,65, + 126,127,128,129]], + Terms = [0,1,-1,-2] + ++lists:flatmap(fun (X) -> [X-2,X-1,X,-X+1,-X,-X-1] end, + Xs), + io:format("~w", [Terms]), + OutTrans = + fun (V) -> + {self(),V,bigint} + end, + InTrans = + fun (Echoer, V, {Echoer,{V,W,X,L,U},bigint}) -> + Bitlength = bitlength(V), + {w,W} = {w,signum(V) * Bitlength}, + Y = V band 16#FFFFffffFFFFffff, + {y,Y} = {y,X band 16#FFFFffffFFFFffff}, + {l,L} = {l,if V =:= X, Bitlength < 64 -> 1; + true -> 0 end}, + {u,U} = {u,if V =:= Y, V >= 0, Bitlength =< 64 -> 1; + true -> 0 end} + end, + do_echo(Terms, Config, OutTrans, InTrans). + +signum(V) when is_integer(V), V > 0 -> 1; +signum(V) when is_integer(V), V < 0 -> -1; +signum(0) -> 0. + +bitlength(0) -> + 0; +bitlength(-1) -> + 0; +bitlength(V) when is_integer(V) -> + 1 + bitlength(V bsr 1). + + + +lists_roundtrip(doc) -> []; +lists_roundtrip(suite) -> []; +lists_roundtrip(Config) when is_list(Config) -> + Ls = [lists:seq(1,10), + lists:seq(11,17)++last_tail, + [{default}], + [car|cdr], + [[]], + []], + do_echo(Ls, Config). + + + +lists_roundtrip_2(doc) -> []; +lists_roundtrip_2(suite) -> []; +lists_roundtrip_2(Config) when is_list(Config) -> + Ls = [{[a,b],tail}, + {[c,d,e],tail}, + {[],tail}, + {[f],tail}, + {[g,h|i],tail}, + {[j,k,l|m],tail}, + {[n|o],tail}, + {[z,1,2,3,4],tail3}, + {[z,5,6,7],tail3}, + {[z,8,9],tail3}, + {[z,10],tail3}, + {[],tail3}, + {[z,11,12,13,14|15],tail3}, + {[z,16,17,18|19],tail3}, + {[z,20,21|22],tail3}, + {[z,23|24],tail3}, + {[z|25],tail3}, + {"abc123",sub3atom}, + {"abc",sub3atom} + ], + Trans = + fun ([_|T], tail) -> + T; + (L, tail) when is_list(L) -> + null; + ([_,_,_|T], tail3) -> + T; + (L, tail3) when is_list(L) -> + null; + ([_,_,_|L], sub3atom) -> + list_to_atom(L) + end, + OutTrans = + fun ({L,Twist}) -> + {self(),L,Twist} + end, + InTrans = + fun (Echoer, {L,Twist}, {Echoer,X,Twist}) -> + Y = Trans(L, Twist), + io:format("## ~w ~w ~w ~w~n", [L,Twist,X,Y]), + X = Y + end, + do_echo(Ls, Config, OutTrans, InTrans). + + + + +lists_iterator(doc) -> []; +lists_iterator(suite) -> []; +lists_iterator(Config) when is_list(Config) -> + Ls = [["able ","was ","I ","ere ","I ","saw ","elba"]], + do_echo(Ls, Config, + fun (L) -> {self(),L,strcat} end, + fun (Echoer, L, {Echoer,X,strcat}) -> + io:format("## ~p ~p~n", [L,X]), + X = lists:flatten(L) + end). + + + +unicode(doc) -> []; +unicode(suite) -> []; +unicode(Config) when is_list(Config) -> + S1 = "plain ascii", + S2 = "iso-latin ��� �", + S3 = "Codepoints... ��� \x{1000}", + S4 = [0,1,31,32,63,64,127,128,255], + S5 = [0,1,127,128,255,256,16#d7ff, + 16#e000,16#fffd,16#10000,16#10ffff], + Ss = [S1,S2,S3,S4,S5], + do_echo(unicode_cp_gen([{S,valid} || S <- Ss] ++ cp_gen(71)), Config, + fun ({L,invalid}) -> {self(),L,utf8}; + ({L,Tag}) -> {self(),L,Tag}; + ({L}) -> {self(),L} + end, + fun (Echoer, {L,invalid}=Out, {Echoer,X,utf8}=In) -> + case L of + X -> ok; + _ -> + ?t:fail({mismatch,Out,In}) + end; + (Echoer, {L,Tag}=Out, {Echoer,X,Tag}=In) -> + case unicode:characters_to_binary(L, utf8) of + X -> ok; + _ -> + ?t:fail({mismatch,Out,In}) + end; + (Echoer, {L}=Out, {Echoer,X}=In) -> + case L of + X -> ok; + _ -> + ?t:fail({mismatch,Out,In}) + end + end, ["unicode"]). + +%% Lazy wrapper to lazy list +unicode_cp_gen([{S,valid}|Ss]) -> + [{S,utf8},{S}|unicode_cp_gen(Ss)]; +unicode_cp_gen([{S,invalid}=St|Ss]) -> + [St,{S}|unicode_cp_gen(Ss)]; +unicode_cp_gen([]) -> + []; +unicode_cp_gen(Cont) when is_function(Cont, 0) -> + fun () -> + unicode_cp_gen(Cont()) + end. + + + +unicode_list_to_string(doc) -> []; +unicode_list_to_string(suite) -> []; +unicode_list_to_string(Config) when is_list(Config) -> + do_echo(cp_gen(73), Config, + fun ({L,_}) -> {self(),L,to_string_neg_int_list} end, + fun (Echoer, {L,invalid}=Out, {Echoer,X,_}=In) -> + case L of + X -> ok; + _ -> + ?t:fail({mismatch,Out,In}) + end; + (Echoer, {L,valid}=Out, {Echoer,X,_}=In) -> + B = unicode:characters_to_binary(L, unicode, {utf16,big}), + case [-D || <<D:16/big>> <= B] of + X -> ok; + _ -> + ?t:fail({mismatch,Out,In}) + end + end). + + + +unicode_string_to_list(doc) -> []; +unicode_string_to_list(suite) -> []; +unicode_string_to_list(Config) when is_list(Config) -> + do_echo(cp_gen(79), Config, + fun ({L,_}) -> {self(),L,to_neg_int_list} end, + fun (Echoer, {L,invalid}=Out, {Echoer,X,_}=In) -> + case L of + X -> ok; + _ -> + ?t:fail({mismatch,Out,In}) + end; + (Echoer, {L,valid}=Out, {Echoer,X,_}=In) -> + case [-C || C <- L] of + X -> ok; + _ -> + ?t:fail({mismatch,Out,In}) + end + end, ["unicode"]). + + +%% Lazy list +cp_gen(N) -> + cp_gen(N, -1, 16#110000). + +cp_gen(N, Start, End) -> + cp_gen(N, Start, End, cp_validity(Start), [], 0, [], 0). + +cp_gen(N, U, End, PrevValidity, Acc, Len, Ss, Ls) when Len >= N -> + cp_gen(N, U, End, PrevValidity, [], 0, [{Acc,PrevValidity}|Ss], Ls+1); +cp_gen(N, U, End, PrevValidity, Acc, Len, Ss, Ls) when Ls >= N -> + Ss ++ fun () -> + cp_gen(N, U, End, PrevValidity, Acc, Len, [], 0) + end; +cp_gen(_, U, End, _, Acc, _, Ss, _) when U > End -> + [{Acc,valid}|Ss]; +cp_gen(N, U, End, PrevValidity, Acc, Len, Ss, Ls) -> + Validity = cp_validity(U), + NextU = U+1, + {NextAcc,NextLen} = case Validity of + valid -> {[U|Acc],Len+1}; + invalid -> {Acc,Len} + end, + {NextSs,NextLs} = case Validity of + PrevValidity -> {Ss,Ls}; + valid -> {[{[U-1],PrevValidity}|Ss],Ls+1}; + invalid -> {[{[U],Validity}|Ss],Ls+1} + end, + cp_gen(N, NextU, End, Validity, NextAcc, NextLen, NextSs, NextLs). + +cp_validity(UnicodeCP) -> + try <<UnicodeCP/big-utf32>> of + _ -> valid + catch + error:_ -> invalid + end. + + + +connect(doc) -> []; +connect(suite) -> []; +connect(Config) when is_list(Config) -> + WD = filename:dirname(code:which(?MODULE)), + {ok,Other} = ?t:start_node(make_name(), slave, [{args,"-pa "++WD}]), + Action = + fun (Pid) -> + JName = node(Pid), + Hidden = [JName], + Pid ! {self(),Other}, + receive + {Pid,Other,true} -> + ok; + Unexpected1 -> + ?t:fail({result,Unexpected1}) + end, + Hidden = erlang:nodes(hidden), + Hidden = rpc:call(Other, erlang, nodes, [hidden]), + true = + rpc:call(Other, erlang, disconnect_node, [JName]), + [] = + rpc:call(Other, erlang, nodes, [hidden]), + Hidden = erlang:nodes(hidden), + %% Again + receive after 2000 -> ok end, + %% We have no way of knowing when the Java node + %% detects the nodedown. + Pid ! {self(),Other}, + receive + {Pid,Other,true} -> + ok; + Unexpected2-> + ?t:fail({result,Unexpected2}) + end, + Hidden = rpc:call(Other, erlang, nodes, [hidden]) + end, + run_server(connection_server, Config, Action, []). + + + +seq(_, 0, _) -> + []; +seq(X, N, Fun) -> + [X|seq(Fun(X), N-1, Fun)]. + +do_echo(DataList, Config) -> + do_echo(DataList, Config, + fun (D) -> % OutTrans + {self(),D} + end, + fun (Echoer, D, {Echoer,D}) -> % InTrans + ok + end, []). + +do_echo(DataList, Config, OutTrans, InTrans) -> + do_echo(DataList, Config, OutTrans, InTrans, []). + +do_echo(DataList, Config, OutTrans, InTrans, ExtraArgs) + when is_list(DataList), is_list(Config) -> + run_server(echo_server, Config, + fun (Echoer) -> + echo_loop(DataList, Echoer, OutTrans, InTrans, []) + end, + ExtraArgs). + +echo_loop([D|Ds], Echoer, OutTrans, InTrans, TermAcc) -> + OutMsg = OutTrans(D), + Echoer ! OutMsg, + io:format("echo_server ~p: ~p ! ~P~n", [self(),Echoer,OutMsg,10]), + receive + Reply -> + io:format("echo_server ~p: receive ~P~n", + [self(),Reply,10]), + InTrans(Echoer, D, Reply) + end, + Term = case OutMsg of + {_, T, _} -> T; + {_, T} -> T + end, + echo_loop(Ds, Echoer, OutTrans, InTrans, [Term | TermAcc]); +echo_loop([], Echoer, _, _, TermAcc) -> + check_terms(Echoer, TermAcc); +%% Lazy list +echo_loop(Cont, Echoer, OutTrans, InTrans, TermAcc) + when is_function(Cont, 0) -> + check_terms(Echoer, TermAcc), + OutMsg = Echoer ! {self(),undefined,hash_clear}, + io:format("echo_server ~p: ~p ! ~P~n", [self(),Echoer,OutMsg,10]), + receive + {Echoer,hash_cleared,hash_clear}=Reply -> + io:format("echo_server ~p: receive ~P~n", + [self(),Reply,10]), + ok; + Other -> + io:format("echo_server_terms unexpected ~p: receive ~P~n", + [self(),Other,10]), + ?t:fail({unexpected, Other}) + end, + echo_loop(Cont(), Echoer, OutTrans, InTrans, []). + +check_terms(Echoer, [Term | Rest]) -> + OutMsg = {self(),Term,hash_lookup}, + Echoer ! OutMsg, + io:format("check_terms ~p: ~p ! ~P~n", [self(),Echoer,OutMsg,10]), + receive + {Echoer,true,hash_lookup} = ReplyMsg -> + io:format("check_terms ~p: receive ~P~n", + [self(),ReplyMsg,10]), + check_terms(Echoer, Rest); + Other -> + io:format("check_terms unexpected ~p: receive ~P~n", + [self(),Other,10]), + ?t:fail({unexpected, Other}) + end; +check_terms(_, []) -> + ok. + +run_server(Server, Config, Action, ExtraArgs) -> + Name = make_name(), + true = register(Name, self()), + JName = make_name(), + spawn_link(fun () -> + ok = jitu:java(?config(java, Config), + ?config(data_dir, Config), + atom_to_list(Server), + [JName, + erlang:get_cookie(), + node(), + Name]++ExtraArgs + ), + %,"-DOtpConnection.trace=3"), + Name ! {done, JName} + end), + receive + {Server, JName, Pid} -> + ?t:format("~w: ~p (~p)~n", + [Server, Pid, node(Pid)]), + ?t:format("nodes(hidden): ~p~n", + [nodes(hidden)]), + Action(Pid), + Pid ! bye, + receive + {done, JName} -> + ok + end; + Other -> + ?t:fail({unexpected,Other}) + end. + +%% +%% Utils... +%% + +make_name() -> + {A, B, C} = now(), + list_to_atom(atom_to_list(?MODULE) + ++ "-" ++ integer_to_list(A) + ++ "-" ++ integer_to_list(B) + ++ "-" ++ integer_to_list(C)). + + + +-define(VERSION_MAGIC, 131). + +-define(ATOM_EXT, 100). +-define(REFERENCE_EXT, 101). +-define(PORT_EXT, 102). +-define(PID_EXT, 103). +-define(NEW_REFERENCE_EXT, 114). + +uint32_be(Uint) when is_integer(Uint), 0 =< Uint, Uint < 1 bsl 32 -> + [(Uint bsr 24) band 16#ff, + (Uint bsr 16) band 16#ff, + (Uint bsr 8) band 16#ff, + Uint band 16#ff]; +uint32_be(Uint) -> + exit({badarg, uint32_be, [Uint]}). + + +uint16_be(Uint) when is_integer(Uint), 0 =< Uint, Uint < 1 bsl 16 -> + [(Uint bsr 8) band 16#ff, + Uint band 16#ff]; +uint16_be(Uint) -> + exit({badarg, uint16_be, [Uint]}). + +uint8(Uint) when is_integer(Uint), 0 =< Uint, Uint < 1 bsl 8 -> + Uint band 16#ff; +uint8(Uint) -> + exit({badarg, uint8, [Uint]}). + + + +mk_pid({NodeName, Creation}, Number, Serial) when is_atom(NodeName) -> + mk_pid({atom_to_list(NodeName), Creation}, Number, Serial); +mk_pid({NodeName, Creation}, Number, Serial) -> + case catch binary_to_term(list_to_binary([?VERSION_MAGIC, + ?PID_EXT, + ?ATOM_EXT, + uint16_be(length(NodeName)), + NodeName, + uint32_be(Number), + uint32_be(Serial), + uint8(Creation)])) of + Pid when is_pid(Pid) -> + Pid; + {'EXIT', {badarg, _}} -> + exit({badarg, mk_pid, [{NodeName, Creation}, Number, Serial]}); + Other -> + exit({unexpected_binary_to_term_result, Other}) + end. + +mk_port({NodeName, Creation}, Number) when is_atom(NodeName) -> + mk_port({atom_to_list(NodeName), Creation}, Number); +mk_port({NodeName, Creation}, Number) -> + case catch binary_to_term(list_to_binary([?VERSION_MAGIC, + ?PORT_EXT, + ?ATOM_EXT, + uint16_be(length(NodeName)), + NodeName, + uint32_be(Number), + uint8(Creation)])) of + Port when is_port(Port) -> + Port; + {'EXIT', {badarg, _}} -> + exit({badarg, mk_port, [{NodeName, Creation}, Number]}); + Other -> + exit({unexpected_binary_to_term_result, Other}) + end. + +mk_ref({NodeName, Creation}, Numbers) when is_atom(NodeName), + is_integer(Creation), + is_list(Numbers) -> + mk_ref({atom_to_list(NodeName), Creation}, Numbers); +mk_ref({NodeName, Creation}, [Number]) when is_list(NodeName), + is_integer(Creation), + is_integer(Number) -> + case catch binary_to_term(list_to_binary([?VERSION_MAGIC, + ?REFERENCE_EXT, + ?ATOM_EXT, + uint16_be(length(NodeName)), + NodeName, + uint32_be(Number), + uint8(Creation)])) of + Ref when is_reference(Ref) -> + Ref; + {'EXIT', {badarg, _}} -> + exit({badarg, mk_ref, [{NodeName, Creation}, [Number]]}); + Other -> + exit({unexpected_binary_to_term_result, Other}) + end; +mk_ref({NodeName, Creation}, Numbers) when is_list(NodeName), + is_integer(Creation), + is_list(Numbers) -> + case catch binary_to_term(list_to_binary([?VERSION_MAGIC, + ?NEW_REFERENCE_EXT, + uint16_be(length(Numbers)), + ?ATOM_EXT, + uint16_be(length(NodeName)), + NodeName, + uint8(Creation), + lists:map(fun (N) -> + uint32_be(N) + end, + Numbers)])) of + Ref when is_reference(Ref) -> + Ref; + {'EXIT', {badarg, _}} -> + exit({badarg, mk_ref, [{NodeName, Creation}, Numbers]}); + Other -> + exit({unexpected_binary_to_term_result, Other}) + end. diff --git a/lib/jinterface/test/nc_SUITE_data/Makefile.src b/lib/jinterface/test/nc_SUITE_data/Makefile.src new file mode 100644 index 0000000000..3d131250be --- /dev/null +++ b/lib/jinterface/test/nc_SUITE_data/Makefile.src @@ -0,0 +1,53 @@ +# +# %CopyrightBegin% +# +# Copyright Ericsson AB 2004-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% +# + +# Makefile.src for java_client_erl_server test +# Note: This file *must* work for both Unix and Windows +# +# We use both `rm' (Unix) and `del' (Windows) for removing files, but +# with a `-' in front so that the error in not finding `rm' (`del') on +# Windows (Unix) is ignored. +# +# VxWorks? XXX +# + +.SUFFIXES: +.SUFFIXES: .java + + +JAVAC = @JAVAC@ +ERLC = erlc + +JINTERFACE_CLASSPATH = @jinterface_classpath@ + +CLASSPATH = .@PS@$(JINTERFACE_CLASSPATH)@PS@ + +JAVA_FILES = echo_server.java connection_server.java +CLASS_FILES = $(JAVA_FILES:.java=.class) + +all: $(CLASS_FILES) + +clean: + -rm -f $(CLASS_FILES) + -del /F /Q $(CLASS_FILES) + +$(CLASS_FILES) : $(JAVA_FILES) + $(JAVAC) -classpath $(CLASSPATH) $(JAVA_FILES) + +# diff --git a/lib/jinterface/test/nc_SUITE_data/connection_server.java b/lib/jinterface/test/nc_SUITE_data/connection_server.java new file mode 100644 index 0000000000..19ed1c7d5c --- /dev/null +++ b/lib/jinterface/test/nc_SUITE_data/connection_server.java @@ -0,0 +1,96 @@ +/* + * %CopyrightBegin% + * + * Copyright Ericsson AB 2004-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% + */ + +import com.ericsson.otp.erlang.*; + +public class connection_server { + static java.lang.String Name = "connection_server"; + + public static void main(String[] argv) { + try { + System.out.println("connection_server booting..."); + + for (int j = 0; j < argv.length; j++) + System.out.println("argv[" + j + "] = \"" + argv[j] + "\""); + + if (argv.length != 4) { + System.out.println("Wrong number of arguments!"); + System.exit(1); + } + + // Start node and mbox + OtpNode node = new OtpNode(argv[0], argv[1]); + OtpMbox mbox = node.createMbox(); + if (! mbox.registerName(Name)) { + System.out.println("Could not register name " + Name); + System.exit(3); + } + + // Announce our presence + OtpErlangObject[] amsg = new OtpErlangObject[3]; + amsg[0] = new OtpErlangAtom(Name); + amsg[1] = new OtpErlangAtom(argv[0]); + amsg[2] = mbox.self(); + OtpErlangTuple atuple = new OtpErlangTuple(amsg); + mbox.send(argv[3], argv[2], atuple); + + // Do connects ... + while (true) { + OtpErlangObject o = mbox.receive(); + if (o == null) + continue; + if (o instanceof OtpErlangTuple) { + OtpErlangTuple msg = (OtpErlangTuple) o; + OtpErlangPid from = (OtpErlangPid)(msg.elementAt(0)); + OtpErlangAtom conn_node = (OtpErlangAtom) msg.elementAt(1); + + System.out.println("Got request to connect to: " + + conn_node); + OtpErlangObject[] rmsg = new OtpErlangObject[3]; + rmsg[0] = mbox.self(); + rmsg[1] = conn_node; + if (node.ping(conn_node.atomValue(), 1000)) { + System.out.println("Successfully connected to " + + conn_node.toString()); + rmsg[2] = new OtpErlangAtom("true"); + } + else { + System.out.println("Failed to connect to " + + conn_node.toString()); + rmsg[2] = new OtpErlangAtom("false"); + } + + OtpErlangTuple rtuple = new OtpErlangTuple(rmsg); + + mbox.send(from, rtuple); + } + else { // probably 'bye' + System.out.println("connection_server halting..."); + System.exit(0); + } + } + } + catch (Exception e) { + System.out.println("" + e); + System.exit(2); + } + + } + +} diff --git a/lib/jinterface/test/nc_SUITE_data/echo_server.java b/lib/jinterface/test/nc_SUITE_data/echo_server.java new file mode 100644 index 0000000000..0550e4beb1 --- /dev/null +++ b/lib/jinterface/test/nc_SUITE_data/echo_server.java @@ -0,0 +1,261 @@ +/* + * %CopyrightBegin% + * + * Copyright Ericsson AB 2004-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% + */ + +import java.io.UnsupportedEncodingException; +import java.util.HashSet; + +import com.ericsson.otp.erlang.OtpErlangAtom; +import com.ericsson.otp.erlang.OtpErlangBinary; +import com.ericsson.otp.erlang.OtpErlangBoolean; +import com.ericsson.otp.erlang.OtpErlangException; +import com.ericsson.otp.erlang.OtpErlangInt; +import com.ericsson.otp.erlang.OtpErlangList; +import com.ericsson.otp.erlang.OtpErlangLong; +import com.ericsson.otp.erlang.OtpErlangObject; +import com.ericsson.otp.erlang.OtpErlangPid; +import com.ericsson.otp.erlang.OtpErlangString; +import com.ericsson.otp.erlang.OtpErlangTuple; +import com.ericsson.otp.erlang.OtpExternal; +import com.ericsson.otp.erlang.OtpInputStream; +import com.ericsson.otp.erlang.OtpMbox; +import com.ericsson.otp.erlang.OtpNode; +import com.ericsson.otp.erlang.OtpOutputStream; + +public class echo_server { + private static boolean debug = false; + + public static void main(final String[] argv) { + try { + System.out.println("echo_server booting..."); + + for (int j = 0; j < argv.length; j++) { + System.out.println("argv[" + j + "] = \"" + argv[j] + "\""); + } + + if (argv.length != 4 && argv.length != 5) { + System.out.println("Wrong number of arguments!"); + System.exit(1); + } + + // Start node and mbox + final OtpNode node = new OtpNode(argv[0], argv[1]); + if (argv.length == 5 && argv[4].equals("unicode")) { + System.out.println("Setting unicode string mode."); + node.setFlags(OtpInputStream.DECODE_INT_LISTS_AS_STRINGS); + } + final OtpMbox mbox = node.createMbox(); + + // Announce our presence + final OtpErlangObject[] amsg = new OtpErlangObject[3]; + amsg[0] = new OtpErlangAtom("echo_server"); + amsg[1] = new OtpErlangAtom(argv[0]); + amsg[2] = mbox.self(); + final OtpErlangTuple atuple = new OtpErlangTuple(amsg); + mbox.send(argv[3], argv[2], atuple); + + // Do echoing... + while (true) { + final OtpErlangObject o = mbox.receive(); + if (o == null) { + continue; + } + if (o instanceof OtpErlangTuple) { + final OtpErlangTuple msg = (OtpErlangTuple) o; + final int arity = msg.arity(); + if (arity < 2) { + System.out + .println("Arity < 2; echo_server aborting..."); + System.exit(2); + } else if (arity == 2) { + final OtpErlangPid from = (OtpErlangPid) msg + .elementAt(0); + if (debug) System.out.println("Echoing: " + + msg.elementAt(1)); + + final OtpErlangObject[] rmsg = new OtpErlangObject[2]; + rmsg[0] = mbox.self(); + rmsg[1] = msg.elementAt(1); + final OtpErlangTuple rtuple = new OtpErlangTuple(rmsg); + + mbox.send(from, rtuple); + continue; + } else if (arity == 3) { + echoTwisted(mbox, msg); + continue; + } else { + System.out + .println("Arity > 3; echo_server aborting..."); + System.exit(2); + } + } else if (o instanceof OtpErlangAtom) { + OtpErlangAtom a = (OtpErlangAtom) o; + if (a.atomValue().equals("debug")) { + debug = true; + } else if (a.atomValue().equals("bye")) { + System.out.println("echo_server halting..."); + System.exit(0); + } + } else { // probably 'bye' + } + System.out.println("Unexpected: " + o + + " echo_server aborting..."); + System.exit(2); + } + } catch (final Exception e) { + System.out.println("" + e); + System.exit(2); + } + } + + private static void echoTwisted(final OtpMbox mbox, + final OtpErlangTuple msg) + throws OtpErlangException { + final OtpErlangPid from = (OtpErlangPid) msg.elementAt(0); + + final OtpErlangObject[] rmsg = new OtpErlangObject[3]; + if (debug) System.out.println("Echo in: " + msg); + rmsg[0] = mbox.self(); + rmsg[1] = twist(msg.elementAt(1), rmsg[2] = msg.elementAt(2)); + final OtpErlangTuple rtuple = new OtpErlangTuple(rmsg); + if (debug) System.out.println("Echo out: " + rtuple); + + mbox.send(from, rtuple); + } + + private static HashSet<OtpErlangObject> hash_set = + new HashSet<OtpErlangObject>(); + + private static OtpErlangObject twist(final OtpErlangObject i, + final OtpErlangObject t) throws OtpErlangException { + hash_set.add(i); + if (t instanceof OtpErlangAtom) { + final String atomValue = ((OtpErlangAtom) t).atomValue(); + if (atomValue.equals("binary") && i instanceof OtpErlangBinary) { + final OtpErlangBinary b = (OtpErlangBinary) i; + final OtpInputStream bis = new OtpInputStream(b.binaryValue(), + 0); + final OtpErlangObject o = bis.read_any(); + return o; + } else if (atomValue.equals("compress")) { + final OtpOutputStream oos = new OtpOutputStream(); + oos.write1(OtpExternal.versionTag); + oos.write_compressed(i); + final OtpErlangBinary o = + new OtpErlangBinary(oos.toByteArray()); + return o; + } else if (atomValue.equals("bigint") + && i instanceof OtpErlangLong) { + final OtpErlangLong l = (OtpErlangLong) i; + final int w = l.signum() * l.bitLength(); + final OtpErlangLong x = new OtpErlangLong(l.longValue()); + final java.math.BigInteger b = l.bigIntegerValue(); + System.out.println("long: " + l + ": " + w + ": " + b.signum() + * b.bitLength() + ": " + x + ": " + l.isLong() + ": " + + l.isULong()); + return new OtpErlangTuple(new OtpErlangObject[] { l, + new OtpErlangInt(w), x, + new OtpErlangInt(l.isLong() ? 1 : 0), + new OtpErlangInt(l.isULong() ? 1 : 0) }); + } else if (atomValue.equals("tail") + && i instanceof OtpErlangList) { + final OtpErlangObject o = ((OtpErlangList) i).getTail(); + if (o == null) { + return new OtpErlangAtom("null"); + } + return o; + } else if (atomValue.equals("tail3") + && i instanceof OtpErlangList) { + final OtpErlangObject o = ((OtpErlangList) i).getNthTail(3); + if (o == null) { + return new OtpErlangAtom("null"); + } + return o; + } else if (atomValue.equals("strcat") + && i instanceof OtpErlangList) { + final java.lang.StringBuffer b = new java.lang.StringBuffer(); + final OtpErlangList l = (OtpErlangList) i; + for (final OtpErlangObject j : l) { + final OtpErlangString k = (OtpErlangString) j; + b.append(k.stringValue()); + } + final OtpErlangObject o = new OtpErlangString(b.toString()); + return o; + } else if (atomValue.equals("sub3atom") + && i instanceof OtpErlangString) { + final OtpErlangString s = (OtpErlangString) i; + final OtpErlangAtom o = new OtpErlangAtom(s.stringValue() + .substring(3)); + return o; + } else if (atomValue.equals("utf8")) { + if (i instanceof OtpErlangString) { + final OtpErlangString s = (OtpErlangString) i; + byte[] bytes; + try { + bytes = s.stringValue().getBytes("UTF-8"); + } catch (final UnsupportedEncodingException e) { + bytes = new byte[] { 'e', 'r', 'r', 'o', 'r' }; + } + final OtpErlangBinary b = new OtpErlangBinary(bytes); + return b; + } + } else if(atomValue.equals("to_string_neg_int_list")) { + OtpErlangString oes = null; + if (i instanceof OtpErlangString) { + oes = (OtpErlangString) i; + } else if (i instanceof OtpErlangList) { + OtpErlangList oel = (OtpErlangList) i; + try { + oes = new OtpErlangString(oel); + } catch (final Exception e) { + } + } + if (oes != null) { + String s = oes.stringValue(); + int n = s.length(); + OtpErlangObject l[] = new OtpErlangObject[n]; + for (int j = 0; j < n; j++) { + int c = s.charAt(j); + l[j] = new OtpErlangInt(-c); + } + return new OtpErlangList(l); + } + } else if(atomValue.equals("to_neg_int_list")) { + if (i instanceof OtpErlangString) { + OtpErlangString oes = (OtpErlangString) i; + OtpErlangList oel = new OtpErlangList(oes.stringValue()); + int n = oel.arity(); + OtpErlangObject l[] = new OtpErlangObject[n]; + for (int j = 0; j < n; j++) { + OtpErlangLong c = (OtpErlangLong) oel.elementAt(j); + l[j] = new OtpErlangInt(-c.intValue()); + } + return new OtpErlangList(l); + } + } else if (atomValue.equals("hash_lookup")) { + final boolean exists = hash_set.contains(i); + final OtpErlangBoolean b = new OtpErlangBoolean(exists); + return b; + } else if (atomValue.equals("hash_clear")) { + hash_set.clear(); + return new OtpErlangAtom("hash_cleared"); + } + } + return i; + } +} diff --git a/lib/jinterface/vsn.mk b/lib/jinterface/vsn.mk index 6b5719d7c5..26613febbf 100644 --- a/lib/jinterface/vsn.mk +++ b/lib/jinterface/vsn.mk @@ -1,19 +1 @@ -## -## %CopyrightBegin% -## -## Copyright Ericsson AB 2000-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% - JINTERFACE_VSN = 1.5.3 diff --git a/lib/kernel/doc/src/erl_ddll.xml b/lib/kernel/doc/src/erl_ddll.xml index 4e65bf46f8..9a62b45d63 100644 --- a/lib/kernel/doc/src/erl_ddll.xml +++ b/lib/kernel/doc/src/erl_ddll.xml @@ -177,7 +177,7 @@ <name>demonitor(MonitorRef) -> ok</name> <fsummary>Remove a monitor for a driver</fsummary> <type> - <v>MonitorRef = ref()</v> + <v>MonitorRef = reference()</v> </type> <desc> <p>Removes a driver monitor in much the same way as @@ -185,7 +185,7 @@ monitors. See <seealso marker="#monitor/2">monitor/2</seealso>, <seealso marker="#try_load/3">try_load/3</seealso> and <seealso marker="#try_unload/2">try_unload/2</seealso> for details about how to create driver monitors.</p> <p>The function throws a <c>badarg</c> exception if the - parameter is not a ref(). </p> + parameter is not a reference(). </p> </desc> </func> <func> @@ -400,7 +400,7 @@ <v>Item = {Name, When}</v> <v>Name = atom() | string()</v> <v>When = loaded | unloaded | unloaded_only</v> - <v>MonitorRef = ref()</v> + <v>MonitorRef = reference()</v> </type> <desc> <p>This function creates a driver monitor and works in many @@ -449,7 +449,7 @@ eventually lead to one of the following messages being sent:</p> <taglist> - <tag><em>{'UP', ref(), driver, Name, loaded}</em></tag> + <tag><em>{'UP', reference(), driver, Name, loaded}</em></tag> <item> <p>This message is sent, either immediately if the driver is already loaded and no reloading is @@ -459,7 +459,7 @@ expected to know if reloading is demanded prior to creating a monitor for loading.</p> </item> - <tag><em>{'UP', ref(), driver, Name, permanent}</em></tag> + <tag><em>{'UP', reference(), driver, Name, permanent}</em></tag> <item> <p>This message will be sent if reloading was expected, but the (old) driver made itself @@ -467,7 +467,7 @@ sent if the driver was permanent or statically linked in when trying to create the monitor.</p> </item> - <tag><em>{'DOWN', ref(), driver, Name, load_cancelled}</em></tag> + <tag><em>{'DOWN', reference(), driver, Name, load_cancelled}</em></tag> <item> <p>This message will arrive if reloading was underway, but the <seealso marker="#users">user</seealso> having requested @@ -476,7 +476,7 @@ (or <c>unload/1</c>/<c>unload_driver/1</c>) again before it was reloaded.</p> </item> - <tag><em>{'DOWN', ref(), driver, Name, {load_failure, Failure}}</em></tag> + <tag><em>{'DOWN', reference(), driver, Name, {load_failure, Failure}}</em></tag> <item> <p>This message will arrive if reloading was underway but the loading for some reason @@ -500,7 +500,7 @@ <p>A driver monitor for unload will eventually result in one of the following messages being sent:</p> <taglist> - <tag><em>{'DOWN', ref(), driver, Name, unloaded}</em></tag> + <tag><em>{'DOWN', reference(), driver, Name, unloaded}</em></tag> <item> <p>The driver instance monitored is now unloaded. As the unload might have been due to a @@ -508,7 +508,7 @@ again have been loaded when this message arrives.</p> </item> - <tag><em>{'UP', ref(), driver, Name, unload_cancelled}</em></tag> + <tag><em>{'UP', reference(), driver, Name, unload_cancelled}</em></tag> <item> <p>This message will be sent if unloading was expected, but while the driver was waiting for @@ -525,7 +525,7 @@ similar to an <c>unloaded</c> monitor, but does never result in this message.</p> </item> - <tag><em>{'UP', ref(), driver, Name, permanent}</em></tag> + <tag><em>{'UP', reference(), driver, Name, permanent}</em></tag> <item> <p>This message will be sent if unloading was expected, but the driver made itself @@ -539,7 +539,7 @@ <item> <p>A monitor created as <c>unloaded_only</c> behaves exactly as one created as <c>unloaded</c> with the - exception that the <c>{'UP', ref(), driver, Name, unload_cancelled}</c> message will never be + exception that the <c>{'UP', reference(), driver, Name, unload_cancelled}</c> message will never be sent, but the monitor instead persists until the driver <em>really</em> gets unloaded.</p> </item> @@ -626,7 +626,7 @@ <v>ReloadOption = pending_driver | pending</v> <v>Status = loaded | already_loaded | PendingStatus </v> <v>PendingStatus = pending_driver | pending_process</v> - <v>Ref = ref()</v> + <v>Ref = reference()</v> <v>ErrorDesc = ErrorAtom | OpaqueError</v> <v>ErrorAtom = linked_in_driver | inconsistent | permanent | not_loaded_by_this_process | not_loaded | pending_reload | pending_process</v> </type> @@ -650,7 +650,7 @@ registered and a corresponding <c>try_unload</c> is expected sometime in the future.</p> </item> - <tag><em>{ok, pending_driver}</em>or <em>{ok, pending_driver, ref()}</em></tag> + <tag><em>{ok, pending_driver}</em>or <em>{ok, pending_driver, reference()}</em></tag> <item> <p>The load request is registered, but the loading is delayed due to the fact that an earlier instance of the @@ -665,7 +665,7 @@ set. In other words, this return value will always need to be handled!</p> </item> - <tag><em>{ok, pending_process}</em>or <em>{ok, pending_process, ref()}</em></tag> + <tag><em>{ok, pending_process}</em>or <em>{ok, pending_process, reference()}</em></tag> <item> <p>The load request is registered, but the loading is delayed due to the fact that an earlier instance of the @@ -683,7 +683,7 @@ about when the driver is <em>actually</em> loaded. This can be achieved by using the <c>{monitor, PendingOption}</c> option.</p> <p>When monitoring is requested, and a corresponding <c>{ok, pending_driver}</c> or <c>{ok, pending_process}</c> would be - returned, the function will instead return a tuple <c>{ok, PendingStatus, ref()}</c> and the process will, at a later + returned, the function will instead return a tuple <c>{ok, PendingStatus, reference()}</c> and the process will, at a later time when the driver actually gets loaded, get a monitor message. The monitor message one can expect is described in the <seealso marker="#monitor/2">monitor/2</seealso> @@ -760,7 +760,7 @@ <p>A <c>MonitorOption</c> tells <c>try_load/3</c> to trigger a driver monitor under certain conditions. When the monitor is triggered, the - function will return a three-tuple <c>{ok, PendingStatus, ref()}</c>, where the <c>ref()</c> is + function will return a three-tuple <c>{ok, PendingStatus, reference()}</c>, where the <c>reference()</c> is the monitor ref for the driver monitor.</p> <p>Only one <c>MonitorOption</c> can be specified and it is either the atom <c>pending</c>, which means @@ -891,7 +891,7 @@ <v>MonitorOption = pending_driver | pending</v> <v>Status = unloaded | PendingStatus </v> <v>PendingStatus = pending_driver | pending_process</v> - <v>Ref = ref()</v> + <v>Ref = reference()</v> <v>ErrorAtom = linked_in_driver | not_loaded | not_loaded_by_this_process | permanent</v> </type> <desc> @@ -943,7 +943,7 @@ ports using it and there are no more <seealso marker="#users">users</seealso> requiring it to be loaded.</p> </item> - <tag><em>{ok, pending_driver}</em>or <em>{ok, pending_driver, ref()}</em></tag> + <tag><em>{ok, pending_driver}</em>or <em>{ok, pending_driver, reference()}</em></tag> <item> <p>This return value indicates that this call removed the last <seealso marker="#users">user</seealso> from the @@ -957,7 +957,7 @@ in that case, however transient. Monitors are as always useful to detect when the driver is really unloaded.</p> </item> - <tag><em>{ok, pending_process}</em>or <em>{ok, pending_process, ref()}</em></tag> + <tag><em>{ok, pending_process}</em>or <em>{ok, pending_process, reference()}</em></tag> <item> <p>The unload request is registered, but there are still other <seealso marker="#users">users</seealso> holding diff --git a/lib/kernel/src/gen_sctp.erl b/lib/kernel/src/gen_sctp.erl index 5a31e3976f..a1542ab507 100644 --- a/lib/kernel/src/gen_sctp.erl +++ b/lib/kernel/src/gen_sctp.erl @@ -166,18 +166,14 @@ send(S, #sctp_assoc_change{assoc_id=AssocId}, Stream, Data) when is_port(S), is_integer(Stream) -> case inet_db:lookup_socket(S) of {ok,Mod} -> - Mod:sendmsg(S, #sctp_sndrcvinfo{ - stream = Stream, - assoc_id = AssocId}, Data); + Mod:send(S, AssocId, Stream, Data); Error -> Error end; send(S, AssocId, Stream, Data) when is_port(S), is_integer(AssocId), is_integer(Stream) -> case inet_db:lookup_socket(S) of {ok,Mod} -> - Mod:sendmsg(S, #sctp_sndrcvinfo{ - stream = Stream, - assoc_id = AssocId}, Data); + Mod:send(S, AssocId, Stream, Data); Error -> Error end; send(S, AssocChange, Stream, Data) -> diff --git a/lib/kernel/src/inet6_sctp.erl b/lib/kernel/src/inet6_sctp.erl index 5c49c4fec3..5bf3fca647 100644 --- a/lib/kernel/src/inet6_sctp.erl +++ b/lib/kernel/src/inet6_sctp.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2007-2009. All Rights Reserved. +%% Copyright Ericsson AB 2007-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 @@ -32,7 +32,7 @@ -define(FAMILY, inet6). -export([getserv/1,getaddr/1,getaddr/2,translate_ip/1]). --export([open/1,close/1,listen/2,connect/5,sendmsg/3,recv/2]). +-export([open/1,close/1,listen/2,connect/5,sendmsg/3,send/4,recv/2]). @@ -71,5 +71,24 @@ connect(S, Addr, Port, Opts, Timer) -> sendmsg(S, SRI, Data) -> prim_inet:sendmsg(S, SRI, Data). +send(S, AssocId, Stream, Data) -> + case prim_inet:getopts( + S, + [{sctp_default_send_param,#sctp_sndrcvinfo{assoc_id=AssocId}}]) of + {ok, + [{sctp_default_send_param, + #sctp_sndrcvinfo{ + flags=Flags, context=Context, ppid=PPID, timetolive=TTL}}]} -> + prim_inet:sendmsg( + S, + #sctp_sndrcvinfo{ + flags=Flags, context=Context, ppid=PPID, timetolive=TTL, + assoc_id=AssocId, stream=Stream}, + Data); + _ -> + prim_inet:sendmsg( + S, #sctp_sndrcvinfo{assoc_id=AssocId, stream=Stream}, Data) + end. + recv(S, Timeout) -> prim_inet:recvfrom(S, 0, Timeout). diff --git a/lib/kernel/src/inet_sctp.erl b/lib/kernel/src/inet_sctp.erl index 795bf83807..de74b573bd 100644 --- a/lib/kernel/src/inet_sctp.erl +++ b/lib/kernel/src/inet_sctp.erl @@ -31,7 +31,7 @@ -define(FAMILY, inet). -export([getserv/1,getaddr/1,getaddr/2,translate_ip/1]). --export([open/1,close/1,listen/2,connect/5,sendmsg/3,recv/2]). +-export([open/1,close/1,listen/2,connect/5,sendmsg/3,send/4,recv/2]). @@ -141,5 +141,24 @@ connect_get_assoc(S, Addr, Port, Active, Timer) -> sendmsg(S, SRI, Data) -> prim_inet:sendmsg(S, SRI, Data). +send(S, AssocId, Stream, Data) -> + case prim_inet:getopts( + S, + [{sctp_default_send_param,#sctp_sndrcvinfo{assoc_id=AssocId}}]) of + {ok, + [{sctp_default_send_param, + #sctp_sndrcvinfo{ + flags=Flags, context=Context, ppid=PPID, timetolive=TTL}}]} -> + prim_inet:sendmsg( + S, + #sctp_sndrcvinfo{ + flags=Flags, context=Context, ppid=PPID, timetolive=TTL, + assoc_id=AssocId, stream=Stream}, + Data); + _ -> + prim_inet:sendmsg( + S, #sctp_sndrcvinfo{assoc_id=AssocId, stream=Stream}, Data) + end. + recv(S, Timeout) -> prim_inet:recvfrom(S, 0, Timeout). diff --git a/lib/kernel/src/net_kernel.erl b/lib/kernel/src/net_kernel.erl index 0e5cc8c2c6..f5e2820bbe 100644 --- a/lib/kernel/src/net_kernel.erl +++ b/lib/kernel/src/net_kernel.erl @@ -500,8 +500,8 @@ handle_call({new_ticktime,T,TP}, From, #state{tick = #tick{ticker = Tckr, time = T, how = How}}}, From); -handle_call({new_ticktime,From,_}, - _, +handle_call({new_ticktime,_T,_TP}, + From, #state{tick = #tick_change{time = T}} = State) -> async_reply({reply, {ongoing_change_to, T}, State}, From); diff --git a/lib/kernel/test/erl_distribution_SUITE.erl b/lib/kernel/test/erl_distribution_SUITE.erl index d15f6aa0d5..21a96f804a 100644 --- a/lib/kernel/test/erl_distribution_SUITE.erl +++ b/lib/kernel/test/erl_distribution_SUITE.erl @@ -273,6 +273,7 @@ tick_change(Config) when is_list(Config) -> ?line PaDir = filename:dirname(code:which(?MODULE)), ?line [BN, CN] = get_nodenames(2, tick_change), ?line DefaultTT = net_kernel:get_net_ticktime(), + ?line unchanged = net_kernel:set_net_ticktime(DefaultTT, 60), ?line case DefaultTT of I when is_integer(I) -> ?line ok; _ -> ?line ?t:fail(DefaultTT) @@ -377,6 +378,7 @@ run_tick_change_test(B, C, PrevTT, TT, PaDir) -> end, ?line change_initiated = net_kernel:set_net_ticktime(TT,20), + ?line {ongoing_change_to,_} = net_kernel:set_net_ticktime(TT,20), ?line sleep(3), ?line change_initiated = rpc:call(B,net_kernel,set_net_ticktime,[TT,15]), ?line sleep(7), diff --git a/lib/kernel/test/gen_sctp_SUITE.erl b/lib/kernel/test/gen_sctp_SUITE.erl index fad8c7398b..eb06d4324b 100644 --- a/lib/kernel/test/gen_sctp_SUITE.erl +++ b/lib/kernel/test/gen_sctp_SUITE.erl @@ -23,12 +23,16 @@ %%-compile(export_all). --export([all/1,init_per_testcase/2,fin_per_testcase/2, - basic/1,api_open_close/1,api_listen/1,api_connect_init/1, - xfer_min/1,xfer_active/1]). +-export([all/1,init_per_testcase/2,fin_per_testcase/2]). +-export( + [basic/1, + api_open_close/1,api_listen/1,api_connect_init/1,api_opts/1, + xfer_min/1,xfer_active/1,def_sndrcvinfo/1]). all(suite) -> - [basic,api_open_close,api_listen,api_connect_init,xfer_min,xfer_active]. + [basic, + api_open_close,api_listen,api_connect_init,api_opts, + xfer_min,xfer_active,def_sndrcvinfo]. init_per_testcase(_Func, Config) -> Dog = test_server:timetrap(test_server:seconds(15)), @@ -39,6 +43,10 @@ fin_per_testcase(_Func, Config) -> +-define(LOGVAR(Var), begin io:format(??Var" = ~p~n", [Var]) end). + + + basic(doc) -> "Hello world"; basic(suite) -> @@ -214,12 +222,17 @@ xfer_active(Config) when is_list(Config) -> end, ?line ok = gen_sctp:close(Sb), ?line receive - {sctp,Sa,Loopback,Pb, - {[], - #sctp_assoc_change{state=comm_lost, - assoc_id=SaAssocId}}} -> ok - after 17 -> ok %% On Solaris this does not arrive - end, + {sctp,Sa,Loopback,Pb, + {[], + #sctp_assoc_change{state=comm_lost, + assoc_id=SaAssocId}}} -> ok + after Timeout -> + ?line test_server:fail({unexpected,flush()}) + end, + ?line receive + {sctp_error,Sa,enotconn} -> ok % Solaris + after 17 -> ok %% Only happens on Solaris + end, ?line ok = gen_sctp:close(Sa), %% ?line receive @@ -228,6 +241,148 @@ xfer_active(Config) when is_list(Config) -> end, ok. +def_sndrcvinfo(doc) -> + "Test that #sctp_sndrcvinfo{} parameters set on a socket " + "are used by gen_sctp:send/4"; +def_sndrcvinfo(suite) -> + []; +def_sndrcvinfo(Config) when is_list(Config) -> + ?line Loopback = {127,0,0,1}, + ?line Data = <<"What goes up, must come down.">>, + %% + ?line S1 = + ok(gen_sctp:open( + 0, [{sctp_default_send_param,#sctp_sndrcvinfo{ppid=17}}])), + ?LOGVAR(S1), + ?line P1 = + ok(inet:port(S1)), + ?LOGVAR(P1), + ?line #sctp_sndrcvinfo{ppid=17, context=0, timetolive=0, assoc_id=0} = + getopt(S1, sctp_default_send_param), + ?line ok = + gen_sctp:listen(S1, true), + %% + ?line S2 = + ok(gen_sctp:open()), + ?LOGVAR(S2), + ?line P2 = + ok(inet:port(S2)), + ?LOGVAR(P2), + ?line #sctp_sndrcvinfo{ppid=0, context=0, timetolive=0, assoc_id=0} = + getopt(S2, sctp_default_send_param), + %% + ?line #sctp_assoc_change{ + state=comm_up, + error=0, + assoc_id=S2AssocId} = S2AssocChange = + ok(gen_sctp:connect(S2, Loopback, P1, [])), + ?LOGVAR(S2AssocChange), + ?line case ok(gen_sctp:recv(S1)) of + {Loopback, P2,[], + #sctp_assoc_change{ + state=comm_up, + error=0, + assoc_id=S1AssocId}} -> + ?LOGVAR(S1AssocId) + end, + ?line #sctp_sndrcvinfo{ + ppid=17, context=0, timetolive=0, assoc_id=S1AssocId} = + getopt( + S1, sctp_default_send_param, #sctp_sndrcvinfo{assoc_id=S1AssocId}), + ?line #sctp_sndrcvinfo{ + ppid=0, context=0, timetolive=0, assoc_id=S2AssocId} = + getopt( + S2, sctp_default_send_param, #sctp_sndrcvinfo{assoc_id=S2AssocId}), + %% + ?line ok = + gen_sctp:send(S1, S1AssocId, 1, <<"1: ",Data/binary>>), + ?line case ok(gen_sctp:recv(S2)) of + {Loopback,P1, + [#sctp_sndrcvinfo{ + stream=1, ppid=17, context=0, assoc_id=S2AssocId}], + <<"1: ",Data/binary>>} -> ok + end, + %% + ?line ok = + setopt( + S1, sctp_default_send_param, #sctp_sndrcvinfo{ppid=18}), + ?line ok = + setopt( + S1, sctp_default_send_param, + #sctp_sndrcvinfo{ppid=19, assoc_id=S1AssocId}), + ?line #sctp_sndrcvinfo{ + ppid=18, context=0, timetolive=0, assoc_id=0} = + getopt(S1, sctp_default_send_param), + ?line #sctp_sndrcvinfo{ + ppid=19, context=0, timetolive=0, assoc_id=S1AssocId} = + getopt( + S1, sctp_default_send_param, #sctp_sndrcvinfo{assoc_id=S1AssocId}), + %% + ?line ok = + gen_sctp:send(S1, S1AssocId, 0, <<"2: ",Data/binary>>), + ?line case ok(gen_sctp:recv(S2)) of + {Loopback,P1, + [#sctp_sndrcvinfo{ + stream=0, ppid=19, context=0, assoc_id=S2AssocId}], + <<"2: ",Data/binary>>} -> ok + end, + ?line ok = + gen_sctp:send(S2, S2AssocChange, 1, <<"3: ",Data/binary>>), + ?line case ok(gen_sctp:recv(S1)) of + {Loopback,P2, + [#sctp_sndrcvinfo{ + stream=1, ppid=0, context=0, assoc_id=S1AssocId}], + <<"3: ",Data/binary>>} -> ok; + {Loopback,P2,[], + #sctp_paddr_change{ + addr={Loopback,_}, state=addr_available, + error=0, assoc_id=S1AssocId}} -> + ?line case ok(gen_sctp:recv(S1)) of + {Loopback,P2, + [#sctp_sndrcvinfo{ + stream=1, ppid=0, context=0, + assoc_id=S1AssocId}], + <<"3: ",Data/binary>>} -> ok + end + end, + ?line ok = + gen_sctp:send( + S2, + #sctp_sndrcvinfo{stream=0, ppid=20, assoc_id=S2AssocId}, + <<"4: ",Data/binary>>), + ?line case ok(gen_sctp:recv(S1)) of + {Loopback,P2, + [#sctp_sndrcvinfo{ + stream=0, ppid=20, context=0, assoc_id=S1AssocId}], + <<"4: ",Data/binary>>} -> ok + end, + %% + ?line ok = + gen_sctp:close(S1), + ?line ok = + gen_sctp:close(S2), + ?line receive + Msg -> + test_server:fail({received,Msg}) + after 17 -> ok + end, + ok. + +getopt(S, Opt) -> + {ok,[{Opt,Val}]} = inet:getopts(S, [Opt]), + Val. + +getopt(S, Opt, Param) -> + {ok,[{Opt,Val}]} = inet:getopts(S, [{Opt,Param}]), + Val. + +setopt(S, Opt, Val) -> + inet:setopts(S, [{Opt,Val}]). + +ok({ok,X}) -> + io:format("OK: ~p~n", [X]), + X. + flush() -> receive Msg -> @@ -382,3 +537,17 @@ api_connect_init(Config) when is_list(Config) -> ?line ok = gen_sctp:close(Sa), ?line ok = gen_sctp:close(Sb), ok. + +api_opts(doc) -> + "Test socket options"; +api_opts(suite) -> + []; +api_opts(Config) when is_list(Config) -> + ?line {ok,S} = gen_sctp:open(0), + ?line OSType = os:type(), + ?line case {inet:setopts(S, [{linger,{true,2}}]),OSType} of + {ok,_} -> + ok; + {{error,einval},{unix,sunos}} -> + ok + end. diff --git a/lib/kernel/test/inet_SUITE.erl b/lib/kernel/test/inet_SUITE.erl index eb8f918491..f4f27933a5 100644 --- a/lib/kernel/test/inet_SUITE.erl +++ b/lib/kernel/test/inet_SUITE.erl @@ -26,7 +26,8 @@ t_gethostbyaddr_v6/1, t_getaddr_v6/1, t_gethostbyname_v6/1, ipv4_to_ipv6/1, host_and_addr/1, parse/1, t_gethostnative/1, gethostnative_parallell/1, cname_loop/1, - gethostnative_soft_restart/1,gethostnative_debug_level/1,getif/1]). + gethostnative_soft_restart/1,gethostnative_debug_level/1,getif/1, + getif_ifr_name_overflow/1,getservbyname_overflow/1]). -export([get_hosts/1, get_ipv6_hosts/1, parse_hosts/1, parse_address/1, kill_gethost/0, parallell_gethost/0]). @@ -39,7 +40,7 @@ all(suite) -> ipv4_to_ipv6, host_and_addr, parse,t_gethostnative, gethostnative_parallell, cname_loop, gethostnative_debug_level,gethostnative_soft_restart, - getif]. + getif,getif_ifr_name_overflow,getservbyname_overflow]. init_per_testcase(_Func, Config) -> Dog = test_server:timetrap(test_server:seconds(60)), @@ -876,6 +877,17 @@ getif(Config) when is_list(Config) -> ?line {ok,Address} = inet:getaddr(Hostname, inet), ?line {ok,Loopback} = inet:getaddr("localhost", inet), ?line {ok,Interfaces} = inet:getiflist(), + ?line HWAs = + lists:sort( + lists:foldl( + fun (I, Acc) -> + case inet:ifget(I, [hwaddr]) of + {ok,[{hwaddr,A}]} -> [A|Acc]; + {ok,[]} -> Acc + end + end, [], Interfaces)), + ?line io:format("HWAs = ~p~n", [HWAs]), + ?line length(HWAs) > 0 orelse ?t:fail(no_HWAs), ?line Addresses = lists:sort( lists:foldl( @@ -891,6 +903,20 @@ getif(Config) when is_list(Config) -> ?line true = ip_member(Loopback, Addresses), ?line ok. +getif_ifr_name_overflow(doc) -> + "Test long interface names do not overrun buffer"; +getif_ifr_name_overflow(Config) when is_list(Config) -> + %% emulator should not crash + ?line {ok,[]} = inet:ifget(lists:duplicate(128, "x"), [addr]), + ok. + +getservbyname_overflow(doc) -> + "Test long service names do not overrun buffer"; +getservbyname_overflow(Config) when is_list(Config) -> + %% emulator should not crash + ?line {error,einval} = inet:getservbyname(list_to_atom(lists:flatten(lists:duplicate(128, "x"))), tcp), + ok. + %% Works just like lists:member/2, except that any {127,_,_,_} tuple %% matches any other {127,_,_,_}. We do this to handle Linux systems %% that use (for instance) 127.0.1.1 as the IP address for the hostname. diff --git a/lib/kernel/vsn.mk b/lib/kernel/vsn.mk index 9a191f9aeb..651d082379 100644 --- a/lib/kernel/vsn.mk +++ b/lib/kernel/vsn.mk @@ -1,20 +1 @@ -# -# %CopyrightBegin% -# -# Copyright Ericsson AB 1997-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% -# - KERNEL_VSN = 2.14.1 diff --git a/lib/megaco/vsn.mk b/lib/megaco/vsn.mk index efb46253aa..73ac5bbc63 100644 --- a/lib/megaco/vsn.mk +++ b/lib/megaco/vsn.mk @@ -1,151 +1,4 @@ -#-*-makefile-*- ; force emacs to enter makefile-mode - -# %CopyrightBegin% -# -# Copyright Ericsson AB 2001-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% - APPLICATION = megaco MEGACO_VSN = 3.14.1.1 PRE_VSN = APP_VSN = "$(APPLICATION)-$(MEGACO_VSN)$(PRE_VSN)" - -TICKETS = OTP-8696 - -TICKETS_3_14_1 = OTP-8529 OTP-8561 OTP-8627 OTP-8634 - -TICKETS_3_14 = OTP-8317 OTP-8323 OTP-8328 OTP-8362 OTP-8403 - -TICKETS_3_13 = OTP-8205 OTP-8239 OTP-8249 - -TICKETS_3_12 = OTP-8183 OTP-8212 - -TICKETS_3_11_3 = OTP-8164 OTP-8167 OTP-8191 - -TICKETS_3_11_2 = OTP-8123 - -TICKETS_3_11_1 = OTP-8081 OTP-8114 - -TICKETS_3_11 = OTP-7302 OTP-7995 - -TICKETS_3_10_1 = OTP-7926 OTP-7936 - -TICKETS_3_10_0_1 = OTP-7851 - -TICKETS_3_10 = OTP-7713 OTP-7743 - -TICKETS_3_9_4 = OTP-7728 OTP-7733 - -TICKETS_3_9_3 = OTP-7700 - -TICKETS_3_9_2 = OTP-7671 OTP-7672 - -TICKETS_3_9_1_1 = OTP-7614 - -TICKETS_3_9_1 = OTP-7572 OTP-7573 OTP-7576 - -TICKETS_3_9 = OTP-7431 - -TICKETS_3_8_2 = OTP-7534 - -TICKETS_3_8_1 = OTP-7398 OTP-7417 OTP-7444 OTP-7449 OTP-7455 OTP-7457 OTP-7459 - -TICKETS_3_8 = OTP-7192 OTP-7228 OTP-7259 - -TICKETS_3_7_5 = OTP-7286 OTP-7303 - -TICKETS_3_7_4 = OTP-7249 OTP-7251 - -TICKETS_3_7_3 = OTP-7168 OTP-7180 OTP-7189 OTP-7216 - -TICKETS_3_7_2 = OTP-6972 OTP-7138 - -TICKETS_3_7_1 = OTP-6919 OTP-6971 OTP-6992 OTP-6999 OTP-7000 OTP-7005 OTP-7124 - -TICKETS_3_7 = OTP-5979 OTP-6753 OTP-6804 OTP-6865 OTP-6919 OTP-6976 - -TICKETS_3_6_2 = OTP-6921 - -TICKETS_3_6_1 = OTP-6803 - -TICKETS_3_6_0_1 = OTP-6704 - -TICKETS_3_6 = OTP-6185 OTP-6578 OTP-6441 OTP-6442 OTP-6544 OTP-6605 OTP-6609 - -TICKETS_3_5_3 = OTP-6520 OTP-6549 - -TICKETS_3_5_2 = OTP-6404 OTP-6422 OTP-6490 OTP-6503 - -TICKETS_3_5_1 = OTP-6275 OTP-6276 - -TICKETS_3_5 = OTP-6223 OTP-6253 OTP-6256 - -TICKETS_3_4_4 = OTP-6181 OTP-6182 OTP-6217 OTP-6219 - -TICKETS_3_4_3 = OTP-6170 OTP-6171 OTP-6172 - -TICKETS_3_4_2 = OTP-6148 - -TICKETS_3_4_1 = OTP-6113 - -TICKETS_3_4 = \ - OTP-5769 \ - OTP-5980 \ - OTP-6009 \ - OTP-6025 \ - OTP-6028 \ - OTP-6030 \ - OTP-6048 \ - OTP-6051 \ - OTP-6052 \ - OTP-6055 \ - OTP-6089 \ - OTP-6090 - -TICKETS_3_3_5 = OTP-6108 - -TICKETS_3_3_4 = OTP-6076 - -TICKETS_3_3_3 = OTP-6046 - -TICKETS_3_3_2 = OTP-6017 OTP-6022 - -TICKETS_3_3_1 = OTP-5993 - -TICKETS_3_3 = OTP-5965 OTP-5973 - -TICKETS_3_2_7 = OTP-5948 OTP-5952 OTP-5953 - -TICKETS_3_2_6 = OTP-5918 OTP-5919 OTP-5920 - -TICKETS_3_2_5 = OTP-5887 - -TICKETS_3_2_4 = OTP-5867 OTP-5879 OTP-5880 OTP-5881 OTP-5882 OTP-5885 OTP-5886 - -TICKETS_3_2_3 = OTP-5826 OTP-5830 OTP-5833 OTP-5836 OTP-5839 - -TICKETS_3_2_2 = OTP-5799 OTP-5803 OTP-5804 OTP-5805 OTP-5816 - -TICKETS_3_2_1 = OTP-5725 OTP-5793 - -TICKETS_3_2 = OTP-5717 OTP-5750 - -TICKETS_3_1 = OTP-5542 OTP-5597 OTP-5600 OTP-5601 OTP-5619 OTP-5664 - -TICKETS_3_0_1 = \ - OTP-5401 \ - OTP-5446 \ - OTP-5447 - diff --git a/lib/mnesia/vsn.mk b/lib/mnesia/vsn.mk index 2780b737b6..ab2bb73c33 100644 --- a/lib/mnesia/vsn.mk +++ b/lib/mnesia/vsn.mk @@ -1,17 +1 @@ - MNESIA_VSN = 4.4.14 - -TICKETS = OTP-8519 -#TICKETS_4.4.13 = OTP-8402 OTP-8406 -#TICKETS_4.4.12 = OTP-8250 -#TICKETS_4.4.11 = OTP-8074 -#TICKETS_4.4.10 = OTP-7928 OTP-7968 OTP-8002 -#TICKETS_4.4.9 = OTP-7911 -#TICKETS_4.4.8 = OTP-7753 OTP-7835 -#TICKETS_4.4.7 = OTP-7524 OTP-7625 -#TICKETS_4.4.6 = OTP-7585 -#TICKETS_4.4.5 = OTP-7466 -#TICKETS_4.4.4 = OTP-7419 -#TICKETS_4.4.3 = OTP-7340 OTP-7378 OTP-7383 -#TICKETS_4.4.2 = OTP-7205 OTP-7208 -#TICKETS_4.4.1 = OTP-7170 diff --git a/lib/odbc/vsn.mk b/lib/odbc/vsn.mk index d813466437..fac3f06d4b 100644 --- a/lib/odbc/vsn.mk +++ b/lib/odbc/vsn.mk @@ -1,23 +1 @@ ODBC_VSN = 2.10.8 - -TICKETS = OTP-7452 OTP-8511 - -TICKETS_2.10.6 = \ - OTP-8250 \ - OTP-8291 - -TICKETS_2.10.5 = \ - OTP-7978 - -TICKETS_2.10.4 = \ - OTP-7720 \ - OTP-7721 - -TICKETS_2.10.3 = \ - OTP-7418 -TICKETS_2.10.2 = \ - OTP-7297 -TICKETS_2.10.1 = \ - OTP-7019 \ - OTP-7294 \ - OTP-7307 diff --git a/lib/orber/vsn.mk b/lib/orber/vsn.mk index ec349ee189..cf80e27a61 100644 --- a/lib/orber/vsn.mk +++ b/lib/orber/vsn.mk @@ -1,21 +1 @@ - ORBER_VSN = 3.6.16 - -TICKETS = OTP-8489 \ - OTP-8543 - -TICKETS_3.6.15 = OTP-8353 \ - OTP-8354 \ - OTP-8374 \ - OTP-8409 \ - OTP-8448 - -TICKETS_3.6.14 = OTP-8201 - -TICKETS_3.6.13 = OTP-7987 - -TICKETS_3.6.12 = OTP-7906 - -TICKETS_3.6.11 = OTP-7837 - -TICKETS_3.6.10 = OTP-7595 diff --git a/lib/parsetools/include/yeccpre.hrl b/lib/parsetools/include/yeccpre.hrl index 33a103d95f..39dea0552d 100644 --- a/lib/parsetools/include/yeccpre.hrl +++ b/lib/parsetools/include/yeccpre.hrl @@ -26,8 +26,8 @@ parse(Tokens) -> yeccpars0(Tokens, {no_func, no_line}, 0, [], []). --spec parse_and_scan({function() | {atom(), atom()}, [_]} | {atom(), atom(), [_]}) -> - yecc_ret(). +-spec parse_and_scan({function() | {atom(), atom()}, [_]} + | {atom(), atom(), [_]}) -> yecc_ret(). parse_and_scan({F, A}) -> % Fun or {M, F} yeccpars0([], {{F, A}, no_line}, 0, [], []); parse_and_scan({M, F, A}) -> @@ -44,7 +44,7 @@ format_error(Message) -> %% To be used in grammar files to throw an error message to the parser %% toplevel. Doesn't have to be exported! --compile({nowarn_unused_function,{return_error,2}}). +-compile({nowarn_unused_function, return_error/2}). -spec return_error(integer(), any()) -> no_return(). return_error(Line, Message) -> throw({error, {Line, ?MODULE, Message}}). @@ -57,10 +57,7 @@ yeccpars0(Tokens, Tzr, State, States, Vstack) -> error: Error -> Stacktrace = erlang:get_stacktrace(), try yecc_error_type(Error, Stacktrace) of - {syntax_error, Token} -> - yeccerror(Token); - {missing_in_goto_table=Tag, Symbol, State} -> - Desc = {Symbol, State, Tag}, + Desc -> erlang:raise(error, {yecc_bug, ?CODE_VERSION, Desc}, Stacktrace) catch _:_ -> erlang:raise(error, Error, Stacktrace) @@ -70,13 +67,15 @@ yeccpars0(Tokens, Tzr, State, States, Vstack) -> Error end. -yecc_error_type(function_clause, [{?MODULE,F,[State,_,_,_,Token,_,_]} | _]) -> +yecc_error_type(function_clause, [{?MODULE,F,ArityOrArgs} | _]) -> case atom_to_list(F) of - "yeccpars2" ++ _ -> - {syntax_error, Token}; "yeccgoto_" ++ SymbolL -> {ok,[{atom,_,Symbol}],_} = erl_scan:string(SymbolL), - {missing_in_goto_table, Symbol, State} + State = case ArityOrArgs of + [S,_,_,_,_,_,_] -> S; + _ -> state_is_unknown + end, + {Symbol, State, missing_in_goto_table} end. yeccpars1([Token | Tokens], Tzr, State, States, Vstack) -> @@ -141,11 +140,13 @@ yecctoken_end_location(Token) -> yecctoken_location(Token) end. +-compile({nowarn_unused_function, yeccerror/1}). yeccerror(Token) -> Text = yecctoken_to_string(Token), Location = yecctoken_location(Token), {error, {Location, ?MODULE, ["syntax error before: ", Text]}}. +-compile({nowarn_unused_function, yecctoken_to_string/1}). yecctoken_to_string(Token) -> case catch erl_scan:token_info(Token, text) of {text, Txt} -> Txt; @@ -158,6 +159,7 @@ yecctoken_location(Token) -> _ -> element(2, Token) end. +-compile({nowarn_unused_function, yecctoken2string/1}). yecctoken2string({atom, _, A}) -> io_lib:write(A); yecctoken2string({integer,_,N}) -> io_lib:write(N); yecctoken2string({float,_,F}) -> io_lib:write(F); diff --git a/lib/parsetools/src/yecc.erl b/lib/parsetools/src/yecc.erl index c4a47d008f..4119e2631b 100644 --- a/lib/parsetools/src/yecc.erl +++ b/lib/parsetools/src/yecc.erl @@ -1875,8 +1875,12 @@ format_conflict({Symbol, N, Reduce, Confl}) -> %% - "__Stack" has been substituted for "Stack"; %% - several states can share yeccpars2_S_cont(), which reduces code size; %% - instead if calling lists:nthtail() matching code is emitted. +%% +%% "1.4", parsetools-2.0.4: +%% - yeccerror() is called when a syntax error is found (as in version 1.1). +%% - the include file yeccpre.hrl has been changed. --define(CODE_VERSION, "1.3"). +-define(CODE_VERSION, "1.4"). -define(YECC_BUG(M, A), iolist_to_binary([" erlang:error({yecc_bug,\"",?CODE_VERSION,"\",", io_lib:fwrite(M, A), "}).\n\n"])). @@ -2106,13 +2110,11 @@ output_call_to_includefile(NewState, St) -> fwrite(St, <<" yeccpars1(S, ~w, Ss, Stack, T, Ts, Tzr)">>, [NewState]). -output_state_actions_fini(State, #yecc{includefile_version = {1,1}}=St0) -> - %% Backward compatibility. +output_state_actions_fini(State, St0) -> + %% Backward compatible. St10 = delim(St0, false), St = fwrite(St10, <<"yeccpars2_~w(_, _, _, _, T, _, _) ->\n">>, [State]), - fwrite(St, <<" yeccerror(T).\n\n">>, []); -output_state_actions_fini(_State, St) -> - fwrite(St, <<".\n\n">>, []). + fwrite(St, <<" yeccerror(T).\n\n">>, []). output_reduce(St0, State, Terminal0, #reduce{rule_nmbr = RuleNmbr, @@ -2416,7 +2418,7 @@ include1(Line, Inport, Outport, Nmbr_of_lines) -> include1(io:get_line(Inport, ''), Inport, Outport, Nmbr_of_lines + Incr). includefile_version([]) -> - {1,2}; + {1,4}; includefile_version(Includefile) -> case epp:open(Includefile, []) of {ok, Epp} -> @@ -2432,7 +2434,7 @@ includefile_version(Includefile) -> parse_file(Epp) -> case epp:parse_erl_form(Epp) of {ok, {function,_Line,yeccpars1,7,_Clauses}} -> - {1,2}; + {1,4}; {eof,_Line} -> {1,1}; _Form -> diff --git a/lib/parsetools/src/yeccparser.erl b/lib/parsetools/src/yeccparser.erl index 415547b4ce..63127802ee 100644 --- a/lib/parsetools/src/yeccparser.erl +++ b/lib/parsetools/src/yeccparser.erl @@ -38,16 +38,16 @@ line_of(Token) -> -type yecc_ret() :: {'error', _} | {'ok', _}. --spec parse(_) -> yecc_ret(). +-spec parse(Tokens :: list()) -> yecc_ret(). parse(Tokens) -> - yeccpars0(Tokens, false). + yeccpars0(Tokens, {no_func, no_line}, 0, [], []). --spec parse_and_scan({function() | {atom(), atom()}, [_]} | {atom(), atom(), [_]}) -> - yecc_ret(). +-spec parse_and_scan({function() | {atom(), atom()}, [_]} + | {atom(), atom(), [_]}) -> yecc_ret(). parse_and_scan({F, A}) -> % Fun or {M, F} - yeccpars0([], {F, A}); + yeccpars0([], {{F, A}, no_line}, 0, [], []); parse_and_scan({M, F, A}) -> - yeccpars0([], {{M, F}, A}). + yeccpars0([], {{{M, F}, A}, no_line}, 0, [], []). -spec format_error(any()) -> [char() | list()]. format_error(Message) -> @@ -60,54 +60,58 @@ format_error(Message) -> %% To be used in grammar files to throw an error message to the parser %% toplevel. Doesn't have to be exported! --compile({nowarn_unused_function,{return_error,2}}). +-compile({nowarn_unused_function, return_error/2}). -spec return_error(integer(), any()) -> no_return(). return_error(Line, Message) -> throw({error, {Line, ?MODULE, Message}}). --define(CODE_VERSION, "1.3"). +-define(CODE_VERSION, "1.4"). -yeccpars0(Tokens, MFA) -> - try yeccpars1(Tokens, MFA, 0, [], []) +yeccpars0(Tokens, Tzr, State, States, Vstack) -> + try yeccpars1(Tokens, Tzr, State, States, Vstack) catch error: Error -> Stacktrace = erlang:get_stacktrace(), try yecc_error_type(Error, Stacktrace) of - {syntax_error, Token} -> - yeccerror(Token); - {missing_in_goto_table=Tag, Symbol, State} -> - Desc = {Symbol, State, Tag}, + Desc -> erlang:raise(error, {yecc_bug, ?CODE_VERSION, Desc}, - Stacktrace) + Stacktrace) catch _:_ -> erlang:raise(error, Error, Stacktrace) end; - throw: {error, {_Line, ?MODULE, _M}} = Error -> - Error % probably from return_error/2 + %% Probably thrown from return_error/2: + throw: {error, {_Line, ?MODULE, _M}} = Error -> + Error end. -yecc_error_type(function_clause, [{?MODULE,F,[State,_,_,_,Token,_,_]} | _]) -> +yecc_error_type(function_clause, [{?MODULE,F,ArityOrArgs} | _]) -> case atom_to_list(F) of - "yeccpars2" ++ _ -> - {syntax_error, Token}; "yeccgoto_" ++ SymbolL -> {ok,[{atom,_,Symbol}],_} = erl_scan:string(SymbolL), - {missing_in_goto_table, Symbol, State} + State = case ArityOrArgs of + [S,_,_,_,_,_,_] -> S; + _ -> state_is_unknown + end, + {Symbol, State, missing_in_goto_table} end. -yeccpars1([Token | Tokens], Tokenizer, State, States, Vstack) -> - yeccpars2(State, element(1, Token), States, Vstack, Token, Tokens, - Tokenizer); -yeccpars1([], {F, A}, State, States, Vstack) -> +yeccpars1([Token | Tokens], Tzr, State, States, Vstack) -> + yeccpars2(State, element(1, Token), States, Vstack, Token, Tokens, Tzr); +yeccpars1([], {{F, A},_Line}, State, States, Vstack) -> case apply(F, A) of - {ok, Tokens, _Endline} -> - yeccpars1(Tokens, {F, A}, State, States, Vstack); - {eof, _Endline} -> - yeccpars1([], false, State, States, Vstack); + {ok, Tokens, Endline} -> + yeccpars1(Tokens, {{F, A}, Endline}, State, States, Vstack); + {eof, Endline} -> + yeccpars1([], {no_func, Endline}, State, States, Vstack); {error, Descriptor, _Endline} -> {error, Descriptor} end; -yeccpars1([], false, State, States, Vstack) -> - yeccpars2(State, '$end', States, Vstack, {'$end', 999999}, [], false). +yeccpars1([], {no_func, no_line}, State, States, Vstack) -> + Line = 999999, + yeccpars2(State, '$end', States, Vstack, yecc_end(Line), [], + {no_func, Line}); +yeccpars1([], {no_func, Endline}, State, States, Vstack) -> + yeccpars2(State, '$end', States, Vstack, yecc_end(Endline), [], + {no_func, Endline}). %% yeccpars1/7 is called from generated code. %% @@ -115,48 +119,73 @@ yeccpars1([], false, State, States, Vstack) -> %% yeccpars1/7 can be found by parsing the file without following %% include directives. yecc will otherwise assume that an old %% yeccpre.hrl is included (one which defines yeccpars1/5). -yeccpars1(State1, State, States, Vstack, Stack1, [Token | Tokens], - Tokenizer) -> +yeccpars1(State1, State, States, Vstack, Token0, [Token | Tokens], Tzr) -> yeccpars2(State, element(1, Token), [State1 | States], - [Stack1 | Vstack], Token, Tokens, Tokenizer); -yeccpars1(State1, State, States, Vstack, Stack1, [], {F, A}) -> - case apply(F, A) of - {ok, Tokens, _Endline} -> - yeccpars1(State1, State, States, Vstack, Stack1, Tokens, {F, A}); - {eof, _Endline} -> - yeccpars1(State1, State, States, Vstack, Stack1, [], false); - {error, Descriptor, _Endline} -> - {error, Descriptor} - end; -yeccpars1(State1, State, States, Vstack, Stack1, [], false) -> - yeccpars2(State, '$end', [State1 | States], [Stack1 | Vstack], - {'$end', 999999}, [], false). + [Token0 | Vstack], Token, Tokens, Tzr); +yeccpars1(State1, State, States, Vstack, Token0, [], {{_F,_A}, _Line}=Tzr) -> + yeccpars1([], Tzr, State, [State1 | States], [Token0 | Vstack]); +yeccpars1(State1, State, States, Vstack, Token0, [], {no_func, no_line}) -> + Line = yecctoken_end_location(Token0), + yeccpars2(State, '$end', [State1 | States], [Token0 | Vstack], + yecc_end(Line), [], {no_func, Line}); +yeccpars1(State1, State, States, Vstack, Token0, [], {no_func, Line}) -> + yeccpars2(State, '$end', [State1 | States], [Token0 | Vstack], + yecc_end(Line), [], {no_func, Line}). + +%% For internal use only. +yecc_end({Line,_Column}) -> + {'$end', Line}; +yecc_end(Line) -> + {'$end', Line}. + +yecctoken_end_location(Token) -> + try + {text, Str} = erl_scan:token_info(Token, text), + {line, Line} = erl_scan:token_info(Token, line), + Parts = re:split(Str, "\n"), + Dline = length(Parts) - 1, + Yline = Line + Dline, + case erl_scan:token_info(Token, column) of + {column, Column} -> + Col = byte_size(lists:last(Parts)), + {Yline, Col + if Dline =:= 0 -> Column; true -> 1 end}; + undefined -> + Yline + end + catch _:_ -> + yecctoken_location(Token) + end. -% For internal use only. yeccerror(Token) -> - Text = case catch erl_scan:token_info(Token, text) of - {text, Txt} -> Txt; - _ -> yecctoken2string(Token) - end, - Location = case catch erl_scan:token_info(Token, location) of - {location, Loc} -> Loc; - _ -> element(2, Token) - end, + Text = yecctoken_to_string(Token), + Location = yecctoken_location(Token), {error, {Location, ?MODULE, ["syntax error before: ", Text]}}. +yecctoken_to_string(Token) -> + case catch erl_scan:token_info(Token, text) of + {text, Txt} -> Txt; + _ -> yecctoken2string(Token) + end. + +yecctoken_location(Token) -> + case catch erl_scan:token_info(Token, location) of + {location, Loc} -> Loc; + _ -> element(2, Token) + end. + yecctoken2string({atom, _, A}) -> io_lib:write(A); yecctoken2string({integer,_,N}) -> io_lib:write(N); yecctoken2string({float,_,F}) -> io_lib:write(F); yecctoken2string({char,_,C}) -> io_lib:write_char(C); yecctoken2string({var,_,V}) -> io_lib:format("~s", [V]); yecctoken2string({string,_,S}) -> io_lib:write_unicode_string(S); -yecctoken2string({reserved_symbol, _, A}) -> io_lib:format("~w", [A]); -yecctoken2string({_Cat, _, Val}) -> io_lib:format("~w", [Val]); +yecctoken2string({reserved_symbol, _, A}) -> io_lib:write(A); +yecctoken2string({_Cat, _, Val}) -> io_lib:write(Val); yecctoken2string({dot, _}) -> "'.'"; yecctoken2string({'$end', _}) -> []; yecctoken2string({Other, _}) when is_atom(Other) -> - io_lib:format("~w", [Other]); + io_lib:write(Other); yecctoken2string(Other) -> io_lib:write(Other). @@ -164,7 +193,7 @@ yecctoken2string(Other) -> --file("yeccparser.erl", 168). +-file("yeccparser.erl", 196). yeccpars2(0=S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccpars2_0(S, Cat, Ss, Stack, T, Ts, Tzr); @@ -248,7 +277,9 @@ yeccpars2_0(S, integer, Ss, Stack, T, Ts, Tzr) -> yeccpars2_0(S, reserved_word, Ss, Stack, T, Ts, Tzr) -> yeccpars1(S, 8, Ss, Stack, T, Ts, Tzr); yeccpars2_0(S, var, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 9, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 9, Ss, Stack, T, Ts, Tzr); +yeccpars2_0(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_1(S, atom, Ss, Stack, T, Ts, Tzr) -> yeccpars1(S, 6, Ss, Stack, T, Ts, Tzr); @@ -267,10 +298,14 @@ yeccpars2_2(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccgoto_grammar(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr). yeccpars2_3(S, '->', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 10, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 10, Ss, Stack, T, Ts, Tzr); +yeccpars2_3(_, _, _, _, T, _, _) -> + yeccerror(T). -yeccpars2_4(_S, '$end', _Ss, Stack, _T, _Ts, _Tzr) -> - {ok, hd(Stack)}. +yeccpars2_4(_S, '$end', _Ss, Stack, _T, _Ts, _Tzr) -> + {ok, hd(Stack)}; +yeccpars2_4(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_5(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccgoto_grammar(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr). @@ -317,7 +352,9 @@ yeccpars2_13(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccgoto_symbols(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). yeccpars2_14(S, dot, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 29, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 29, Ss, Stack, T, Ts, Tzr); +yeccpars2_14(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_15(S, '->', Ss, Stack, T, Ts, Tzr) -> yeccpars1(S, 18, Ss, Stack, T, Ts, Tzr); @@ -338,7 +375,9 @@ yeccpars2_15(S, reserved_word, Ss, Stack, T, Ts, Tzr) -> yeccpars2_15(S, string, Ss, Stack, T, Ts, Tzr) -> yeccpars1(S, 26, Ss, Stack, T, Ts, Tzr); yeccpars2_15(S, var, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 27, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 27, Ss, Stack, T, Ts, Tzr); +yeccpars2_15(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_16(_S, Cat, Ss, Stack, T, Ts, Tzr) -> [_|Nss] = Ss, @@ -414,10 +453,14 @@ yeccpars2_29(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccgoto_rule(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). yeccpars2_30(S, dot, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 35, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 35, Ss, Stack, T, Ts, Tzr); +yeccpars2_30(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_31(S, dot, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 34, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 34, Ss, Stack, T, Ts, Tzr); +yeccpars2_31(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_32(S, string, Ss, Stack, T, Ts, Tzr) -> yeccpars1(S, 32, Ss, Stack, T, Ts, Tzr); @@ -486,7 +529,7 @@ yeccgoto_tokens(15=_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccgoto_tokens(17=_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccpars2_28(_S, Cat, Ss, Stack, T, Ts, Tzr). --compile({inline,{yeccpars2_6_,1}}). +-compile({inline,yeccpars2_6_/1}). -file("yeccgramm.yrl", 44). yeccpars2_6_(__Stack0) -> [__1 | __Stack] = __Stack0, @@ -494,7 +537,7 @@ yeccpars2_6_(__Stack0) -> symbol ( __1 ) end | __Stack]. --compile({inline,{yeccpars2_7_,1}}). +-compile({inline,yeccpars2_7_/1}). -file("yeccgramm.yrl", 45). yeccpars2_7_(__Stack0) -> [__1 | __Stack] = __Stack0, @@ -502,7 +545,7 @@ yeccpars2_7_(__Stack0) -> symbol ( __1 ) end | __Stack]. --compile({inline,{yeccpars2_8_,1}}). +-compile({inline,yeccpars2_8_/1}). -file("yeccgramm.yrl", 46). yeccpars2_8_(__Stack0) -> [__1 | __Stack] = __Stack0, @@ -510,7 +553,7 @@ yeccpars2_8_(__Stack0) -> symbol ( __1 ) end | __Stack]. --compile({inline,{yeccpars2_9_,1}}). +-compile({inline,yeccpars2_9_/1}). -file("yeccgramm.yrl", 43). yeccpars2_9_(__Stack0) -> [__1 | __Stack] = __Stack0, @@ -518,14 +561,14 @@ yeccpars2_9_(__Stack0) -> symbol ( __1 ) end | __Stack]. --compile({inline,{yeccpars2_11_,1}}). +-compile({inline,yeccpars2_11_/1}). -file("yeccgramm.yrl", 40). yeccpars2_11_(__Stack0) -> [begin { erlang_code , [ { atom , 0 , '$undefined' } ] } end | __Stack0]. --compile({inline,{yeccpars2_12_,1}}). +-compile({inline,yeccpars2_12_/1}). -file("yeccgramm.yrl", 35). yeccpars2_12_(__Stack0) -> [__1 | __Stack] = __Stack0, @@ -533,7 +576,7 @@ yeccpars2_12_(__Stack0) -> [ __1 ] end | __Stack]. --compile({inline,{yeccpars2_13_,1}}). +-compile({inline,yeccpars2_13_/1}). -file("yeccgramm.yrl", 36). yeccpars2_13_(__Stack0) -> [__2,__1 | __Stack] = __Stack0, @@ -541,7 +584,7 @@ yeccpars2_13_(__Stack0) -> [ __1 | __2 ] end | __Stack]. --compile({inline,{yeccpars2_16_,1}}). +-compile({inline,yeccpars2_16_/1}). -file("yeccgramm.yrl", 39). yeccpars2_16_(__Stack0) -> [__2,__1 | __Stack] = __Stack0, @@ -549,7 +592,7 @@ yeccpars2_16_(__Stack0) -> { erlang_code , __2 } end | __Stack]. --compile({inline,{yeccpars2_17_,1}}). +-compile({inline,yeccpars2_17_/1}). -file("yeccgramm.yrl", 41). yeccpars2_17_(__Stack0) -> [__1 | __Stack] = __Stack0, @@ -557,7 +600,7 @@ yeccpars2_17_(__Stack0) -> [ __1 ] end | __Stack]. --compile({inline,{yeccpars2_18_,1}}). +-compile({inline,yeccpars2_18_/1}). -file("yeccgramm.yrl", 55). yeccpars2_18_(__Stack0) -> [__1 | __Stack] = __Stack0, @@ -565,7 +608,7 @@ yeccpars2_18_(__Stack0) -> { '->' , line_of ( __1 ) } end | __Stack]. --compile({inline,{yeccpars2_19_,1}}). +-compile({inline,yeccpars2_19_/1}). -file("yeccgramm.yrl", 56). yeccpars2_19_(__Stack0) -> [__1 | __Stack] = __Stack0, @@ -573,7 +616,7 @@ yeccpars2_19_(__Stack0) -> { ':' , line_of ( __1 ) } end | __Stack]. --compile({inline,{yeccpars2_24_,1}}). +-compile({inline,yeccpars2_24_/1}). -file("yeccgramm.yrl", 53). yeccpars2_24_(__Stack0) -> [__1 | __Stack] = __Stack0, @@ -581,7 +624,7 @@ yeccpars2_24_(__Stack0) -> { value_of ( __1 ) , line_of ( __1 ) } end | __Stack]. --compile({inline,{yeccpars2_25_,1}}). +-compile({inline,yeccpars2_25_/1}). -file("yeccgramm.yrl", 54). yeccpars2_25_(__Stack0) -> [__1 | __Stack] = __Stack0, @@ -589,7 +632,7 @@ yeccpars2_25_(__Stack0) -> { value_of ( __1 ) , line_of ( __1 ) } end | __Stack]. --compile({inline,{yeccpars2_28_,1}}). +-compile({inline,yeccpars2_28_/1}). -file("yeccgramm.yrl", 42). yeccpars2_28_(__Stack0) -> [__2,__1 | __Stack] = __Stack0, @@ -597,7 +640,7 @@ yeccpars2_28_(__Stack0) -> [ __1 | __2 ] end | __Stack]. --compile({inline,{yeccpars2_29_,1}}). +-compile({inline,yeccpars2_29_/1}). -file("yeccgramm.yrl", 33). yeccpars2_29_(__Stack0) -> [__5,__4,__3,__2,__1 | __Stack] = __Stack0, @@ -605,7 +648,7 @@ yeccpars2_29_(__Stack0) -> { rule , [ __1 | __3 ] , __4 } end | __Stack]. --compile({inline,{yeccpars2_32_,1}}). +-compile({inline,yeccpars2_32_/1}). -file("yeccgramm.yrl", 37). yeccpars2_32_(__Stack0) -> [__1 | __Stack] = __Stack0, @@ -613,7 +656,7 @@ yeccpars2_32_(__Stack0) -> [ __1 ] end | __Stack]. --compile({inline,{yeccpars2_33_,1}}). +-compile({inline,yeccpars2_33_/1}). -file("yeccgramm.yrl", 38). yeccpars2_33_(__Stack0) -> [__2,__1 | __Stack] = __Stack0, @@ -621,7 +664,7 @@ yeccpars2_33_(__Stack0) -> [ __1 | __2 ] end | __Stack]. --compile({inline,{yeccpars2_34_,1}}). +-compile({inline,yeccpars2_34_/1}). -file("yeccgramm.yrl", 32). yeccpars2_34_(__Stack0) -> [__3,__2,__1 | __Stack] = __Stack0, @@ -629,7 +672,7 @@ yeccpars2_34_(__Stack0) -> { __1 , __2 } end | __Stack]. --compile({inline,{yeccpars2_35_,1}}). +-compile({inline,yeccpars2_35_/1}). -file("yeccgramm.yrl", 31). yeccpars2_35_(__Stack0) -> [__3,__2,__1 | __Stack] = __Stack0, diff --git a/lib/parsetools/test/yecc_SUITE.erl b/lib/parsetools/test/yecc_SUITE.erl index 61e2456323..93949a074a 100644 --- a/lib/parsetools/test/yecc_SUITE.erl +++ b/lib/parsetools/test/yecc_SUITE.erl @@ -298,8 +298,8 @@ syntax(Config) when is_list(Config) -> {_,[{L1,_,{undefined_function,{yeccpars2_2_,1}}}, {L2,_,{bad_inline,{yeccpars2_2_,1}}}]}], []} = compile:file(Parserfile1, [basic_validation,return]), - ?line L1 = 24 + SzYeccPre, - ?line L2 = 31 + SzYeccPre + ?line L1 = 28 + SzYeccPre, + ?line L2 = 35 + SzYeccPre end(), %% Bad macro in action. OTP-7224. @@ -316,8 +316,8 @@ syntax(Config) when is_list(Config) -> {_,[{L1,_,{undefined_function,{yeccpars2_2_,1}}}, {L2,_,{bad_inline,{yeccpars2_2_,1}}}]}], []} = compile:file(Parserfile1, [basic_validation,return]), - ?line L1 = 24 + SzYeccPre, - ?line L2 = 31 + SzYeccPre + ?line L1 = 28 + SzYeccPre, + ?line L2 = 35 + SzYeccPre end(), %% Check line numbers. OTP-7224. @@ -1584,8 +1584,8 @@ otp_7292(Config) when is_list(Config) -> {L2,_,{bad_inline,{yeccpars2_2_,1}}}]}], [{_,[{16,_,{unused_function,{foo,0}}}]}]} = compile:file(Parserfile1, [basic_validation, return]), - ?line L1 = 34 + SzYeccPre, - ?line L2 = 41 + SzYeccPre + ?line L1 = 38 + SzYeccPre, + ?line L2 = 45 + SzYeccPre end(), YeccPre = filename:join(Dir, "yeccpre.hrl"), @@ -1602,8 +1602,8 @@ otp_7292(Config) when is_list(Config) -> {L2,_,{bad_inline,{yeccpars2_2_,1}}}]}], [{_,[{16,_,{unused_function,{foo,0}}}]}]} = compile:file(Parserfile1, [basic_validation, return]), - ?line L1 = 33 + SzYeccPre, - ?line L2 = 40 + SzYeccPre + ?line L1 = 37 + SzYeccPre, + ?line L2 = 44 + SzYeccPre end(), file:delete(YeccPre), diff --git a/lib/parsetools/vsn.mk b/lib/parsetools/vsn.mk index f3e2dc0fb4..46915baed6 100644 --- a/lib/parsetools/vsn.mk +++ b/lib/parsetools/vsn.mk @@ -1 +1 @@ -PARSETOOLS_VSN = 2.0.3 +PARSETOOLS_VSN = 2.0.4 diff --git a/lib/public_key/doc/src/cert_records.xml b/lib/public_key/doc/src/cert_records.xml index 8cfe57f670..0d6113acef 100644 --- a/lib/public_key/doc/src/cert_records.xml +++ b/lib/public_key/doc/src/cert_records.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="latin1" ?> +<?xml version="1.0" encoding="iso-8859-1" ?> <!DOCTYPE chapter SYSTEM "chapter.dtd"> <chapter> @@ -37,7 +37,7 @@ <p>This chapter briefly describes erlang records derived from asn1 specifications used to handle X509 certificates. The intent is to describe the data types and not to specify the meaning of each - component for this we refer you to RFC 3280. + component for this we refer you to RFC 5280. </p> <p>Use the following include directive to get access to the @@ -45,11 +45,7 @@ <code> -include_lib("public_key/include/public_key.hrl"). </code> - <p>The used specification is available in <c>OTP-PKIX.asn1</c>, - which is an amelioration of - the <c>PKIX1Explicit88.asn1</c>, <c>PKIX1Implicit88.asn1</c> - and <c>PKIX1Algorithms88.asn1</c> modules. - You find all these modules in the <c>asn1</c> subdirectory + <p>The used asn1 specifications are available <c>asn1</c> subdirectory of the application <c>public_key</c>. </p> @@ -62,6 +58,9 @@ marker="public_key">public key reference manual </seealso> or follows here.</p> + <p><c>oid() - a tuple of integers + as generated by the asn1 compiler.</c></p> + <p><c>time() = uct_time() | general_time()</c></p> <p><c>uct_time() = {utcTime, "YYMMDDHHMMSSZ"} </c></p> @@ -119,9 +118,31 @@ algorithm, % oid() parameters % asn1_der_encoded() }. +</code> + +<code> +#'OTPCertificate'{ + tbsCertificate, % #'OTPTBSCertificate'{} + signatureAlgorithm, % #'SignatureAlgorithm' + signature % {0, binary()} - asn1 compact bitstring + }. + +#'OTPTBSCertificate'{ + version, % v1 | v2 | v3 + serialNumber, % integer() + signature, % #'SignatureAlgorithm' + issuer, % {rdnSequence, [#AttributeTypeAndValue'{}]} + validity, % #'Validity'{} + subject, % {rdnSequence, [#AttributeTypeAndValue'{}]} + subjectPublicKeyInfo, % #'SubjectPublicKeyInfo'{} + issuerUniqueID, % binary() | asn1_novalue + subjectUniqueID, % binary() | asn1_novalue + extensions % [#'Extension'{}] + }. + #'SignatureAlgorithm'{ algorithm, % id_signature_algorithm() - parameters % public_key_params() + parameters % asn1_novalue | #'Dss-Parms'{} }. </code> diff --git a/lib/public_key/doc/src/public_key.xml b/lib/public_key/doc/src/public_key.xml index dc9a96906f..c72719fac4 100644 --- a/lib/public_key/doc/src/public_key.xml +++ b/lib/public_key/doc/src/public_key.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="latin1" ?> +<?xml version="1.0" encoding="iso-8859-1" ?> <!DOCTYPE erlref SYSTEM "erlref.dtd"> <erlref> @@ -34,11 +34,7 @@ <modulesummary> API module for public key infrastructure.</modulesummary> <description> <p>This module provides functions to handle public key infrastructure - from RFC 3280 - X.509 certificates (will later be upgraded to RFC 5280) - and some parts of the PKCS-standard. - Currently this application is mainly used by the new - ssl implementation. The API is yet under construction - and only a few of the functions are currently documented and thereby supported. + from RFC 5280 - X.509 certificates and some parts of the PKCS-standard. </p> </description> @@ -62,37 +58,37 @@ <p><c>boolean() = true | false</c></p> - <p><c>string = [bytes()]</c></p> - - <p><c>asn1_der_encoded() = binary() | [bytes()]</c></p> + <p><c>string = [bytes()]</c></p> + + <p><c>der_encoded() = binary() </c></p> - <p><c>der_bin() = binary() </c></p> + <p><c>decrypt_der() = binary() </c></p> - <p><c>oid() - a tuple of integers - as generated by the asn1 compiler.</c></p> - - <p><c>public_key() = rsa_public_key() | dsa_public_key()</c></p> + <p><c>pki_asn1_type() = 'Certificate' | 'RSAPrivateKey'| + 'DSAPrivateKey' | 'DHParameter'</c></p> + <p><c>pem_entry () = {pki_asn1_type(), der_encoded() | decrypt_der(), not_encrypted | + {"DES-CBC" | "DES-EDE3-CBC", crypto:rand_bytes(8)}}.</c></p> + <p><c>rsa_public_key() = #'RSAPublicKey'{}</c></p> <p><c>rsa_private_key() = #'RSAPrivateKey'{} </c></p> - <p><c>dsa_public_key() = integer() </c></p> - - <p><c>public_key_params() = dsa_key_params() </c></p> - - <p><c>dsa_key_params() = #'Dss-Parms'{} </c></p> - - <p><c>private_key() = rsa_private_key() | dsa_private_key()</c></p> + <p><c>dsa_public_key() = {integer(), #'Dss-Parms'{}} </c></p> <p><c>rsa_private_key() = #'RSAPrivateKey'{} </c></p> <p><c>dsa_private_key() = #'DSAPrivateKey'{}</c></p> + + <p><c> public_crypt_options() = [{rsa_pad, rsa_padding()}]. </c></p> - <p><c>x509_certificate() = "#Certificate{}"</c></p> - - <p><c>x509_tbs_certificate() = #'TBSCertificate'{} </c></p> - + <p><c> rsa_padding() = 'rsa_pkcs1_padding' | 'rsa_pkcs1_oaep_padding' + | 'rsa_no_padding'</c></p> + + <p><c> rsa_digest_type() = 'md5' | 'sha' </c></p> + + <p><c> dss_digest_type() = 'none' | 'sha' </c></p> + <!-- <p><c>policy_tree() = [Root, Children]</c></p> --> <!-- <p><c>Root = #policy_tree_node{}</c></p> --> @@ -121,197 +117,301 @@ <!-- that would satisfy this policy in the certificate x+1. </item> --> <!-- </taglist> --> </section> - -<funcs> - <func> - <name>decode_private_key(KeyInfo) -> </name> - <name>decode_private_key(KeyInfo, Password) -> {ok, PrivateKey} | {error, Reason}</name> - <fsummary> Decodes an asn1 der encoded private key.</fsummary> - <type> - <v> KeyInfo = {KeyType, der_bin(), ChipherInfo} </v> - <d> As returned from pem_to_der/1 for private keys</d> - <v> KeyType = rsa_private_key | dsa_private_key </v> - <v> ChipherInfo = opaque() | no_encryption </v> - <d> ChipherInfo may contain encryption parameters if the private key is password - protected, these are opaque to the user just pass the value returned by pem_to_der/1 - to this function.</d> - <v> Password = string() </v> - <d>Must be specified if CipherInfo =/= no_encryption</d> - <v> PrivateKey = private_key() </v> - <v> Reason = term() </v> - </type> - <desc> - <p>Decodes an asn1 der encoded private key.</p> - </desc> - </func> - + +<funcs> + <func> - <name>pem_to_der(File) -> {ok, [Entry]}</name> - <fsummary>Reads a PEM file and translates it into its asn1 der - encoded parts.</fsummary> + <name>decrypt_private(CipherText, Key [, Options]) -> binary()</name> + <fsummary>Public key decryption.</fsummary> <type> - <v>File = path()</v> - <v>Password = string()</v> - <v>Entry = {entry_type(), der_bin(), CipherInfo}</v> - <v> ChipherInfo = opaque() | no_encryption </v> - <d> ChipherInfo may contain encryption parameters if the private key is password - protected, these will be handled by the function decode_private_key/2. </d> - <v>entry_type() = cert | cert_req | rsa_private_key | dsa_private_key | - dh_params </v> + <v>CipherText = binary()</v> + <v>Key = rsa_private_key()</v> + <v>Options = public_crypt_options()</v> </type> <desc> - <p>Reads a PEM file and translates it into its asn1 der - encoded parts.</p> + <p>Public key decryption using the private key.</p> + </desc> + </func> + + <func> + <name>decrypt_public(CipherText, Key [, Options]) - > binary()</name> + <fsummary></fsummary> + <type> + <v>CipherText = binary()</v> + <v>Key = rsa_public_key()</v> + <v>Options = public_crypt_options()</v> + </type> + <desc> + <p> Public key decryption using the public key.</p> </desc> </func> - - <func> - <name>pkix_decode_cert(Cert, Type) -> {ok, DecodedCert} | {error, Reason}</name> - <fsummary> Decodes an asn1 der encoded pkix certificate. </fsummary> - <type> - <v>Cert = asn1_der_encoded() </v> - <v>Type = plain | otp</v> - <v>DecodeCert = x509_certificate() </v> - <d>When type is specified as otp the asn1 spec OTP-PKIX.asn1 is used to decode known - extensions and enhance the signature field in - #'Certificate'{} and '#TBSCertificate'{}. This is currently used by the new ssl - implementation but not documented and supported for the public_key application.</d> - <v>Reason = term() </v> + + <func> + <name>der_decode(Asn1type, Der) -> term()</name> + <fsummary> Decodes a public key asn1 der encoded entity.</fsummary> + <type> + <v>Asn1Type = atom() -</v> + <d> Asn1 type present in the public_key applications + asn1 specifications.</d> + <v>Der = der_encoded()</v> </type> - <desc> - <p> Decodes an asn1 encoded pkix certificate.</p> + <desc> + <p> Decodes a public key asn1 der encoded entity.</p> </desc> </func> + + <func> + <name>der_encode(Asn1Type, Entity) -> der_encoded()</name> + <fsummary> Encodes a public key entity with asn1 DER encoding.</fsummary> + <type> + <v>Asn1Type = atom()</v> + <d> Asn1 type present in the public_key applications + asn1 specifications.</d> + <v>Entity = term() - The erlang representation of <c> Asn1Type</c></v> + </type> + <desc> + <p> Encodes a public key entity with asn1 DER encoding.</p> + </desc> + </func> + + <func> + <name>pem_decode(PemBin) -> [pem_entry()]</name> + <fsummary>Decode PEM binary data and return + entries as asn1 der encoded entities. </fsummary> + <type> + <v>PemBin = binary()</v> + <d>Example {ok, PemBin} = file:read_file("cert.pem").</d> + </type> + <desc> + <p>Decode PEM binary data and return + entries as asn1 der encoded entities.</p> + </desc> + </func> + + <func> + <name>pem_encode(PemEntries) -> binary()</name> + <fsummary>Creates a PEM binary</fsummary> + <type> + <v> PemEntries = [pem_entry()] </v> + </type> + <desc> + <p>Creates a PEM binary</p> + </desc> + </func> + + <func> + <name>pem_entry_decode(PemEntry [, Password]) -> term()</name> + <fsummary>Decodes a pem entry.</fsummary> + <type> + <v> PemEntry = pem_entry() </v> + <v> Password = string() </v> + </type> + <desc> + <p>Decodes a pem entry. pem_decode/1 returns a list of + pem entries.</p> + </desc> + </func> + + <func> + <name>pem_entry_encode(Asn1Type, Entity [,{CipherInfo, Password}]) -> pem_entry()</name> + <fsummary> Creates a pem entry that can be feed to pem_encode/1.</fsummary> + <type> + <v>Asn1Type = atom()</v> + <v>Entity = term()</v> + <v>CipherInfo = {"DES-CBC" | "DES-EDE3-CBC", crypto:rand_bytes(8)}</v> + <v>Password = string()</v> + </type> + <desc> + <p> Creates a pem entry that can be feed to pem_encode/1.</p> + </desc> + </func> + + <func> + <name>encrypt_private(PlainText, Key) -> binary()</name> + <fsummary> Public key encryption using the private key.</fsummary> + <type> + <v>PlainText = binary()</v> + <v>Key = rsa_private_key()</v> + </type> + <desc> + <p> Public key encryption using the private key.</p> + </desc> + </func> + + <func> + <name>encrypt_public(PlainText, Key) -> binary()</name> + <fsummary> Public key encryption using the public key.</fsummary> + <type> + <v>PlainText = binary()</v> + <v>Key = rsa_public_key()</v> + </type> + <desc> + <p> Public key encryption using the public key.</p> + </desc> + </func> -<!-- <func> --> -<!-- <name> pkix_encode_cert(Cert) -> {ok, EncodedCert} | {error, Reason}</name> --> -<!-- <fsummary>Encodes a certificate record using asn1. </fsummary> --> -<!-- <type> --> -<!-- <v>Cert = x509_certificate() </v> --> -<!-- <v>EncodedCert = asn1_der_encoded() </v> --> -<!-- <v>Reason = term() </v> --> -<!-- </type> --> -<!-- <desc> --> -<!-- <p> Encodes a certificate record using asn1.</p> --> -<!-- </desc> --> -<!-- </func> --> + <func> + <name> pkix_decode_cert(Cert, otp|plain) -> #'Certificate'{} | #'OTPCertificate'{}</name> + <fsummary> Decodes an asn1 der encoded pkix x509 certificate.</fsummary> + <type> + <v>Cert = der_encoded()</v> + </type> + <desc> + <p>Decodes an asn1 der encoded pkix certificate. The otp option + will use the customized asn1 specification OTP-PKIX.asn1 for + decoding and also recursively decode most of the standard + parts.</p> + </desc> + </func> -<!-- <func> --> -<!-- <name>pkix_path_validation(TrustedCert, CertChain, Options) -> {ok, Result} | {error, Reason}</name> --> - -<!-- <fsummary>Performs a basic path validation according to RFC 3280</fsummary> --> -<!-- <type> --> -<!-- <v>TrustedCert = asn1_der_encoded()</v> --> -<!-- <v>CertChain = [asn1_der_encoded()]</v> --> -<!-- <v>Options = [{Option, Value}]</v> --> -<!-- <v>Result = {{algorithm(), public_key(), --> -<!-- public_key_params()}, policy_tree()}</v> --> -<!-- </type> --> + <func> + <name>pkix_encode(Asn1Type, Entity, otp | plain) -> der_encoded()</name> + <fsummary>Der encodes a pkix x509 certificate or part of such a + certificate.</fsummary> + <type> + <v>Asn1Type = atom()</v> + <d>The asn1 type can be 'Certificate', 'OTPCertificate' or a subtype of either .</d> + </type> + <desc> + <p>Der encodes a pkix x509 certificate or part of such a + certificate. This function must be used for encoding certificates or parts of certificates + that are decoded/created on the otp format, whereas for the plain format this + function will directly call der_encode/2. </p> + </desc> + </func> + + <func> + <name>pkix_is_issuer(Cert, IssuerCert) -> boolean()</name> + <fsummary> Checks if <c>IssuerCert</c> issued <c>Cert</c> </fsummary> + <type> + <v>Cert = der_encode() | #'OTPCertificate'{}</v> + <v>IssuerCert = der_encode() | #'OTPCertificate'{}</v> + </type> + <desc> + <p> Checks if <c>IssuerCert</c> issued <c>Cert</c> </p> + </desc> + </func> + + <func> + <name>pkix_is_fixed_dh_cert(Cert) -> boolean()</name> + <fsummary> Checks if a Certificate is a fixed Diffie-Hellman Cert.</fsummary> + <type> + <v>Cert = der_encode() | #'OTPCertificate'{}</v> + </type> + <desc> + <p> Checks if a Certificate is a fixed Diffie-Hellman Cert.</p> + </desc> + </func> + + <func> + <name>pkix_is_self_signed(Cert) -> boolean()</name> + <fsummary> Checks if a Certificate is self signed.</fsummary> + <type> + <v>Cert = der_encode() | #'OTPCertificate'{}</v> + </type> + <desc> + <p> Checks if a Certificate is self signed.</p> + </desc> + </func> + + <func> + <name>pkix_issuer_id(Cert, IssuedBy) -> {ok, IssuerID} | {error, Reason}</name> + <fsummary> Returns the issuer id.</fsummary> + <type> + <v>Cert = der_encode() | #'OTPCertificate'{}</v> + <v>IssuedBy = self | other</v> + <v>IssuerID = {integer(), {rdnSequence, [#'AttributeTypeAndValue'{}]}}</v> + <d>The issuer id consists of the serial number and the issuers name.</d> + <v>Reason = term()</v> + </type> + <desc> + <p> Returns the issuer id.</p> + </desc> + </func> -<!-- <desc> --> -<!-- <p>Available options are: </p> --> -<!-- <taglist> --> -<!-- <tag>{validate_extension_fun, fun()}</tag> --> -<!-- <item> A fun behaving according to the following outline: --> -<!-- <code> --> -<!-- [...] --> -<!-- ValidateExtensionFun = fun(Extensions, UserState) -> --> -<!-- validate_extensions(Extensions, UserState, []) --> -<!-- end, --> -<!-- [...] --> + <func> + <name>pkix_normalize_name(Issuer) -> Normalized</name> + <fsummary>Normalizes a issuer name so that it can be easily + compared to another issuer name. </fsummary> + <type> + <v>Issuer = {rdnSequence,[#'AttributeTypeAndValue'{}]}</v> + <v>Normalized = {rdnSequence, [#'AttributeTypeAndValue'{}]}</v> + </type> + <desc> + <p>Normalizes a issuer name so that it can be easily + compared to another issuer name.</p> + </desc> + </func> + + <!-- <func> --> + <!-- <name>pkix_path_validation()</name> --> + <!-- <fsummary> Performs a basic path validation according to RFC 5280.</fsummary> --> + <!-- <type> --> + <!-- <v></v> --> + <!-- </type> --> + <!-- <desc> --> + <!-- <p> Performs a basic path validation according to RFC 5280.</p> --> + <!-- </desc> --> + <!-- </func> --> -<!-- validate_extensions([], UserState, UnknowExtension) -> --> -<!-- {UserState, UnknowExtension}; --> -<!-- validate_extensions([#'Extension'{} = Ext | Rest], UserState, UnknowExtension) -> --> -<!-- case valid_extension(Ext) of --> -<!-- {true, NewUserState} -> --> -<!-- validate_extensions(Rest, NewUserState, UnknowExtension); --> -<!-- unknown -> --> -<!-- validate_extensions(Rest, UserState, [Ext | UnknowExtension]); --> -<!-- {false, Reason} -> --> -<!-- throw(bad_cert, Reason) --> -<!-- end. --> -<!-- </code> --> - -<!-- </item> --> - -<!-- <tag>{policy_set, [oid()]}</tag> --> -<!-- <item>A set of certificate policy --> -<!-- identifiers naming the policies that are acceptable to the --> -<!-- certificate user. If the user is not concerned about --> -<!-- certificate policy there is no need --> -<!-- to set this option. Defaults to the --> -<!-- special value [?anyPolicy]. --> -<!-- </item> --> - -<!-- <tag>{policy_mapping, boolean()}</tag> --> -<!-- <item>Indicates if policy --> -<!-- mapping, initially, is allowed in the certification path. --> -<!-- Defaults to false. --> -<!-- </item> --> - -<!-- <tag> {explicit_policy, boolean()}</tag> --> -<!-- <item>Indicates if the path, initially, must be --> -<!-- valid for at least one of the certificate policies in the user --> -<!-- specified policy set. --> -<!-- Defaults to false. --> -<!-- </item> --> + + <func> + <name>pkix_sign(#'OTPTBSCertificate'{}, Key) -> der_encode()</name> + <fsummary>Signs certificate.</fsummary> + <type> + <v>Key = rsa_public_key() | dsa_public_key()</v> + </type> + <desc> + <p>Signs a 'OTPTBSCertificate'. Returns the corresponding + der encoded certificate.</p> + </desc> + </func> -<!-- <tag>{inhibit_any_policy, boolean()}</tag> --> -<!-- <item>Indicates whether the anyPolicy OID, initially, should --> -<!-- be processed if it is included in a certificate. --> -<!-- Defaults to false. --> -<!-- </item> --> - -<!-- </taglist> --> - -<!-- <p>Performs a basic path validation according to RFC 3280, --> -<!-- e.i. signature validation, time validation, issuer validation, --> -<!-- alternative subject name validation, CRL validation, policy --> -<!-- validation and checks that no unknown extensions --> -<!-- are marked as critical. The option <c>validate_extension_fun</c> --> -<!-- may be used to validate application specific extensions. If --> -<!-- a validation criteria is found to be invalid the validation process --> -<!-- will immediately be stopped and this functions will return --> -<!-- {error, Reason}. --> -<!-- </p> --> -<!-- </desc> --> -<!-- </func> --> + <func> + <name>pkix_verify(Cert, Key) -> boolean()</name> + <fsummary> Verify pkix x.509 certificate signature.</fsummary> + <type> + <v>Cert = der_encode()</v> + <v>Key = rsa_public_key() | dsa_public_key()</v> + </type> + <desc> + <p> Verify pkix x.509 certificate signature.</p> + </desc> + </func> -<!-- <func> --> -<!-- <name>sign(DigestOrTBSCert, Key) -> </name> --> -<!-- <name>sign(DigestOrTBSCert, Key, KeyParams) -> {ok, SignatureOrDerCert} | {error, Reason}</name> --> -<!-- <fsummary>Signs Digest/Certificate using Key.</fsummary> --> -<!-- <type> --> -<!-- <v>DigestOrTBSCert = binary() | x509_tbs_certificate()</v> --> -<!-- <v>Key = private_key()</v> --> -<!-- <v>SignatureORDerCert = binary() | der_bin() </v> --> -<!-- <v>Reason = term() </v> --> -<!-- </type> --> -<!-- <desc> --> -<!-- <p> Signs Digest/Certificate using Key, in the later --> -<!-- case a der encoded x509_certificate() will be returned. </p> --> -<!-- </desc> --> -<!-- </func> --> + <func> + <name>sign(Msg, DigestType, Key) -> binary()</name> + <fsummary> Create digital signature.</fsummary> + <type> + <v>Msg = binary()</v> + <d>The msg is either the binary "plain text" data to be + signed or in the case that digest type is <c>none</c> + it is the hashed value of "plain text" i.e. the digest.</d> + <v>DigestType = rsa_digest_type() | dsa_digest_type()</v> + <v>Key = rsa_public_key() | dsa_public_key()</v> + </type> + <desc> + <p> Creates a digital signature.</p> + </desc> + </func> -<!-- <func> --> -<!-- <name>verify_signature(Digest, Signature, Key) -> </name> --> -<!-- <name>verify_signature(DerCert, Key, KeyParams) -> </name> --> -<!-- <name>verify_signature(Digest, Signature, Key, Params) -> Verified </name> --> -<!-- <fsummary> Verifies the signature. </fsummary> --> -<!-- <type> --> -<!-- <v>Digest = binary() </v> --> -<!-- <v>DerCert = der_bin() </v> --> -<!-- <v>Signature = binary() </v> --> -<!-- <v>Key = public_key() </v> --> -<!-- <v>Params = key_params()</v> --> -<!-- <v>Verified = boolean()</v> --> -<!-- </type> --> -<!-- <desc> --> -<!-- <p> Verifies the signature Signature. If the key is an rsa-key no --> -<!-- paramters are neeed.</p> --> -<!-- </desc> --> -<!-- </func> --> + <func> + <name>verify(Msg, DigestType, Signature, Key) -> boolean()</name> + <fsummary>Verifies a digital signature.</fsummary> + <type> + <v>Msg = binary()</v> + <d>The msg is either the binary "plain text" data + or in the case that digest type is <c>none</c> + it is the hashed value of "plain text" i.e. the digest.</d> + <v>DigestType = rsa_digest_type() | dsa_digest_type()</v> + <v>Signature = binary()</v> + <v>Key = rsa_public_key() | dsa_public_key()</v> + </type> + <desc> + <p>Verifies a digital signature</p> + </desc> + </func> + </funcs> </erlref> diff --git a/lib/public_key/include/public_key.hrl b/lib/public_key/include/public_key.hrl index fbce10f0eb..82681502ab 100644 --- a/lib/public_key/include/public_key.hrl +++ b/lib/public_key/include/public_key.hrl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2009. All Rights Reserved. +%% Copyright Ericsson AB 2008-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 @@ -28,6 +28,13 @@ algorithm, parameters = asn1_NOVALUE}). +-define(DEFAULT_VERIFYFUN, + {fun(_,{bad_cert, _} = Reason, _) -> + {fail, Reason}; + (_,{extension, _}, UserState) -> + {unknown, UserState} + end, []}). + -record(path_validation_state, { valid_policy_tree, explicit_policy, @@ -42,7 +49,7 @@ working_public_key_parameters, working_issuer_name, max_path_length, - acc_errors, %% If verify_none option is set + verify_fun, user_state }). @@ -59,4 +66,13 @@ interim_reasons_mask }). + +-type der_encoded() :: binary(). +-type decrypt_der() :: binary(). +-type pki_asn1_type() :: 'Certificate' | 'RSAPrivateKey' + | 'DSAPrivateKey' | 'DHParameter'. +-type pem_entry() :: {pki_asn1_type(), der_encoded() | decrypt_der(), + not_encrypted | {Cipher :: string(), Salt :: binary()}}. +-type asn1_type() :: atom(). %% see "OTP-PUB-KEY.hrl + -endif. % -ifdef(public_key). diff --git a/lib/public_key/src/Makefile b/lib/public_key/src/Makefile index c30399f33a..51f405361b 100644 --- a/lib/public_key/src/Makefile +++ b/lib/public_key/src/Makefile @@ -42,8 +42,7 @@ MODULES = \ public_key \ pubkey_pem \ pubkey_cert \ - pubkey_cert_records \ - pubkey_crypto + pubkey_cert_records HRL_FILES = $(INCLUDE)/public_key.hrl diff --git a/lib/public_key/src/pubkey_cert.erl b/lib/public_key/src/pubkey_cert.erl index 0651dcec29..b3c230df25 100644 --- a/lib/public_key/src/pubkey_cert.erl +++ b/lib/public_key/src/pubkey_cert.erl @@ -23,14 +23,13 @@ -include("public_key.hrl"). --export([verify_signature/3, - init_validation_state/3, prepare_for_next_cert/2, +-export([init_validation_state/3, prepare_for_next_cert/2, validate_time/3, validate_signature/6, validate_issuer/4, validate_names/6, validate_revoked_status/3, validate_extensions/4, - validate_unknown_extensions/3, normalize_general_name/1, digest_type/1, is_self_signed/1, - is_issuer/2, issuer_id/2, is_fixed_dh_cert/1]). + is_issuer/2, issuer_id/2, is_fixed_dh_cert/1, + verify_data/1]). -define(NULL, 0). @@ -38,10 +37,22 @@ %% Internal application API %%==================================================================== -verify_signature(DerCert, Key, KeyParams) -> - {ok, OtpCert} = pubkey_cert_records:decode_cert(DerCert, otp), - verify_signature(OtpCert, DerCert, Key, KeyParams). +%%-------------------------------------------------------------------- +-spec verify_data(der_encoded()) -> {md5 | sha, binary(), binary()}. +%% +%% Description: Extracts data from DerCert needed to call public_key:verify/4. +%%-------------------------------------------------------------------- +verify_data(DerCert) -> + {ok, OtpCert} = pubkey_cert_records:decode_cert(DerCert), + extract_verify_data(OtpCert, DerCert). +%%-------------------------------------------------------------------- +-spec init_validation_state(#'OTPCertificate'{}, integer(), list()) -> + #path_validation_state{}. +%% +%% Description: Creates inital version of path_validation_state for +%% basic path validation of x509 certificates. +%%-------------------------------------------------------------------- init_validation_state(#'OTPCertificate'{} = OtpCert, DefaultPathLen, Options) -> PolicyTree = #policy_tree_node{valid_policy = ?anyPolicy, @@ -56,16 +67,23 @@ init_validation_state(#'OTPCertificate'{} = OtpCert, DefaultPathLen, Options, false)), PolicyMapping = policy_indicator(MaxLen, proplists:get_value(policy_mapping, Options, false)), - AccErrors = proplists:get_value(acc_errors, Options, []), - State = #path_validation_state{max_path_length = MaxLen, - valid_policy_tree = PolicyTree, - explicit_policy = ExplicitPolicy, - inhibit_any_policy = InhibitAnyPolicy, - policy_mapping = PolicyMapping, - acc_errors = AccErrors, + {VerifyFun, UserState} = proplists:get_value(verify_fun, Options, ?DEFAULT_VERIFYFUN), + State = #path_validation_state{max_path_length = MaxLen, + valid_policy_tree = PolicyTree, + explicit_policy = ExplicitPolicy, + inhibit_any_policy = InhibitAnyPolicy, + policy_mapping = PolicyMapping, + verify_fun = VerifyFun, + user_state = UserState, cert_num = 0}, prepare_for_next_cert(OtpCert, State). +%%-------------------------------------------------------------------- +-spec prepare_for_next_cert(#'OTPCertificate'{}, #path_validation_state{}) -> + #path_validation_state{}. +%% +%% Description: Update path_validation_state for next iteration. +%%-------------------------------------------------------------------- prepare_for_next_cert(OtpCert, ValidationState = #path_validation_state{ working_public_key_algorithm = PrevAlgo, working_public_key_parameters = @@ -92,8 +110,14 @@ prepare_for_next_cert(OtpCert, ValidationState = #path_validation_state{ working_issuer_name = Issuer, cert_num = ValidationState#path_validation_state.cert_num + 1 }. - -validate_time(OtpCert, AccErr, Verify) -> + + %%-------------------------------------------------------------------- +-spec validate_time(#'OTPCertificate'{}, term(), fun()) -> term(). +%% +%% Description: Check that the certificate validity period includes the +%% current time. +%%-------------------------------------------------------------------- +validate_time(OtpCert, UserState, VerifyFun) -> TBSCert = OtpCert#'OTPCertificate'.tbsCertificate, {'Validity', NotBeforeStr, NotAfterStr} = TBSCert#'OTPTBSCertificate'.validity, @@ -103,34 +127,52 @@ validate_time(OtpCert, AccErr, Verify) -> case ((NotBefore =< Now) and (Now =< NotAfter)) of true -> - AccErr; + UserState; false -> - not_valid({bad_cert, cert_expired}, Verify, AccErr) + verify_fun(OtpCert, {bad_cert, cert_expired}, UserState, VerifyFun) end. - -validate_issuer(OtpCert, Issuer, AccErr, Verify) -> +%%-------------------------------------------------------------------- +-spec validate_issuer(#'OTPCertificate'{}, term(), term(), fun()) -> term(). +%% +%% Description: Check that the certificate issuer name is the working_issuer_name +%% in path_validation_state. +%%-------------------------------------------------------------------- +validate_issuer(OtpCert, Issuer, UserState, VerifyFun) -> TBSCert = OtpCert#'OTPCertificate'.tbsCertificate, case is_issuer(Issuer, TBSCert#'OTPTBSCertificate'.issuer) of true -> - AccErr; + UserState; _ -> - not_valid({bad_cert, invalid_issuer}, Verify, AccErr) + verify_fun(OtpCert, {bad_cert, invalid_issuer}, UserState, VerifyFun) end. - +%%-------------------------------------------------------------------- +-spec validate_signature(#'OTPCertificate'{}, der_encoded(), + term(),term(), term(), fun()) -> term(). + +%% +%% Description: Check that the signature on the certificate can be verified using +%% working_public_key_algorithm, the working_public_key, and +%% the working_public_key_parameters in path_validation_state. +%%-------------------------------------------------------------------- validate_signature(OtpCert, DerCert, Key, KeyParams, - AccErr, Verify) -> + UserState, VerifyFun) -> case verify_signature(OtpCert, DerCert, Key, KeyParams) of true -> - AccErr; + UserState; false -> - not_valid({bad_cert, invalid_signature}, Verify, AccErr) + verify_fun(OtpCert, {bad_cert, invalid_signature}, UserState, VerifyFun) end. - -validate_names(OtpCert, Permit, Exclude, Last, AccErr, Verify) -> +%%-------------------------------------------------------------------- +-spec validate_names(#'OTPCertificate'{}, list(), list(), + term(), term(), fun())-> term(). +%% +%% Description: Validate Subject Alternative Name. +%%-------------------------------------------------------------------- +validate_names(OtpCert, Permit, Exclude, Last, UserState, VerifyFun) -> case is_self_signed(OtpCert) andalso (not Last) of true -> - AccErr; + UserState; false -> TBSCert = OtpCert#'OTPCertificate'.tbsCertificate, Subject = TBSCert#'OTPTBSCertificate'.subject, @@ -143,8 +185,10 @@ validate_names(OtpCert, Permit, Exclude, Last, AccErr, Verify) -> Name = [{directoryName, Subject}|EmailAddress], AltNames = case AltSubject of - undefined -> []; - _ -> AltSubject#'Extension'.extnValue + undefined -> + []; + _ -> + AltSubject#'Extension'.extnValue end, case (is_permitted(Name, Permit) andalso @@ -152,65 +196,69 @@ validate_names(OtpCert, Permit, Exclude, Last, AccErr, Verify) -> (not is_excluded(Name, Exclude)) andalso (not is_excluded(AltNames, Exclude))) of true -> - AccErr; + UserState; false -> - not_valid({bad_cert, name_not_permitted}, - Verify, AccErr) + verify_fun(OtpCert, {bad_cert, name_not_permitted}, + UserState, VerifyFun) end end. - -%% See rfc3280 4.1.2.6 Subject: regarding emails. -extract_email({rdnSequence, List}) -> - extract_email2(List). -extract_email2([[#'AttributeTypeAndValue'{type=?'id-emailAddress', - value=Mail}]|_]) -> - [{rfc822Name, Mail}]; -extract_email2([_|Rest]) -> - extract_email2(Rest); -extract_email2([]) -> []. - -validate_revoked_status(_OtpCert, _Verify, AccErr) -> - %% true | +%%-------------------------------------------------------------------- +-spec validate_revoked_status(#'OTPCertificate'{}, term(), fun()) -> + term(). +%% +%% Description: Check if certificate has been revoked. +%%-------------------------------------------------------------------- +validate_revoked_status(_OtpCert, UserState, _VerifyFun) -> + %% TODO: Implement or leave for application?! + %% valid | %% throw({bad_cert, cert_revoked}) - AccErr. - -validate_extensions(OtpCert, ValidationState, Verify, AccErr) -> + UserState. +%%-------------------------------------------------------------------- +-spec validate_extensions(#'OTPCertificate'{}, #path_validation_state{}, + term(), fun())-> + {#path_validation_state{}, UserState :: term()}. +%% +%% Description: Check extensions included in basic path validation. +%%-------------------------------------------------------------------- +validate_extensions(OtpCert, ValidationState, UserState, VerifyFun) -> TBSCert = OtpCert#'OTPCertificate'.tbsCertificate, Extensions = TBSCert#'OTPTBSCertificate'.extensions, - validate_extensions(Extensions, ValidationState, no_basic_constraint, - is_self_signed(OtpCert), [], Verify, AccErr). - -validate_unknown_extensions([], AccErr, _Verify) -> - AccErr; -validate_unknown_extensions([#'Extension'{critical = true} | _], - AccErr, Verify) -> - not_valid({bad_cert, unknown_critical_extension}, Verify, AccErr); -validate_unknown_extensions([#'Extension'{critical = false} | Rest], - AccErr, Verify) -> - validate_unknown_extensions(Rest, AccErr, Verify). + validate_extensions(OtpCert, Extensions, ValidationState, no_basic_constraint, + is_self_signed(OtpCert), UserState, VerifyFun). +%%-------------------------------------------------------------------- +-spec normalize_general_name({rdnSequence, term()}) -> {rdnSequence, term()}. +%% +%% Description: Normalizes a general name so that it can be easily +%% compared to another genral name. +%%-------------------------------------------------------------------- normalize_general_name({rdnSequence, Issuer}) -> - NormIssuer = normalize_general_name(Issuer), - {rdnSequence, NormIssuer}; - -normalize_general_name(Issuer) -> - Normalize = fun([{Description, Type, {printableString, Value}}]) -> - NewValue = string:to_lower(strip_spaces(Value)), - [{Description, Type, {printableString, NewValue}}]; - (Atter) -> - Atter - end, - lists:sort(lists:map(Normalize, Issuer)). + NormIssuer = do_normalize_general_name(Issuer), + {rdnSequence, NormIssuer}. +%%-------------------------------------------------------------------- +-spec is_self_signed(#'OTPCertificate'{}) -> boolean(). +%% +%% Description: Checks if the certificate is self signed. +%%-------------------------------------------------------------------- is_self_signed(#'OTPCertificate'{tbsCertificate= #'OTPTBSCertificate'{issuer = Issuer, subject = Subject}}) -> is_issuer(Issuer, Subject). - +%%-------------------------------------------------------------------- +-spec is_issuer({rdnSequence, term()}, {rdnSequence, term()}) -> boolean(). +%% +%% Description: Checks if <Issuer> issued <Candidate>. +%%-------------------------------------------------------------------- is_issuer({rdnSequence, Issuer}, {rdnSequence, Candidate}) -> is_dir_name(Issuer, Candidate, true). - +%%-------------------------------------------------------------------- +-spec issuer_id(#'OTPCertificate'{}, self | other) -> + {ok, {integer(), term()}} | {error, issuer_not_found}. +%% +%% Description: Extracts the issuer id from a certificate if possible. +%%-------------------------------------------------------------------- issuer_id(Otpcert, other) -> TBSCert = Otpcert#'OTPCertificate'.tbsCertificate, Extensions = extensions_list(TBSCert#'OTPTBSCertificate'.extensions), @@ -227,7 +275,12 @@ issuer_id(Otpcert, self) -> SerialNr = TBSCert#'OTPTBSCertificate'.serialNumber, {ok, {SerialNr, normalize_general_name(Issuer)}}. - +%%-------------------------------------------------------------------- +-spec is_fixed_dh_cert(#'OTPCertificate'{}) -> boolean(). +%% +%% Description: Checks if the certificate can be be used +%% for DH key agreement. +%%-------------------------------------------------------------------- is_fixed_dh_cert(#'OTPCertificate'{tbsCertificate = #'OTPTBSCertificate'{subjectPublicKeyInfo = SubjectPublicKeyInfo, @@ -238,28 +291,66 @@ is_fixed_dh_cert(#'OTPCertificate'{tbsCertificate = %%-------------------------------------------------------------------- %%% Internal functions %%-------------------------------------------------------------------- +do_normalize_general_name(Issuer) -> + Normalize = fun([{Description, Type, {printableString, Value}}]) -> + NewValue = string:to_lower(strip_spaces(Value)), + [{Description, Type, {printableString, NewValue}}]; + (Atter) -> + Atter + end, + lists:sort(lists:map(Normalize, Issuer)). + +%% See rfc3280 4.1.2.6 Subject: regarding emails. +extract_email({rdnSequence, List}) -> + extract_email2(List). +extract_email2([[#'AttributeTypeAndValue'{type=?'id-emailAddress', + value=Mail}]|_]) -> + [{rfc822Name, Mail}]; +extract_email2([_|Rest]) -> + extract_email2(Rest); +extract_email2([]) -> []. extensions_list(asn1_NOVALUE) -> []; extensions_list(Extensions) -> Extensions. -not_valid(Error, true, _) -> - throw(Error); -not_valid(Error, false, AccErrors) -> - [Error | AccErrors]. +verify_fun(Otpcert, Result, UserState0, VerifyFun) -> + case VerifyFun(Otpcert, Result, UserState0) of + {valid,UserState} -> + UserState; + {fail, Reason} -> + case Result of + {bad_cert, _} -> + throw(Result); + _ -> + throw({bad_cert, Reason}) + end; + {unknown, UserState} -> + case Result of + {extension, #'Extension'{critical = true}} -> + throw({bad_cert, unknown_critical_extension}); + _ -> + UserState + end + end. -verify_signature(OtpCert, DerCert, Key, KeyParams) -> - %% Signature is an ASN1 compact bit string +extract_verify_data(OtpCert, DerCert) -> {0, Signature} = OtpCert#'OTPCertificate'.signature, SigAlgRec = OtpCert#'OTPCertificate'.signatureAlgorithm, SigAlg = SigAlgRec#'SignatureAlgorithm'.algorithm, - EncTBSCert = encoded_tbs_cert(DerCert), - verify(SigAlg, EncTBSCert, Signature, Key, KeyParams). + PlainText = encoded_tbs_cert(DerCert), + DigestType = digest_type(SigAlg), + {DigestType, PlainText, Signature}. -verify(Alg, PlainText, Signature, Key, KeyParams) -> - public_key:verify_signature(PlainText, digest_type(Alg), - Signature, Key, KeyParams). +verify_signature(OtpCert, DerCert, Key, KeyParams) -> + {DigestType, PlainText, Signature} = extract_verify_data(OtpCert, DerCert), + case Key of + #'RSAPublicKey'{} -> + public_key:verify(PlainText, DigestType, Signature, Key); + _ -> + public_key:verify(PlainText, DigestType, Signature, {Key, KeyParams}) + end. encoded_tbs_cert(Cert) -> {ok, PKIXCert} = @@ -369,198 +460,189 @@ select_extension(Id, [_ | Extensions]) -> select_extension(Id, Extensions). %% No extensions present -validate_extensions(asn1_NOVALUE, ValidationState, ExistBasicCon, - SelfSigned, UnknownExtensions, Verify, AccErr) -> - validate_extensions([], ValidationState, ExistBasicCon, - SelfSigned, UnknownExtensions, Verify, AccErr); - -validate_extensions([], ValidationState, basic_constraint, _SelfSigned, - UnknownExtensions, _Verify, AccErr) -> - {ValidationState, UnknownExtensions, AccErr}; -validate_extensions([], ValidationState = - #path_validation_state{max_path_length = Len, - last_cert = Last}, - no_basic_constraint, SelfSigned, UnknownExtensions, - Verify, AccErr0) -> +validate_extensions(OtpCert, asn1_NOVALUE, ValidationState, ExistBasicCon, + SelfSigned, UserState, VerifyFun) -> + validate_extensions(OtpCert, [], ValidationState, ExistBasicCon, + SelfSigned, UserState, VerifyFun); + +validate_extensions(_,[], ValidationState, basic_constraint, _SelfSigned, + UserState, _) -> + {ValidationState, UserState}; +validate_extensions(OtpCert, [], ValidationState = + #path_validation_state{max_path_length = Len, + last_cert = Last}, + no_basic_constraint, SelfSigned, UserState0, VerifyFun) -> case Last of true when SelfSigned -> - {ValidationState, UnknownExtensions, AccErr0}; + {ValidationState, UserState0}; true -> {ValidationState#path_validation_state{max_path_length = Len - 1}, - UnknownExtensions, AccErr0}; + UserState0}; %% basic_constraint must appear in certs used for digital sign %% see 4.2.1.10 in rfc 3280 false -> - AccErr = not_valid({bad_cert, missing_basic_constraint}, - Verify, AccErr0), + UserState = verify_fun(OtpCert, {bad_cert, missing_basic_constraint}, + UserState0, VerifyFun), case SelfSigned of true -> - {ValidationState, UnknownExtensions, AccErr}; + {ValidationState, UserState}; false -> {ValidationState#path_validation_state{max_path_length = - Len - 1}, - UnknownExtensions, AccErr} + Len - 1}, + UserState} end end; -validate_extensions([#'Extension'{extnID = ?'id-ce-basicConstraints', +validate_extensions(OtpCert, + [#'Extension'{extnID = ?'id-ce-basicConstraints', extnValue = - #'BasicConstraints'{cA = true, - pathLenConstraint = N}} | + #'BasicConstraints'{cA = true, + pathLenConstraint = N}} | Rest], - ValidationState = - #path_validation_state{max_path_length = Len}, _, - SelfSigned, UnknownExtensions, Verify, AccErr) -> - Length = if SelfSigned -> min(N, Len); - true -> min(N, Len-1) + ValidationState = + #path_validation_state{max_path_length = Len}, _, + SelfSigned, UserState, VerifyFun) -> + Length = if SelfSigned -> erlang:min(N, Len); + true -> erlang:min(N, Len-1) end, - validate_extensions(Rest, + validate_extensions(OtpCert, Rest, ValidationState#path_validation_state{max_path_length = - Length}, - basic_constraint, SelfSigned, UnknownExtensions, - Verify, AccErr); + Length}, + basic_constraint, SelfSigned, + UserState, VerifyFun); %% The pathLenConstraint field is meaningful only if cA is set to %% TRUE. -validate_extensions([#'Extension'{extnID = ?'id-ce-basicConstraints', - extnValue = - #'BasicConstraints'{cA = false}} | - Rest], ValidationState, ExistBasicCon, - SelfSigned, UnknownExtensions, Verify, AccErr) -> - validate_extensions(Rest, ValidationState, ExistBasicCon, - SelfSigned, UnknownExtensions, Verify, AccErr); - -%% -validate_extensions([#'Extension'{extnID = ?'id-ce-keyUsage', - extnValue = KeyUse - } | Rest], - #path_validation_state{last_cert=Last} = ValidationState, - ExistBasicCon, SelfSigned, UnknownExtensions, - Verify, AccErr0) -> +validate_extensions(OtpCert, [#'Extension'{extnID = ?'id-ce-basicConstraints', + extnValue = + #'BasicConstraints'{cA = false}} | + Rest], ValidationState, ExistBasicCon, + SelfSigned, UserState, VerifyFun) -> + validate_extensions(OtpCert, Rest, ValidationState, ExistBasicCon, + SelfSigned, UserState, VerifyFun); + +validate_extensions(OtpCert, [#'Extension'{extnID = ?'id-ce-keyUsage', + extnValue = KeyUse + } | Rest], + #path_validation_state{last_cert=Last} = ValidationState, + ExistBasicCon, SelfSigned, + UserState0, VerifyFun) -> case Last orelse is_valid_key_usage(KeyUse, keyCertSign) of true -> - validate_extensions(Rest, ValidationState, ExistBasicCon, - SelfSigned, UnknownExtensions, Verify, - AccErr0); + validate_extensions(OtpCert, Rest, ValidationState, ExistBasicCon, + SelfSigned, UserState0, VerifyFun); false -> - AccErr = not_valid({bad_cert, invalid_key_usage}, Verify, AccErr0), - validate_extensions(Rest, ValidationState, ExistBasicCon, - SelfSigned, UnknownExtensions, Verify, - AccErr) + UserState = verify_fun(OtpCert, {bad_cert, invalid_key_usage}, + UserState0, VerifyFun), + validate_extensions(OtpCert, Rest, ValidationState, ExistBasicCon, + SelfSigned, UserState, VerifyFun) end; -validate_extensions([#'Extension'{extnID = ?'id-ce-subjectAltName', - extnValue = Names} | Rest], - ValidationState, ExistBasicCon, - SelfSigned, UnknownExtensions, Verify, AccErr0) -> +validate_extensions(OtpCert, [#'Extension'{extnID = ?'id-ce-subjectAltName', + extnValue = Names} | Rest], + ValidationState, ExistBasicCon, + SelfSigned, UserState0, VerifyFun) -> case validate_subject_alt_names(Names) of true when Names =/= [] -> - validate_extensions(Rest, ValidationState, ExistBasicCon, - SelfSigned, UnknownExtensions, Verify, - AccErr0); + validate_extensions(OtpCert, Rest, ValidationState, ExistBasicCon, + SelfSigned, UserState0, VerifyFun); _ -> - AccErr = - not_valid({bad_cert, invalid_subject_altname}, - Verify, AccErr0), - validate_extensions(Rest, ValidationState, ExistBasicCon, - SelfSigned, UnknownExtensions, Verify, - AccErr) + UserState = verify_fun(OtpCert, {bad_cert, invalid_subject_altname}, + UserState0, VerifyFun), + validate_extensions(OtpCert, Rest, ValidationState, ExistBasicCon, + SelfSigned, UserState, VerifyFun) end; %% This extension SHOULD NOT be marked critical. Its value %% does not have to be further validated at this point. -validate_extensions([#'Extension'{extnID = ?'id-ce-issuerAltName', - extnValue = _} | Rest], - ValidationState, ExistBasicCon, - SelfSigned, UnknownExtensions, Verify, AccErr) -> - validate_extensions(Rest, ValidationState, ExistBasicCon, - SelfSigned, UnknownExtensions, Verify, AccErr); +validate_extensions(OtpCert, [#'Extension'{extnID = ?'id-ce-issuerAltName', + extnValue = _} | Rest], + ValidationState, ExistBasicCon, + SelfSigned, UserState, VerifyFun) -> + validate_extensions(OtpCert, Rest, ValidationState, ExistBasicCon, + SelfSigned, UserState, VerifyFun); %% This extension MUST NOT be marked critical.Its value %% does not have to be further validated at this point. -validate_extensions([#'Extension'{extnID = Id, - extnValue = _, - critical = false} | Rest], +validate_extensions(OtpCert, [#'Extension'{extnID = Id, + extnValue = _, + critical = false} | Rest], ValidationState, - ExistBasicCon, SelfSigned, UnknownExtensions, - Verify, AccErr) + ExistBasicCon, SelfSigned, + UserState, VerifyFun) when Id == ?'id-ce-subjectKeyIdentifier'; Id == ?'id-ce-authorityKeyIdentifier'-> - validate_extensions(Rest, ValidationState, ExistBasicCon, - SelfSigned, UnknownExtensions, Verify, AccErr); + validate_extensions(OtpCert, Rest, ValidationState, ExistBasicCon, + SelfSigned, UserState, VerifyFun); -validate_extensions([#'Extension'{extnID = ?'id-ce-nameConstraints', +validate_extensions(OtpCert, [#'Extension'{extnID = ?'id-ce-nameConstraints', extnValue = NameConst} | Rest], ValidationState, - ExistBasicCon, SelfSigned, UnknownExtensions, - Verify, AccErr) -> + ExistBasicCon, SelfSigned, UserState, VerifyFun) -> Permitted = NameConst#'NameConstraints'.permittedSubtrees, Excluded = NameConst#'NameConstraints'.excludedSubtrees, NewValidationState = add_name_constraints(Permitted, Excluded, ValidationState), - validate_extensions(Rest, NewValidationState, ExistBasicCon, - SelfSigned, UnknownExtensions, Verify, AccErr); + validate_extensions(OtpCert, Rest, NewValidationState, ExistBasicCon, + SelfSigned, UserState, VerifyFun); -validate_extensions([#'Extension'{extnID = ?'id-ce-certificatePolicies', - critical = true} | Rest], ValidationState, - ExistBasicCon, SelfSigned, - UnknownExtensions, Verify, AccErr0) -> +validate_extensions(OtpCert, [#'Extension'{extnID = ?'id-ce-certificatePolicies', + critical = true} = Ext| Rest], ValidationState, + ExistBasicCon, SelfSigned, UserState0, VerifyFun) -> %% TODO: Remove this clause when policy handling is %% fully implemented - AccErr = - not_valid({bad_cert, unknown_critical_extension}, Verify, AccErr0), - validate_extensions(Rest, ValidationState, ExistBasicCon, - SelfSigned, UnknownExtensions, Verify, AccErr); - -validate_extensions([#'Extension'{extnID = ?'id-ce-certificatePolicies', - extnValue = #'PolicyInformation'{ - policyIdentifier = Id, - policyQualifiers = Qualifier}} - | Rest], #path_validation_state{valid_policy_tree = Tree} + UserState = verify_fun(OtpCert, {extension, Ext}, + UserState0, VerifyFun), + validate_extensions(OtpCert,Rest, ValidationState, ExistBasicCon, + SelfSigned, UserState, VerifyFun); + +validate_extensions(OtpCert, [#'Extension'{extnID = ?'id-ce-certificatePolicies', + extnValue = #'PolicyInformation'{ + policyIdentifier = Id, + policyQualifiers = Qualifier}} + | Rest], #path_validation_state{valid_policy_tree = Tree} = ValidationState, - ExistBasicCon, SelfSigned, UnknownExtensions, - Verify, AccErr) -> + ExistBasicCon, SelfSigned, UserState, VerifyFun) -> %% TODO: Policy imp incomplete NewTree = process_policy_tree(Id, Qualifier, Tree), - validate_extensions(Rest, + validate_extensions(OtpCert, Rest, ValidationState#path_validation_state{ valid_policy_tree = NewTree}, - ExistBasicCon, SelfSigned, UnknownExtensions, - Verify, AccErr); + ExistBasicCon, SelfSigned, UserState, VerifyFun); -validate_extensions([#'Extension'{extnID = ?'id-ce-policyConstraints', - critical = true} | Rest], ValidationState, - ExistBasicCon, SelfSigned, UnknownExtensions, Verify, - AccErr0) -> +validate_extensions(OtpCert, [#'Extension'{extnID = ?'id-ce-policyConstraints', + critical = true} = Ext | Rest], ValidationState, + ExistBasicCon, SelfSigned, UserState0, VerifyFun) -> %% TODO: Remove this clause when policy handling is %% fully implemented - AccErr = - not_valid({bad_cert, unknown_critical_extension}, Verify, AccErr0), - validate_extensions(Rest, ValidationState, ExistBasicCon, - SelfSigned, UnknownExtensions, Verify, AccErr); -validate_extensions([#'Extension'{extnID = ?'id-ce-policyConstraints', - extnValue = #'PolicyConstraints'{ - requireExplicitPolicy = ExpPolicy, - inhibitPolicyMapping = MapPolicy}} - | Rest], ValidationState, ExistBasicCon, - SelfSigned, UnknownExtensions, Verify, AccErr) -> + UserState = verify_fun(OtpCert, {extension, Ext}, + UserState0, VerifyFun), + validate_extensions(OtpCert, Rest, ValidationState, ExistBasicCon, + SelfSigned, UserState, VerifyFun); +validate_extensions(OtpCert, [#'Extension'{extnID = ?'id-ce-policyConstraints', + extnValue = #'PolicyConstraints'{ + requireExplicitPolicy = ExpPolicy, + inhibitPolicyMapping = MapPolicy}} + | Rest], ValidationState, ExistBasicCon, + SelfSigned, UserState, VerifyFun) -> %% TODO: Policy imp incomplete - NewValidationState = add_policy_constraints(ExpPolicy, MapPolicy, + NewValidationState = add_policy_constraints(ExpPolicy, MapPolicy, ValidationState), - validate_extensions(Rest, NewValidationState, ExistBasicCon, - SelfSigned, UnknownExtensions, Verify, AccErr); + validate_extensions(OtpCert, Rest, NewValidationState, ExistBasicCon, + SelfSigned, UserState, VerifyFun); -validate_extensions([Extension | Rest], ValidationState, - ExistBasicCon, SelfSigned, UnknownExtensions, - Verify, AccErr) -> - validate_extensions(Rest, ValidationState, ExistBasicCon, SelfSigned, - [Extension | UnknownExtensions], Verify, AccErr). +validate_extensions(OtpCert, [#'Extension'{} = Extension | Rest], + ValidationState, ExistBasicCon, + SelfSigned, UserState0, VerifyFun) -> + UserState = verify_fun(OtpCert, {extension, Extension}, UserState0, VerifyFun), + validate_extensions(OtpCert, Rest, ValidationState, ExistBasicCon, SelfSigned, + UserState, VerifyFun). is_valid_key_usage(KeyUse, Use) -> lists:member(Use, KeyUse). @@ -603,11 +685,6 @@ is_valid_subject_alt_name({_, [_|_]}) -> is_valid_subject_alt_name({_, _}) -> false. -min(N, M) when N =< M -> - N; -min(_, M) -> - M. - is_ip_address(Address) -> case inet_parse:address(Address) of {ok, _} -> @@ -670,10 +747,11 @@ split_auth_path(URIPart) -> end. split_uri(UriPart, SplitChar, NoMatchResult, SkipLeft, SkipRight) -> - case regexp:first_match(UriPart, SplitChar) of - {match, Match, _} -> - {string:substr(UriPart, 1, Match - SkipLeft), - string:substr(UriPart, Match + SkipRight, length(UriPart))}; + case re:run(UriPart, SplitChar) of + {match,[{Start, _}]} -> + StrPos = Start + 1, + {string:substr(UriPart, 1, StrPos - SkipLeft), + string:substr(UriPart, StrPos + SkipRight, length(UriPart))}; nomatch -> NoMatchResult end. @@ -926,7 +1004,7 @@ add_policy_constraints(ExpPolicy, MapPolicy, policy_constraint(Current, asn1_NOVALUE, _) -> Current; policy_constraint(Current, New, CertNum) -> - min(Current, New + CertNum). + erlang:min(Current, New + CertNum). process_policy_tree(_,_, ?NULL) -> ?NULL; diff --git a/lib/public_key/src/pubkey_cert_records.erl b/lib/public_key/src/pubkey_cert_records.erl index ac04e1c2cb..20b322b4a4 100644 --- a/lib/public_key/src/pubkey_cert_records.erl +++ b/lib/public_key/src/pubkey_cert_records.erl @@ -23,30 +23,61 @@ -include("public_key.hrl"). --export([decode_cert/2, encode_cert/1, encode_tbs_cert/1, transform/2]). +-export([decode_cert/1, transform/2]). %%==================================================================== %% Internal application API %%==================================================================== -decode_cert(DerCert, plain) -> - 'OTP-PUB-KEY':decode('Certificate', DerCert); -decode_cert(DerCert, otp) -> +%%-------------------------------------------------------------------- +-spec decode_cert(der_encoded()) -> {ok, #'OTPCertificate'{}}. +%% +%% Description: Recursively decodes a Certificate. +%%-------------------------------------------------------------------- +decode_cert(DerCert) -> {ok, Cert} = 'OTP-PUB-KEY':decode('OTPCertificate', DerCert), #'OTPCertificate'{tbsCertificate = TBS} = Cert, {ok, Cert#'OTPCertificate'{tbsCertificate = decode_tbs(TBS)}}. -encode_cert(Cert = #'Certificate'{}) -> - {ok, EncCert} = 'OTP-PUB-KEY':encode('Certificate', Cert), - list_to_binary(EncCert); -encode_cert(C = #'OTPCertificate'{tbsCertificate = TBS}) -> - Cert = C#'OTPCertificate'{tbsCertificate=encode_tbs(TBS)}, - {ok, EncCert} = 'OTP-PUB-KEY':encode('OTPCertificate', Cert), - list_to_binary(EncCert). - -encode_tbs_cert(TBS) -> - {ok, EncTBSCert} = 'OTP-PUB-KEY':encode('OTPTBSCertificate', encode_tbs(TBS)), - list_to_binary(EncTBSCert). +%%-------------------------------------------------------------------- +-spec transform(term(), encode | decode) ->term(). +%% +%% Description: Transforms between encoded and decode otp formated +%% certificate parts. +%%-------------------------------------------------------------------- + +transform(#'OTPCertificate'{tbsCertificate = TBS} = Cert, encode) -> + Cert#'OTPCertificate'{tbsCertificate=encode_tbs(TBS)}; +transform(#'OTPCertificate'{tbsCertificate = TBS} = Cert, decode) -> + Cert#'OTPCertificate'{tbsCertificate=decode_tbs(TBS)}; +transform(#'OTPTBSCertificate'{}= TBS, encode) -> + encode_tbs(TBS); +transform(#'OTPTBSCertificate'{}= TBS, decode) -> + decode_tbs(TBS); +transform(#'AttributeTypeAndValue'{type=Id,value=Value0} = ATAV, Func) -> + {ok, Value} = + case attribute_type(Id) of + Type when is_atom(Type) -> 'OTP-PUB-KEY':Func(Type, Value0); + _UnknownType -> {ok, Value0} + end, + ATAV#'AttributeTypeAndValue'{value=Value}; +transform(AKI = #'AuthorityKeyIdentifier'{authorityCertIssuer=ACI},Func) -> + AKI#'AuthorityKeyIdentifier'{authorityCertIssuer=transform(ACI,Func)}; +transform(List = [{directoryName, _}],Func) -> + [{directoryName, transform(Value,Func)} || {directoryName, Value} <- List]; +transform({directoryName, Value},Func) -> + {directoryName, transform(Value,Func)}; +transform({rdnSequence, SeqList},Func) when is_list(SeqList) -> + {rdnSequence, + lists:map(fun(Seq) -> + lists:map(fun(Element) -> transform(Element,Func) end, Seq) + end, SeqList)}; +transform(#'NameConstraints'{permittedSubtrees=Permitted, excludedSubtrees=Excluded}, Func) -> + #'NameConstraints'{permittedSubtrees=transform_sub_tree(Permitted,Func), + excludedSubtrees=transform_sub_tree(Excluded,Func)}; + +transform(Other,_) -> + Other. %%-------------------------------------------------------------------- %%% Internal functions @@ -132,31 +163,6 @@ encode_extensions(Exts) -> end end, Exts). -transform(#'AttributeTypeAndValue'{type=Id,value=Value0} = ATAV, Func) -> - {ok, Value} = - case attribute_type(Id) of - Type when is_atom(Type) -> 'OTP-PUB-KEY':Func(Type, Value0); - _UnknownType -> {ok, Value0} - end, - ATAV#'AttributeTypeAndValue'{value=Value}; -transform(AKI = #'AuthorityKeyIdentifier'{authorityCertIssuer=ACI},Func) -> - AKI#'AuthorityKeyIdentifier'{authorityCertIssuer=transform(ACI,Func)}; -transform(List = [{directoryName, _}],Func) -> - [{directoryName, transform(Value,Func)} || {directoryName, Value} <- List]; -transform({directoryName, Value},Func) -> - {directoryName, transform(Value,Func)}; -transform({rdnSequence, SeqList},Func) when is_list(SeqList) -> - {rdnSequence, - lists:map(fun(Seq) -> - lists:map(fun(Element) -> transform(Element,Func) end, Seq) - end, SeqList)}; -transform(#'NameConstraints'{permittedSubtrees=Permitted, excludedSubtrees=Excluded}, Func) -> - #'NameConstraints'{permittedSubtrees=transform_sub_tree(Permitted,Func), - excludedSubtrees=transform_sub_tree(Excluded,Func)}; - -transform(Other,_) -> - Other. - encode_tbs(TBS=#'OTPTBSCertificate'{issuer=Issuer0, subject=Subject0, subjectPublicKeyInfo=Spki0, diff --git a/lib/public_key/src/pubkey_crypto.erl b/lib/public_key/src/pubkey_crypto.erl deleted file mode 100644 index 7b7abb1c56..0000000000 --- a/lib/public_key/src/pubkey_crypto.erl +++ /dev/null @@ -1,171 +0,0 @@ -%% -%% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2008-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% -%% - -%% -%% Description: Functions that call the crypto driver. - --module(pubkey_crypto). - --include("public_key.hrl"). - --export([encrypt_public/3, decrypt_private/3, - encrypt_private/3, decrypt_public/3, - sign/2, sign/3, verify/5, gen_key/2]). - --define(UINT32(X), X:32/unsigned-big-integer). - -%%==================================================================== -%% Internal application API -%%==================================================================== - -%%-------------------------------------------------------------------- -%% Function: encrypt(PlainText, Key, Padding) -> Encrypted -%% -%% PlainText = binary() -%% Key = rsa_public_key() | rsa_private_key() -%% Padding = rsa_pkcs1_padding | rsa_pkcs1_oaep_padding -%% Encrypted = binary() -%% -%% Description: Public key encrypts PlainText. -%%-------------------------------------------------------------------- -encrypt_public(PlainText, #'RSAPublicKey'{modulus=N,publicExponent=E}, - Padding) -> - crypto:rsa_public_encrypt(PlainText, [crypto:mpint(E),crypto:mpint(N)], - Padding); -encrypt_public(PlainText, #'RSAPrivateKey'{modulus=N,publicExponent=E}, - Padding) -> - crypto:rsa_public_encrypt(PlainText, [crypto:mpint(E),crypto:mpint(N)], - Padding). - -encrypt_private(PlainText, #'RSAPrivateKey'{modulus = N, - publicExponent = E, - privateExponent = D}, Padding) -> - crypto:rsa_private_encrypt(PlainText, [crypto:mpint(E), - crypto:mpint(N), - crypto:mpint(D)], Padding). - -%%-------------------------------------------------------------------- -%% Function: decrypt(CipherText, Key) -> PlainText -%% -%% ChipherText = binary() -%% Key = rsa_private_key() -%% Padding = rsa_pkcs1_padding | rsa_pkcs1_oaep_padding -%% PlainText = binary() -%% -%% Description: Uses private key to decrypt public key encrypted data. -%%-------------------------------------------------------------------- -decrypt_private(CipherText, - #'RSAPrivateKey'{modulus = N,publicExponent = E, - privateExponent = D}, - Padding) -> - crypto:rsa_private_decrypt(CipherText, - [crypto:mpint(E), crypto:mpint(N), - crypto:mpint(D)], Padding). -decrypt_public(CipherText, #'RSAPublicKey'{modulus = N, publicExponent = E}, - Padding) -> - crypto:rsa_public_decrypt(CipherText,[crypto:mpint(E), crypto:mpint(N)], - Padding); -decrypt_public(CipherText, #'RSAPrivateKey'{modulus = N, publicExponent = E}, - Padding) -> - crypto:rsa_public_decrypt(CipherText,[crypto:mpint(E), crypto:mpint(N)], - Padding). - -%%-------------------------------------------------------------------- -%% Function: sign(PlainText, Key) -> -%% sign(DigestType, PlainText, Key) -> Signature -%% -%% DigestType = sha | md5 -%% PlainText = binary() -%% Key = rsa_private_key() | dsa_private_key() -%% Signature = binary() -%% -%% Description: Signs PlainText using Key. -%%-------------------------------------------------------------------- -sign(PlainText, Digest) -> - sign(sha, PlainText, Digest). - -sign(DigestType, PlainText, #'RSAPrivateKey'{modulus = N, publicExponent = E, - privateExponent = D}) -> - crypto:rsa_sign(DigestType, sized_binary(PlainText), [crypto:mpint(E), - crypto:mpint(N), - crypto:mpint(D)]); - -sign(none, Hash, #'DSAPrivateKey'{p = P, q = Q, g = G, x = X}) -> - crypto:dss_sign(none, Hash, - [crypto:mpint(P), crypto:mpint(Q), - crypto:mpint(G), crypto:mpint(X)]); - -sign(sha, PlainText, #'DSAPrivateKey'{p = P, q = Q, g = G, x = X}) -> - crypto:dss_sign(sized_binary(PlainText), - [crypto:mpint(P), crypto:mpint(Q), - crypto:mpint(G), crypto:mpint(X)]). - -%%-------------------------------------------------------------------- -%% Function: verify(DigestType, PlainText, Signature, Key) -> true | false -%% -%% DigestType = sha | md5 -%% PlainText = binary() -%% Signature = binary() -%% Key = rsa_public_key() | dsa_public_key() -%% -%% Description: Verifies the signature <Signature>. -%%-------------------------------------------------------------------- -verify(DigestType, PlainText, Signature, - #'RSAPublicKey'{modulus = Mod, publicExponent = Exp}, _) -> - crypto:rsa_verify(DigestType, - sized_binary(PlainText), - sized_binary(Signature), - [crypto:mpint(Exp), crypto:mpint(Mod)]); - -verify(none, Hash, Signature, Key, #'Dss-Parms'{p = P, q = Q, g = G}) -> - crypto:dss_verify(none, Hash, - sized_binary(Signature), - [crypto:mpint(P), crypto:mpint(Q), - crypto:mpint(G), crypto:mpint(Key)]); - -verify(sha, PlainText, Signature, Key, #'Dss-Parms'{p = P, q = Q, g = G}) -> - crypto:dss_verify(sized_binary(PlainText), - sized_binary(Signature), - [crypto:mpint(P), crypto:mpint(Q), - crypto:mpint(G), crypto:mpint(Key)]). - - -%%-------------------------------------------------------------------- -%% Function: gen_key(Type, Params) -> -%% Type = diffie_hellman -%% Params = [P,G] | [Y, P, G] -%% Description: Generates keys. -%% ----------------------------------------------------------------- -gen_key(diffie_hellman, [Y, P, G]) -> - crypto:dh_generate_key(crypto:mpint(Y), [crypto:mpint(P), - crypto:mpint(G)]); -gen_key(diffie_hellman, [P, G]) -> - crypto:dh_generate_key([crypto:mpint(P), crypto:mpint(G)]). - -%%% TODO: Support rsa, dss key_gen - -%%-------------------------------------------------------------------- -%%% Internal functions -%%-------------------------------------------------------------------- -sized_binary(Binary) when is_binary(Binary) -> - Size = size(Binary), - <<?UINT32(Size), Binary/binary>>; -sized_binary(List) -> - sized_binary(list_to_binary(List)). - diff --git a/lib/public_key/src/pubkey_pem.erl b/lib/public_key/src/pubkey_pem.erl index 65879f1bbe..31d881973a 100644 --- a/lib/public_key/src/pubkey_pem.erl +++ b/lib/public_key/src/pubkey_pem.erl @@ -40,7 +40,10 @@ -module(pubkey_pem). --export([read_file/1, read_file/2, write_file/2, decode/2]). +-include("public_key.hrl"). + +-export([encode/1, decode/1, decipher/2, cipher/3]). +%% Backwards compatibility -export([decode_key/2]). -define(ENCODED_LINE_LENGTH, 64). @@ -48,28 +51,82 @@ %%==================================================================== %% Internal application API %%==================================================================== -read_file(File) -> - read_file(File, no_passwd). -read_file(File, Passwd) -> - {ok, Bin} = file:read_file(File), - decode(Bin, Passwd). +%%-------------------------------------------------------------------- +-spec decode(binary()) -> [pem_entry()]. +%% +%% Description: Decodes a PEM binary. +%%-------------------------------------------------------------------- +decode(Bin) -> + decode_pem_entries(split_bin(Bin), []). -write_file(File, Ds) -> - file:write_file(File, encode_file(Ds)). +%%-------------------------------------------------------------------- +-spec encode([pem_entry()]) -> iolist(). +%% +%% Description: Encodes a list of PEM entries. +%%-------------------------------------------------------------------- +encode(PemEntries) -> + encode_pem_entries(PemEntries). -decode_key({_Type, Bin, not_encrypted}, _) -> - Bin; -decode_key({_Type, Bin, {Chipher,Salt}}, Password) -> - decode_key(Bin, Password, Chipher, Salt). +%%-------------------------------------------------------------------- +-spec decipher({pki_asn1_type(), decrypt_der(),{Cipher :: string(), Salt :: binary()}}, string()) -> + der_encoded(). +%% +%% Description: Deciphers a decrypted pem entry. +%%-------------------------------------------------------------------- +decipher({_, DecryptDer, {Cipher,Salt}}, Password) -> + decode_key(DecryptDer, Password, Cipher, Salt). -decode(Bin, Passwd) -> - decode_file(split_bin(Bin), Passwd). +%%-------------------------------------------------------------------- +-spec cipher(der_encoded(),{Cipher :: string(), Salt :: binary()} , string()) -> binary(). +%% +%% Description: Ciphers a PEM entry +%%-------------------------------------------------------------------- +cipher(Der, {Cipher,Salt}, Password)-> + encode_key(Der, Password, Cipher, Salt). %%-------------------------------------------------------------------- %%% Internal functions %%-------------------------------------------------------------------- +encode_pem_entries(Entries) -> + [encode_pem_entry(Entry) || Entry <- Entries]. + +encode_pem_entry({Asn1Type, Der, not_encrypted}) -> + StartStr = pem_start(Asn1Type), + [StartStr, "\n", b64encode_and_split(Der), pem_end(StartStr) ,"\n\n"]; +encode_pem_entry({Asn1Type, Der, {Cipher, Salt}}) -> + StartStr = pem_start(Asn1Type), + [StartStr,"\n", pem_decrypt(),"\n", pem_decrypt_info(Cipher, Salt),"\n", + b64encode_and_split(Der), pem_end(StartStr) ,"\n\n"]. + +decode_pem_entries([], Entries) -> + lists:reverse(Entries); +decode_pem_entries([<<>>], Entries) -> + lists:reverse(Entries); +decode_pem_entries([<<>> | Lines], Entries) -> + decode_pem_entries(Lines, Entries); +decode_pem_entries([Start| Lines], Entries) -> + case pem_end(Start) of + undefined -> + decode_pem_entries(Lines, Entries); + _End -> + {Entry, RestLines} = join_entry(Lines, []), + decode_pem_entries(RestLines, [decode_pem_entry(Start, Entry) | Entries]) + end. +decode_pem_entry(Start, [<<"Proc-Type: 4,ENCRYPTED", _/binary>>, Line | Lines]) -> + Asn1Type = asn1_type(Start), + Cs = erlang:iolist_to_binary(Lines), + Decoded = base64:mime_decode(Cs), + [_, DekInfo0] = string:tokens(binary_to_list(Line), ": "), + [Cipher, Salt] = string:tokens(DekInfo0, ","), + {Asn1Type, Decoded, {Cipher, unhex(Salt)}}; +decode_pem_entry(Start, Lines) -> + Asn1Type = asn1_type(Start), + Cs = erlang:iolist_to_binary(Lines), + Der = base64:mime_decode(Cs), + {Asn1Type, Der, not_encrypted}. + split_bin(Bin) -> split_bin(0, Bin). @@ -85,88 +142,26 @@ split_bin(N, Bin) -> split_bin(N+1, Bin) end. -decode_file(Bin, Passwd) -> - decode_file(Bin, [], [Passwd]). - -decode_file([<<"-----BEGIN CERTIFICATE REQUEST-----", _/binary>>|Rest], Ens, Info) -> - decode_file2(Rest, [], Ens, cert_req, Info); -decode_file([<<"-----BEGIN CERTIFICATE-----", _/binary>>|Rest], Ens, Info) -> - decode_file2(Rest, [], Ens, cert, Info); -decode_file([<<"-----BEGIN RSA PRIVATE KEY-----", _/binary>>|Rest], Ens, Info) -> - decode_file2(Rest, [], Ens, rsa_private_key, Info); -decode_file([<<"-----BEGIN DSA PRIVATE KEY-----", _/binary>>|Rest], Ens, Info) -> - decode_file2(Rest, [], Ens, dsa_private_key, Info); -decode_file([<<"-----BEGIN DH PARAMETERS-----", _/binary>>|Rest], Ens, Info) -> - decode_file2(Rest, [], Ens, dh_params, Info); -decode_file([_|Rest], Ens, Info) -> - decode_file(Rest, Ens, Info); -decode_file([], Ens, _Info) -> - {ok, lists:reverse(Ens)}. - -decode_file2([<<"Proc-Type: 4,ENCRYPTED", _/binary>>| Rest0], RLs, Ens, Tag, Info0) -> - [InfoLine|Rest] = Rest0, - Info = dek_info(InfoLine, Info0), - decode_file2(Rest, RLs, Ens, Tag, Info); -decode_file2([<<"-----END", _/binary>>| Rest], RLs, Ens, Tag, Info0) -> - Cs = erlang:iolist_to_binary(lists:reverse(RLs)), - Bin = base64:mime_decode(Cs), - case Info0 of - [Password, Cipher, SaltHex | Info1] -> - Salt = unhex(SaltHex), - Enc = {Cipher, Salt}, - Decoded = decode_key(Bin, Password, Cipher, Salt), - decode_file(Rest, [{Tag, Decoded, Enc}| Ens], Info1); - _ -> - decode_file(Rest, [{Tag, Bin, not_encrypted}| Ens], Info0) - end; -decode_file2([L|Rest], RLs, Ens, Tag, Info0) -> - decode_file2(Rest, [L|RLs], Ens, Tag, Info0); -decode_file2([], _, Ens, _, _) -> - {ok, lists:reverse(Ens)}. - -%% Support same as decode_file -encode_file(Ds) -> - lists:map( - fun({cert, Bin, not_encrypted}) -> - %% PKIX (X.509) - ["-----BEGIN CERTIFICATE-----\n", - b64encode_and_split(Bin), - "-----END CERTIFICATE-----\n\n"]; - ({cert_req, Bin, not_encrypted}) -> - %% PKCS#10 - ["-----BEGIN CERTIFICATE REQUEST-----\n", - b64encode_and_split(Bin), - "-----END CERTIFICATE REQUEST-----\n\n"]; - ({rsa_private_key, Bin, not_encrypted}) -> - %% PKCS#? - ["XXX Following key assumed not encrypted\n", - "-----BEGIN RSA PRIVATE KEY-----\n", - b64encode_and_split(Bin), - "-----END RSA PRIVATE KEY-----\n\n"]; - ({dsa_private_key, Bin, not_encrypted}) -> - %% PKCS#? - ["XXX Following key assumed not encrypted\n", - "-----BEGIN DSA PRIVATE KEY-----\n", - b64encode_and_split(Bin), - "-----END DSA PRIVATE KEY-----\n\n"] - end, Ds). - -dek_info(Line0, Info) -> - Line = binary_to_list(Line0), - [_, DekInfo0] = string:tokens(Line, ": "), - DekInfo1 = string:tokens(DekInfo0, ",\n"), - Info ++ DekInfo1. +b64encode_and_split(Bin) -> + split_lines(base64:encode(Bin)). -unhex(S) -> - unhex(S, []). +split_lines(<<Text:?ENCODED_LINE_LENGTH/binary, Rest/binary>>) -> + [Text, $\n | split_lines(Rest)]; +split_lines(Bin) -> + [Bin, $\n]. -unhex("", Acc) -> - list_to_binary(lists:reverse(Acc)); -unhex([D1, D2 | Rest], Acc) -> - unhex(Rest, [erlang:list_to_integer([D1, D2], 16) | Acc]). +%% Ignore white space at end of line +join_entry([<<"-----END CERTIFICATE-----", _/binary>>| Lines], Entry) -> + {lists:reverse(Entry), Lines}; +join_entry([<<"-----END RSA PRIVATE KEY-----", _/binary>>| Lines], Entry) -> + {lists:reverse(Entry), Lines}; +join_entry([<<"-----END DSA PRIVATE KEY-----", _/binary>>| Lines], Entry) -> + {lists:reverse(Entry), Lines}; +join_entry([<<"-----END DH PARAMETERS-----", _/binary>>| Lines], Entry) -> + {lists:reverse(Entry), Lines}; +join_entry([Line | Lines], Entry) -> + join_entry(Lines, [Line | Entry]). -decode_key(Data, no_passwd, _Alg, _Salt) -> - Data; decode_key(Data, Password, "DES-CBC", Salt) -> Key = password_to_key(Password, Salt, 8), IV = Salt, @@ -177,6 +172,16 @@ decode_key(Data, Password, "DES-EDE3-CBC", Salt) -> <<Key1:8/binary, Key2:8/binary, Key3:8/binary>> = Key, crypto:des_ede3_cbc_decrypt(Key1, Key2, Key3, IV, Data). +encode_key(Data, Password, "DES-CBC", Salt) -> + Key = password_to_key(Password, Salt, 8), + IV = Salt, + crypto:des_cbc_encrypt(Key, IV, Data); +encode_key(Data, Password, "DES-EDE3-CBC", Salt) -> + Key = password_to_key(Password, Salt, 24), + IV = Salt, + <<Key1:8/binary, Key2:8/binary, Key3:8/binary>> = Key, + crypto:des_ede3_cbc_encrypt(Key1, Key2, Key3, IV, Data). + password_to_key(Data, Salt, KeyLen) -> <<Key:KeyLen/binary, _/binary>> = password_to_key(<<>>, Data, Salt, KeyLen, <<>>), @@ -188,11 +193,58 @@ password_to_key(Prev, Data, Salt, Len, Acc) -> M = crypto:md5([Prev, Data, Salt]), password_to_key(M, Data, Salt, Len - size(M), <<Acc/binary, M/binary>>). -b64encode_and_split(Bin) -> - split_lines(base64:encode(Bin)). +unhex(S) -> + unhex(S, []). -split_lines(<<Text:?ENCODED_LINE_LENGTH/binary, Rest/binary>>) -> - [Text, $\n | split_lines(Rest)]; -split_lines(Bin) -> - [Bin, $\n]. +unhex("", Acc) -> + list_to_binary(lists:reverse(Acc)); +unhex([D1, D2 | Rest], Acc) -> + unhex(Rest, [erlang:list_to_integer([D1, D2], 16) | Acc]). + +hexify(L) -> [[hex_byte(B)] || B <- binary_to_list(L)]. + +hex_byte(B) when B < 16#10 -> ["0", erlang:integer_to_list(B, 16)]; +hex_byte(B) -> erlang:integer_to_list(B, 16). + +pem_start('Certificate') -> + <<"-----BEGIN CERTIFICATE-----">>; +pem_start('RSAPrivateKey') -> + <<"-----BEGIN RSA PRIVATE KEY-----">>; +pem_start('DSAPrivateKey') -> + <<"-----BEGIN DSA PRIVATE KEY-----">>; +pem_start('DHParameter') -> + <<"-----BEGIN DH PARAMETERS-----">>. + +pem_end(<<"-----BEGIN CERTIFICATE-----">>) -> + <<"-----END CERTIFICATE-----">>; +pem_end(<<"-----BEGIN RSA PRIVATE KEY-----">>) -> + <<"-----END RSA PRIVATE KEY-----">>; +pem_end(<<"-----BEGIN DSA PRIVATE KEY-----">>) -> + <<"-----END DSA PRIVATE KEY-----">>; +pem_end(<<"-----BEGIN DH PARAMETERS-----">>) -> + <<"-----END DH PARAMETERS-----">>; +pem_end(_) -> + undefined. + +asn1_type(<<"-----BEGIN CERTIFICATE-----">>) -> + 'Certificate'; +asn1_type(<<"-----BEGIN RSA PRIVATE KEY-----">>) -> + 'RSAPrivateKey'; +asn1_type(<<"-----BEGIN DSA PRIVATE KEY-----">>) -> + 'DSAPrivateKey'; +asn1_type(<<"-----BEGIN DH PARAMETERS-----">>) -> + 'DHParameter'. + +pem_decrypt() -> + <<"Proc-Type: 4,ENCRYPTED">>. + +pem_decrypt_info(Cipher, Salt) -> + io_lib:format("DEK-Info: ~s,~s", [Cipher, lists:flatten(hexify(Salt))]). +%%-------------------------------------------------------------------- +%%% Deprecated +%%-------------------------------------------------------------------- +decode_key({_Type, Bin, not_encrypted}, _) -> + Bin; +decode_key({_Type, Bin, {Chipher,Salt}}, Password) -> + decode_key(Bin, Password, Chipher, Salt). diff --git a/lib/public_key/src/public_key.app.src b/lib/public_key/src/public_key.app.src index d5e1705827..60487946fa 100644 --- a/lib/public_key/src/public_key.app.src +++ b/lib/public_key/src/public_key.app.src @@ -4,7 +4,6 @@ {modules, [ public_key, pubkey_pem, - pubkey_crypto, pubkey_cert, pubkey_cert_records, 'OTP-PUB-KEY' diff --git a/lib/public_key/src/public_key.appup.src b/lib/public_key/src/public_key.appup.src index 2eb5750923..c9d15b8747 100644 --- a/lib/public_key/src/public_key.appup.src +++ b/lib/public_key/src/public_key.appup.src @@ -1,6 +1,15 @@ %% -*- erlang -*- {"%VSN%", [ + {"0.7", + [ + {update, 'OTP-PUB-KEY', soft, soft_purge, soft_purge, []}, + {update, public_key, soft, soft_purge, soft_purge, []}, + {update, pubkey_pem, soft, soft_purge, soft_purge, []}, + {update, pubkey_cert_records, soft, soft_purge, soft_purge, []} + {update, pubkey_cert, soft, soft_purge, soft_purge, []} + ] + }, {"0.6", [ {update, 'OTP-PUB-KEY', soft, soft_purge, soft_purge, []}, @@ -22,6 +31,15 @@ } ], [ + {"0.7", + [ + {update, 'OTP-PUB-KEY', soft, soft_purge, soft_purge, []}, + {update, public_key, soft, soft_purge, soft_purge, []}, + {update, pubkey_pem, soft, soft_purge, soft_purge, []}, + {update, pubkey_cert_records, soft, soft_purge, soft_purge, []} + {update, pubkey_cert, soft, soft_purge, soft_purge, []} + ] + }, {"0.6", [ {update, 'OTP-PUB-KEY', soft, soft_purge, soft_purge, []}, diff --git a/lib/public_key/src/public_key.erl b/lib/public_key/src/public_key.erl index 12354eee5d..68bf04eeff 100644 --- a/lib/public_key/src/public_key.erl +++ b/lib/public_key/src/public_key.erl @@ -23,239 +23,395 @@ -include("public_key.hrl"). --export([decode_private_key/1, decode_private_key/2, decode_dhparams/1, - decrypt_private/2, decrypt_private/3, encrypt_public/2, - encrypt_public/3, decrypt_public/2, decrypt_public/3, - encrypt_private/2, encrypt_private/3, gen_key/1, sign/2, sign/3, - verify_signature/3, verify_signature/4, verify_signature/5, - pem_to_der/1, pem_to_der/2, der_to_pem/2, - pkix_decode_cert/2, pkix_encode_cert/1, pkix_transform/2, - pkix_is_self_signed/1, pkix_is_fixed_dh_cert/1, +-export([pem_decode/1, pem_encode/1, + der_decode/2, der_encode/2, + pem_entry_decode/1, + pem_entry_decode/2, + pem_entry_encode/2, + pem_entry_encode/3, + pkix_decode_cert/2, pkix_encode/3, + encrypt_private/2, encrypt_private/3, + decrypt_private/2, decrypt_private/3, + encrypt_public/2, encrypt_public/3, + decrypt_public/2, decrypt_public/3, + sign/3, verify/4, + pkix_sign/2, pkix_verify/2, + pkix_is_self_signed/1, + pkix_is_fixed_dh_cert/1, + pkix_is_issuer/2, pkix_issuer_id/2, - pkix_is_issuer/2, pkix_normalize_general_name/1, + pkix_normalize_name/1, pkix_path_validation/3 ]). +%% Deprecated +-export([decode_private_key/1, decode_private_key/2, pem_to_der/1]). + +-deprecated({pem_to_der, 1, next_major_release}). +-deprecated({decode_private_key, 1, next_major_release}). +-deprecated({decode_private_key, 2, next_major_release}). + +-type rsa_public_key() :: #'RSAPublicKey'{}. +-type rsa_private_key() :: #'RSAPrivateKey'{}. +-type dsa_private_key() :: #'DSAPrivateKey'{}. +-type dsa_public_key() :: {integer(), #'Dss-Parms'{}}. +-type rsa_padding() :: 'rsa_pkcs1_padding' | 'rsa_pkcs1_oaep_padding' + | 'rsa_no_padding'. +-type public_crypt_options() :: [{rsa_pad, rsa_padding()}]. +-type rsa_digest_type() :: 'md5' | 'sha'. +-type dss_digest_type() :: 'none' | 'sha'. + +-define(UINT32(X), X:32/unsigned-big-integer). + %%==================================================================== %% API %%==================================================================== %%-------------------------------------------------------------------- -%% Function: decode_private_key(KeyInfo [,Password]) -> -%% {ok, PrivateKey} | {error, Reason} -%% -%% KeyInfo = {Type, der_bin(), ChipherInfo} - as returned from -%% pem_to_der/[1,2] for private keys -%% Type = rsa_private_key | dsa_private_key -%% ChipherInfo = opaque() | no_encryption +-spec pem_decode(binary()) -> [pem_entry()]. +%% +%% Description: Decode PEM binary data and return +%% entries as asn1 der encoded entities. +%%-------------------------------------------------------------------- +pem_decode(PemBin) when is_binary(PemBin) -> + pubkey_pem:decode(PemBin). + +%%-------------------------------------------------------------------- +-spec pem_encode([pem_entry()]) -> binary(). %% -%% Description: Decodes an asn1 der encoded private key. +%% Description: Creates a PEM binary. %%-------------------------------------------------------------------- -decode_private_key(KeyInfo) -> - decode_private_key(KeyInfo, no_passwd). +pem_encode(PemEntries) when is_list(PemEntries) -> + iolist_to_binary(pubkey_pem:encode(PemEntries)). -decode_private_key(KeyInfo = {rsa_private_key, _, _}, Password) -> - DerEncoded = pubkey_pem:decode_key(KeyInfo, Password), - 'OTP-PUB-KEY':decode('RSAPrivateKey', DerEncoded); -decode_private_key(KeyInfo = {dsa_private_key, _, _}, Password) -> - DerEncoded = pubkey_pem:decode_key(KeyInfo, Password), - 'OTP-PUB-KEY':decode('DSAPrivateKey', DerEncoded). +%%-------------------------------------------------------------------- +-spec pem_entry_decode(pem_entry(), [string()]) -> term(). +% +%% Description: Decodes a pem entry. pem_decode/1 returns a list of +%% pem entries. +%%-------------------------------------------------------------------- +pem_entry_decode({Asn1Type, Der, not_encrypted}) when is_atom(Asn1Type), + is_binary(Der) -> + der_decode(Asn1Type, Der). +pem_entry_decode({Asn1Type, Der, not_encrypted}, _) when is_atom(Asn1Type), + is_binary(Der) -> + der_decode(Asn1Type, Der); +pem_entry_decode({Asn1Type, CryptDer, {Cipher, Salt}} = PemEntry, + Password) when is_atom(Asn1Type), + is_binary(CryptDer), + is_list(Cipher), + is_binary(Salt), + erlang:byte_size(Salt) == 8 + -> + Der = pubkey_pem:decipher(PemEntry, Password), + der_decode(Asn1Type, Der). +%%-------------------------------------------------------------------- +-spec pem_entry_encode(pki_asn1_type(), term()) -> pem_entry(). +-spec pem_entry_encode(pki_asn1_type(), term(), + {{Cipher :: string(), Salt :: binary()}, string()}) -> + pem_entry(). +% +%% Description: Creates a pem entry that can be feed to pem_encode/1. +%%-------------------------------------------------------------------- +pem_entry_encode(Asn1Type, Entity) when is_atom(Asn1Type) -> + Der = der_encode(Asn1Type, Entity), + {Asn1Type, Der, not_encrypted}. +pem_entry_encode(Asn1Type, Entity, + {{Cipher, Salt}= CipherInfo, Password}) when is_atom(Asn1Type), + is_list(Cipher), + is_binary(Salt), + erlang:byte_size(Salt) == 8, + is_list(Password)-> + Der = der_encode(Asn1Type, Entity), + DecryptDer = pubkey_pem:cipher(Der, CipherInfo, Password), + {Asn1Type, DecryptDer, CipherInfo}. %%-------------------------------------------------------------------- -%% Function: decode_dhparams(DhParamInfo) -> -%% {ok, DhParams} | {error, Reason} +-spec der_decode(asn1_type(), der_encoded()) -> term(). %% -%% DhParamsInfo = {Type, der_bin(), ChipherInfo} - as returned from -%% pem_to_der/[1,2] for DH parameters. -%% Type = dh_params -%% ChipherInfo = opaque() | no_encryption -%% -%% Description: Decodes an asn1 der encoded DH parameters. +%% Description: Decodes a public key asn1 der encoded entity. %%-------------------------------------------------------------------- -decode_dhparams({dh_params, DerEncoded, not_encrypted}) -> - 'OTP-PUB-KEY':decode('DHParameter', DerEncoded). +der_decode(Asn1Type, Der) when is_atom(Asn1Type), is_binary(Der) -> + try + {ok, Decoded} = 'OTP-PUB-KEY':decode(Asn1Type, Der), + Decoded + catch + error:{badmatch, {error, _}} = Error -> + erlang:error(Error) + end. %%-------------------------------------------------------------------- -%% Function: decrypt_private(CipherText, Key) -> -%% decrypt_private(CipherText, Key, Options) -> PlainTex -%% decrypt_public(CipherText, Key) -> -%% decrypt_public(CipherText, Key, Options) -> PlainTex +-spec der_encode(asn1_type(), term()) -> der_encoded(). %% -%% CipherText = binary() -%% Key = rsa_key() -%% PlainText = binary() +%% Description: Encodes a public key entity with asn1 DER encoding. +%%-------------------------------------------------------------------- +der_encode(Asn1Type, Entity) when is_atom(Asn1Type) -> + try + {ok, Encoded} = 'OTP-PUB-KEY':encode(Asn1Type, Entity), + iolist_to_binary(Encoded) + catch + error:{badmatch, {error, _}} = Error -> + erlang:error(Error) + end. + +%%-------------------------------------------------------------------- +-spec pkix_decode_cert(der_encoded(), plain | otp) -> + #'Certificate'{} | #'OTPCertificate'{}. %% -%% Description: Decrypts <CipherText>. +%% Description: Decodes an asn1 der encoded pkix certificate. The otp +%% option will use the customized asn1 specification OTP-PKIX.asn1 for +%% decoding and also recursively decode most of the standard +%% extensions. +%% -------------------------------------------------------------------- +pkix_decode_cert(DerCert, plain) when is_binary(DerCert) -> + der_decode('Certificate', DerCert); +pkix_decode_cert(DerCert, otp) when is_binary(DerCert) -> + try + {ok, #'OTPCertificate'{}= Cert} = + pubkey_cert_records:decode_cert(DerCert), + Cert + catch + error:{badmatch, {error, _}} = Error -> + erlang:error(Error) + end. + +%%-------------------------------------------------------------------- +-spec pkix_encode(asn1_type(), term(), otp | plain) -> der_encoded(). +%% +%% Description: Der encodes a certificate or part of a certificate. +%% This function must be used for encoding certificates or parts of certificates +%% that are decoded with the otp format, whereas for the plain format this +%% function will only call der_encode/2. +%%-------------------------------------------------------------------- +pkix_encode(Asn1Type, Term, plain) when is_atom(Asn1Type) -> + der_encode(Asn1Type, Term); + +pkix_encode(Asn1Type, Term0, otp) when is_atom(Asn1Type) -> + Term = pubkey_cert_records:transform(Term0, encode), + der_encode(Asn1Type, Term). + +%%-------------------------------------------------------------------- +-spec decrypt_private(CipherText :: binary(), rsa_private_key()) -> + PlainText :: binary(). +-spec decrypt_private(CipherText :: binary(), rsa_private_key(), + public_crypt_options()) -> PlainText :: binary(). +%% +%% Description: Public key decryption using the private key. %%-------------------------------------------------------------------- decrypt_private(CipherText, Key) -> decrypt_private(CipherText, Key, []). -decrypt_private(CipherText, Key, Options) -> - Padding = proplists:get_value(rsa_pad, Options, rsa_pkcs1_padding), - pubkey_crypto:decrypt_private(CipherText, Key, Padding). -decrypt_public(CipherText, Key) -> - decrypt_public(CipherText, Key, []). -decrypt_public(CipherText, Key, Options) -> +decrypt_private(CipherText, + #'RSAPrivateKey'{modulus = N,publicExponent = E, + privateExponent = D}, + Options) when is_binary(CipherText), + is_list(Options) -> Padding = proplists:get_value(rsa_pad, Options, rsa_pkcs1_padding), - pubkey_crypto:decrypt_public(CipherText, Key, Padding). + crypto:rsa_private_decrypt(CipherText, + [crypto:mpint(E), crypto:mpint(N), + crypto:mpint(D)], Padding). %%-------------------------------------------------------------------- -%% Function: encrypt_public(PlainText, Key, Options) -> CipherText -%% encrypt_private(PlainText, Key, Options) -> CipherText -%% -%% PlainText = iolist() -%% Key = rsa_private_key() -%% CipherText = binary() +-spec decrypt_public(CipherText :: binary(), rsa_public_key()) -> + PlainText :: binary(). +-spec decrypt_public(CipherText :: binary(), rsa_public_key(), + public_crypt_options()) -> PlainText :: binary(). %% -%% Description: Encrypts <Plain> +%% Description: Public key decryption using the public key. %%-------------------------------------------------------------------- -encrypt_public(PlainText, Key) -> - encrypt_public(PlainText, Key, []). -encrypt_public(PlainText, Key, Options) -> - Padding = proplists:get_value(rsa_pad, Options, rsa_pkcs1_padding), - pubkey_crypto:encrypt_public(PlainText, Key, Padding). +decrypt_public(CipherText, Key) -> + decrypt_public(CipherText, Key, []). -encrypt_private(PlainText, Key) -> - encrypt_private(PlainText, Key, []). -encrypt_private(PlainText, Key, Options) -> - Padding = proplists:get_value(rsa_pad, Options, rsa_pkcs1_padding), - pubkey_crypto:encrypt_private(PlainText, Key, Padding). +decrypt_public(CipherText, #'RSAPublicKey'{modulus = N, publicExponent = E}, + Options) when is_binary(CipherText), is_list(Options) -> + decrypt_public(CipherText, N,E, Options); -%%-------------------------------------------------------------------- -%% Function: gen_key(Params) -> Keys -%% -%% Params = #'DomainParameters'{} - Currently only supported option -%% Keys = {PublicDHKey = integer(), PrivateDHKey = integer()} -%% -%% Description: Generates keys. Currently supports Diffie-Hellman keys. -%%-------------------------------------------------------------------- -gen_key(#'DHParameter'{prime = P, base = G}) when is_integer(P), - is_integer(G) -> - pubkey_crypto:gen_key(diffie_hellman, [P, G]). +decrypt_public(CipherText,#'RSAPrivateKey'{modulus = N, publicExponent = E}, + Options) when is_binary(CipherText), is_list(Options) -> + decrypt_public(CipherText, N,E, Options). %%-------------------------------------------------------------------- -%% Function: pem_to_der(CertSource) -> -%% pem_to_der(CertSource, Password) -> {ok, [Entry]} | -%% {error, Reason} +-spec encrypt_public(PlainText :: binary(), rsa_public_key()) -> + CipherText :: binary(). +-spec encrypt_public(PlainText :: binary(), rsa_public_key(), + public_crypt_options()) -> CipherText :: binary(). %% -%% CertSource = File | CertData -%% CertData = binary() -%% File = path() -%% Entry = {entry_type(), der_bin(), ChipherInfo} -%% ChipherInfo = opague() | no_encryption -%% der_bin() = binary() -%% entry_type() = cert | cert_req | rsa_private_key | dsa_private_key -%% dh_params -%% -%% Description: decode PEM binary data or a PEM file and return -%% entries as asn1 der encoded entities. Currently supported entry -%% types are certificates, certificate requests, rsa private keys and -%% dsa private keys. In the case of a key entry ChipherInfo will be -%% private keys and Diffie Hellam parameters .In the case of a key -%% entry ChipherInfo will be used by decode_private_key/2 if the key -%% is protected by a password. +%% Description: Public key encryption using the public key. %%-------------------------------------------------------------------- -pem_to_der(CertSource) -> - pem_to_der(CertSource, no_passwd). +encrypt_public(PlainText, Key) -> + encrypt_public(PlainText, Key, []). -pem_to_der(File, Password) when is_list(File) -> - pubkey_pem:read_file(File, Password); -pem_to_der(PemBin, Password) when is_binary(PemBin) -> - pubkey_pem:decode(PemBin, Password). +encrypt_public(PlainText, #'RSAPublicKey'{modulus=N,publicExponent=E}, + Options) when is_binary(PlainText), is_list(Options) -> + encrypt_public(PlainText, N,E, Options); -der_to_pem(File, TypeDerList) -> - pubkey_pem:write_file(File, TypeDerList). +encrypt_public(PlainText, #'RSAPrivateKey'{modulus=N,publicExponent=E}, + Options) when is_binary(PlainText), is_list(Options) -> + encrypt_public(PlainText, N,E, Options). %%-------------------------------------------------------------------- -%% Function: pkix_decode_cert(BerCert, Type) -> {ok, Cert} | {error, Reason} +-spec encrypt_private(PlainText :: binary(), rsa_private_key()) -> + CipherText :: binary(). +-spec encrypt_private(PlainText :: binary(), rsa_private_key(), + public_crypt_options()) -> CipherText :: binary(). %% -%% BerCert = binary() -%% Type = plain | otp -%% Cert = certificate() -%% -%% Description: Decodes an asn1 ber encoded pkix certificate. -%% otp - Uses OTP-PKIX.asn1 to decode known extensions and -%% enhance the signature field in #'Certificate'{} and '#TBSCertificate'{}. +%% Description: Public key encryption using the private key. %%-------------------------------------------------------------------- -pkix_decode_cert(BinCert, Type) -> - pubkey_cert_records:decode_cert(BinCert, Type). +encrypt_private(PlainText, Key) -> + encrypt_private(PlainText, Key, []). + +encrypt_private(PlainText, #'RSAPrivateKey'{modulus = N, + publicExponent = E, + privateExponent = D}, + Options) when is_binary(PlainText), is_list(Options) -> + Padding = proplists:get_value(rsa_pad, Options, rsa_pkcs1_padding), + crypto:rsa_private_encrypt(PlainText, [crypto:mpint(E), + crypto:mpint(N), + crypto:mpint(D)], Padding). %%-------------------------------------------------------------------- -%% Function: pkix_encode_cert(Cert) -> {ok, binary()} | {error, Reason} +-spec sign(PlainTextOrDigest :: binary(), rsa_digest_type() | dss_digest_type(), + rsa_private_key() | + dsa_private_key()) -> Signature :: binary(). %% -%% Cert = #'Certificate'{} -%% -%% Description: Encodes a certificate record using asn1. +%% Description: Create digital signature. %%-------------------------------------------------------------------- -pkix_encode_cert(Cert) -> - pubkey_cert_records:encode_cert(Cert). +sign(PlainText, DigestType, #'RSAPrivateKey'{modulus = N, publicExponent = E, + privateExponent = D}) + when is_binary(PlainText), + DigestType == md5; + DigestType == sha -> + + crypto:rsa_sign(DigestType, sized_binary(PlainText), [crypto:mpint(E), + crypto:mpint(N), + crypto:mpint(D)]); + +sign(Digest, none, #'DSAPrivateKey'{p = P, q = Q, g = G, x = X}) + when is_binary(Digest)-> + crypto:dss_sign(none, Digest, + [crypto:mpint(P), crypto:mpint(Q), + crypto:mpint(G), crypto:mpint(X)]); + +sign(PlainText, sha, #'DSAPrivateKey'{p = P, q = Q, g = G, x = X}) + when is_binary(PlainText) -> + crypto:dss_sign(sized_binary(PlainText), + [crypto:mpint(P), crypto:mpint(Q), + crypto:mpint(G), crypto:mpint(X)]). + +%%-------------------------------------------------------------------- +-spec verify(PlainTextOrDigest :: binary(), rsa_digest_type() | dss_digest_type(), + Signature :: binary(), rsa_public_key() + | dsa_public_key()) -> boolean(). +%% +%% Description: Verifies a digital signature. +%%-------------------------------------------------------------------- +verify(PlainText, DigestType, Signature, + #'RSAPublicKey'{modulus = Mod, publicExponent = Exp}) + when is_binary (PlainText), DigestType == sha; DigestType == md5 -> + crypto:rsa_verify(DigestType, + sized_binary(PlainText), + sized_binary(Signature), + [crypto:mpint(Exp), crypto:mpint(Mod)]); + +verify(Digest, none, Signature, {Key, #'Dss-Parms'{p = P, q = Q, g = G}}) + when is_integer(Key), is_binary(Digest), is_binary(Signature) -> + crypto:dss_verify(none, + Digest, + sized_binary(Signature), + [crypto:mpint(P), crypto:mpint(Q), + crypto:mpint(G), crypto:mpint(Key)]); +verify(PlainText, sha, Signature, {Key, #'Dss-Parms'{p = P, q = Q, g = G}}) + when is_integer(Key), is_binary(PlainText), is_binary(Signature) -> + crypto:dss_verify(sized_binary(PlainText), + sized_binary(Signature), + [crypto:mpint(P), crypto:mpint(Q), + crypto:mpint(G), crypto:mpint(Key)]). %%-------------------------------------------------------------------- -%% Function: pkix_transform(CertPart, Op) -> TransformedCertPart -%% -%% CertPart = pkix part data -%% Op = encode | decode +-spec pkix_sign(#'OTPTBSCertificate'{}, + rsa_private_key() | dsa_private_key()) -> der_encoded(). %% -%% Description: Transform parts of a pkix certificate between 'plain' format -%% and the internal 'otp' format, see pkix_decode_cert/2. -%% Decode transforms from 'plain' to 'otp' and encode from 'otp' to 'plain' -%% format. +%% Description: Sign a pkix x.509 certificate. Returns the corresponding +%% der encoded 'Certificate'{} %%-------------------------------------------------------------------- -pkix_transform(CertPart, Op) -> - pubkey_cert_records:transform(CertPart, Op). +pkix_sign(#'OTPTBSCertificate'{signature = + #'SignatureAlgorithm'{algorithm = Alg} + = SigAlg} = TBSCert, Key) -> + + Msg = pkix_encode('OTPTBSCertificate', TBSCert, otp), + DigestType = pubkey_cert:digest_type(Alg), + Signature = sign(Msg, DigestType, Key), + Cert = #'OTPCertificate'{tbsCertificate= TBSCert, + signatureAlgorithm = SigAlg, + signature = {0, Signature} + }, + pkix_encode('OTPCertificate', Cert, otp). %%-------------------------------------------------------------------- -%% Function: pkix_path_validation(TrustedCert, CertChain, Options) -> -%% {ok, {{algorithm(), public_key(), public_key_params()} policy_tree()}} | -%% {error, Reason} +-spec pkix_verify(der_encoded(), rsa_public_key()| + dsa_public_key()) -> boolean(). %% -%% Description: Performs a bacis path validation according to RFC 3280. +%% Description: Verify pkix x.509 certificate signature. %%-------------------------------------------------------------------- -pkix_path_validation(TrustedCert, CertChain, Options) - when is_binary(TrustedCert) -> - {ok, OtpCert} = pkix_decode_cert(TrustedCert, otp), - pkix_path_validation(OtpCert, CertChain, Options); +pkix_verify(DerCert, {Key, #'Dss-Parms'{}} = DSAKey) + when is_binary(DerCert), is_integer(Key) -> + {DigestType, PlainText, Signature} = pubkey_cert:verify_data(DerCert), + verify(PlainText, DigestType, Signature, DSAKey); -pkix_path_validation(#'OTPCertificate'{} = TrustedCert, CertChain, Options) - when is_list(CertChain), is_list(Options) -> - MaxPathDefault = length(CertChain), - ValidationState = pubkey_cert:init_validation_state(TrustedCert, - MaxPathDefault, - Options), - Fun = proplists:get_value(validate_extensions_fun, Options, - fun(Extensions, State, _, AccError) -> - {Extensions, State, AccError} - end), - Verify = proplists:get_value(verify, Options, true), - path_validation(CertChain, ValidationState, Fun, Verify). -%%-------------------------------------------------------------------- -%% Function: pkix_is_fixed_dh_cert(Cert) -> true | false +pkix_verify(DerCert, #'RSAPublicKey'{} = RSAKey) + when is_binary(DerCert) -> + {DigestType, PlainText, Signature} = pubkey_cert:verify_data(DerCert), + verify(PlainText, DigestType, Signature, RSAKey). + +%%-------------------------------------------------------------------- +-spec pkix_is_issuer(Cert :: der_encoded()| #'OTPCertificate'{}, + IssuerCert :: der_encoded()| + #'OTPCertificate'{}) -> boolean(). %% -%% Description: Checks if a Certificate is a fixed Diffie-Hellman Cert +%% Description: Checks if <IssuerCert> issued <Cert>. %%-------------------------------------------------------------------- -pkix_is_fixed_dh_cert(#'OTPCertificate'{} = OTPCert) -> - pubkey_cert:is_fixed_dh_cert(OTPCert); -pkix_is_fixed_dh_cert(Cert) when is_binary(Cert) -> - {ok, OtpCert} = pkix_decode_cert(Cert, otp), - pkix_is_fixed_dh_cert(OtpCert). +pkix_is_issuer(Cert, IssuerCert) when is_binary(Cert) -> + OtpCert = pkix_decode_cert(Cert, otp), + pkix_is_issuer(OtpCert, IssuerCert); +pkix_is_issuer(Cert, IssuerCert) when is_binary(IssuerCert) -> + OtpIssuerCert = pkix_decode_cert(IssuerCert, otp), + pkix_is_issuer(Cert, OtpIssuerCert); +pkix_is_issuer(#'OTPCertificate'{tbsCertificate = TBSCert}, + #'OTPCertificate'{tbsCertificate = Candidate}) -> + pubkey_cert:is_issuer(TBSCert#'OTPTBSCertificate'.issuer, + Candidate#'OTPTBSCertificate'.subject). %%-------------------------------------------------------------------- -%% Function: pkix_is_self_signed(Cert) -> true | false +-spec pkix_is_self_signed(der_encoded()| #'OTPCertificate'{}) -> boolean(). %% %% Description: Checks if a Certificate is self signed. %%-------------------------------------------------------------------- pkix_is_self_signed(#'OTPCertificate'{} = OTPCert) -> pubkey_cert:is_self_signed(OTPCert); pkix_is_self_signed(Cert) when is_binary(Cert) -> - {ok, OtpCert} = pkix_decode_cert(Cert, otp), + OtpCert = pkix_decode_cert(Cert, otp), pkix_is_self_signed(OtpCert). - + %%-------------------------------------------------------------------- -%% Function: pkix_issuer_id(Cert) -> {ok, {SerialNr, Issuer}} | {error, Reason} -%% -%% Cert = asn1_der_encoded() | 'OTPCertificate'{} +-spec pkix_is_fixed_dh_cert(der_encoded()| #'OTPCertificate'{}) -> boolean(). %% +%% Description: Checks if a Certificate is a fixed Diffie-Hellman Cert. +%%-------------------------------------------------------------------- +pkix_is_fixed_dh_cert(#'OTPCertificate'{} = OTPCert) -> + pubkey_cert:is_fixed_dh_cert(OTPCert); +pkix_is_fixed_dh_cert(Cert) when is_binary(Cert) -> + OtpCert = pkix_decode_cert(Cert, otp), + pkix_is_fixed_dh_cert(OtpCert). + +%%-------------------------------------------------------------------- +-spec pkix_issuer_id(der_encoded()| #'OTPCertificate'{}, + IssuedBy :: self | other) -> + {ok, {SerialNr :: integer(), + Issuer :: {rdnSequence, + [#'AttributeTypeAndValue'{}]}}} + | {error, Reason :: term()}. +% %% Description: Returns the issuer id. %%-------------------------------------------------------------------- pkix_issuer_id(#'OTPCertificate'{} = OtpCert, self) -> @@ -265,153 +421,113 @@ pkix_issuer_id(#'OTPCertificate'{} = OtpCert, other) -> pubkey_cert:issuer_id(OtpCert, other); pkix_issuer_id(Cert, Signed) when is_binary(Cert) -> - {ok, OtpCert} = pkix_decode_cert(Cert, otp), + OtpCert = pkix_decode_cert(Cert, otp), pkix_issuer_id(OtpCert, Signed). %%-------------------------------------------------------------------- -%% Function: pkix_is_issuer(Cert, IssuerCert) -> true | false -%% -%% Cert = asn1_der_encoded() | 'OTPCertificate'{} -%% IssuerCert = asn1_der_encoded() | 'OTPCertificate'{} +-spec pkix_normalize_name({rdnSequence, + [#'AttributeTypeAndValue'{}]}) -> + {rdnSequence, + [#'AttributeTypeAndValue'{}]}. %% -%% Description: Checks if <IssuerCert> issued <Cert>. +%% Description: Normalizes a issuer name so that it can be easily +%% compared to another issuer name. %%-------------------------------------------------------------------- -pkix_is_issuer(Cert, IssuerCert) when is_binary(Cert) -> - {ok, OtpCert} = pkix_decode_cert(Cert, otp), - pkix_is_issuer(OtpCert, IssuerCert); +pkix_normalize_name(Issuer) -> + pubkey_cert:normalize_general_name(Issuer). -pkix_is_issuer(Cert, IssuerCert) when is_binary(IssuerCert) -> - {ok, OtpIssuerCert} = pkix_decode_cert(IssuerCert, otp), - pkix_is_issuer(Cert, OtpIssuerCert); +%%-------------------------------------------------------------------- +-spec pkix_path_validation(der_encoded()| #'OTPCertificate'{} | unknown_ca, + CertChain :: [der_encoded()] , + Options :: list()) -> + {ok, {PublicKeyInfo :: term(), + PolicyTree :: term()}} | + {error, {bad_cert, Reason :: term()}}. +%% Description: Performs a basic path validation according to RFC 5280. +%%-------------------------------------------------------------------- +pkix_path_validation(unknown_ca, [Cert | Chain], Options0) -> + {VerifyFun, Userstat0} = + proplists:get_value(verify_fun, Options0, ?DEFAULT_VERIFYFUN), + Otpcert = pkix_decode_cert(Cert, otp), + Reason = {bad_cert, unknown_ca}, + try VerifyFun(Otpcert, Reason, Userstat0) of + {valid, Userstate} -> + Options = proplists:delete(verify_fun, Options0), + pkix_path_validation(Otpcert, Chain, [{verify_fun, + {VerifyFun, Userstate}}| Options]); + {fail, _} -> + {error, Reason} + catch + _:_ -> + {error, Reason} + end; +pkix_path_validation(TrustedCert, CertChain, Options) when + is_binary(TrustedCert) -> OtpCert = pkix_decode_cert(TrustedCert, + otp), pkix_path_validation(OtpCert, CertChain, Options); -pkix_is_issuer(#'OTPCertificate'{tbsCertificate = TBSCert}, - #'OTPCertificate'{tbsCertificate = Candidate}) -> - pubkey_cert:is_issuer(TBSCert#'OTPTBSCertificate'.issuer, - Candidate#'OTPTBSCertificate'.subject). - -%%-------------------------------------------------------------------- -%% Function: pkix_normalize_general_name(Issuer) -> -%% -%% Issuer = general_name() - see PKIX -%% -%% Description: Normalizes a general name so that it can be easily -%% compared to another genral name. -%%-------------------------------------------------------------------- -pkix_normalize_general_name(Issuer) -> - pubkey_cert:normalize_general_name(Issuer). +pkix_path_validation(#'OTPCertificate'{} = TrustedCert, CertChain, Options) + when is_list(CertChain), is_list(Options) -> + MaxPathDefault = length(CertChain), + ValidationState = pubkey_cert:init_validation_state(TrustedCert, + MaxPathDefault, + Options), + path_validation(CertChain, ValidationState). %%-------------------------------------------------------------------- -%% Function:sign(Msg, Key) -> {ok, Signature} -%% sign(Msg, Key, KeyParams) -> {ok, Signature} -%% -%% Msg = binary() | #'TBSCertificate'{} -%% Key = private_key() -%% KeyParams = key_params() -%% Signature = binary() -%% -%% Description: Signs plaintext Msg or #TBSCertificate{}, in the later -%% case a der encoded "#Certificate{}" will be returned. +%%% Internal functions %%-------------------------------------------------------------------- -sign(Msg, #'RSAPrivateKey'{} = Key) when is_binary(Msg) -> - pubkey_crypto:sign(Msg, Key); - -sign(Msg, #'DSAPrivateKey'{} = Key) when is_binary(Msg) -> - pubkey_crypto:sign(Msg, Key); -sign(#'OTPTBSCertificate'{signature = #'SignatureAlgorithm'{algorithm = Alg} - = SigAlg} = TBSCert, Key) -> - Msg = pubkey_cert_records:encode_tbs_cert(TBSCert), - DigestType = pubkey_cert:digest_type(Alg), - Signature = pubkey_crypto:sign(DigestType, Msg, Key), - Cert = #'OTPCertificate'{tbsCertificate= TBSCert, - signatureAlgorithm = SigAlg, - signature = {0, Signature} - }, - pkix_encode_cert(Cert). +encrypt_public(PlainText, N, E, Options)-> + Padding = proplists:get_value(rsa_pad, Options, rsa_pkcs1_padding), + crypto:rsa_public_encrypt(PlainText, [crypto:mpint(E),crypto:mpint(N)], + Padding). -sign(DigestType, Msg, Key) -> - pubkey_crypto:sign(DigestType, Msg, Key). +decrypt_public(CipherText, N,E, Options) -> + Padding = proplists:get_value(rsa_pad, Options, rsa_pkcs1_padding), + crypto:rsa_public_decrypt(CipherText,[crypto:mpint(E), crypto:mpint(N)], + Padding). -%%-------------------------------------------------------------------- -%% Function: verify_signature(PlainText, DigestType, Signature, Key) -> -%% verify_signature(PlainText, DigestType, -%% Signature, Key, KeyParams) -> -%% verify_signature(DerCert, Key, KeyParams) -> -%% -%% PlainText = binary() -%% DigestType = md5 | sha -%% DerCert = asn1_der_encoded() -%% Signature = binary() -%% Key = public_key() -%% KeyParams = key_params() -%% Verified = boolean() -%% -%% Description: Verifies the signature <Signature>. -%%-------------------------------------------------------------------- -verify_signature(PlainText, DigestType, Signature, #'RSAPublicKey'{} = Key) - when is_binary(PlainText), is_binary(Signature), DigestType == sha; - DigestType == md5 -> - pubkey_crypto:verify(DigestType, PlainText, Signature, Key, undefined). - -verify_signature(PlainText, DigestType, Signature, #'RSAPublicKey'{} = Key, - KeyParams) - when is_binary(PlainText), is_binary(Signature), DigestType == sha; - DigestType == md5 -> - pubkey_crypto:verify(DigestType, PlainText, Signature, Key, KeyParams); -verify_signature(PlainText, sha, Signature, Key, #'Dss-Parms'{} = KeyParams) - when is_binary(PlainText), is_binary(Signature), is_integer(Key) -> - pubkey_crypto:verify(sha, PlainText, Signature, Key, KeyParams); -verify_signature(Hash, none, Signature, Key, KeyParams) -> - pubkey_crypto:verify(none, Hash, Signature, Key, KeyParams). - -verify_signature(DerCert, Key, #'Dss-Parms'{} = KeyParams) - when is_binary(DerCert), is_integer(Key) -> - pubkey_cert:verify_signature(DerCert, Key, KeyParams); -verify_signature(DerCert, #'RSAPublicKey'{} = Key, KeyParams) - when is_binary(DerCert) -> - pubkey_cert:verify_signature(DerCert, Key, KeyParams). -%%-------------------------------------------------------------------- -%%% Internal functions -%%-------------------------------------------------------------------- path_validation([], #path_validation_state{working_public_key_algorithm = Algorithm, working_public_key = PublicKey, working_public_key_parameters = PublicKeyParams, - valid_policy_tree = Tree, - acc_errors = AccErrors - }, _, _) -> - {ok, {{Algorithm, PublicKey, PublicKeyParams}, Tree, AccErrors}}; + valid_policy_tree = Tree + }) -> + {ok, {{Algorithm, PublicKey, PublicKeyParams}, Tree}}; path_validation([DerCert | Rest], ValidationState = #path_validation_state{ - max_path_length = Len}, - Fun, Verify) when Len >= 0 -> - try validate(DerCert, - ValidationState#path_validation_state{last_cert=Rest=:=[]}, - Fun, Verify) of + max_path_length = Len}) when Len >= 0 -> + try validate(DerCert, + ValidationState#path_validation_state{last_cert=Rest=:=[]}) of #path_validation_state{} = NewValidationState -> - path_validation(Rest, NewValidationState, Fun, Verify) + path_validation(Rest, NewValidationState) catch throw:Reason -> {error, Reason} end; -path_validation(_, _, _, true) -> - {error, {bad_cert, max_path_length_reached}}; +path_validation([DerCert | _] = Path, + #path_validation_state{user_state = UserState0, + verify_fun = VerifyFun} = + ValidationState) -> + Reason = {bad_cert, max_path_length_reached}, + OtpCert = pkix_decode_cert(DerCert, otp), + try VerifyFun(OtpCert, Reason, UserState0) of + {valid, UserState} -> + path_validation(Path, + ValidationState#path_validation_state{ + max_path_length = 0, + user_state = UserState}); + {fail, _} -> + {error, Reason} + catch + _:_ -> + {error, Reason} + end. -path_validation(_, #path_validation_state{working_public_key_algorithm - = Algorithm, - working_public_key = - PublicKey, - working_public_key_parameters - = PublicKeyParams, - valid_policy_tree = Tree, - acc_errors = AccErrors - }, _, false) -> - {ok, {{Algorithm, PublicKey, PublicKeyParams}, Tree, - [{bad_cert, max_path_length_reached}|AccErrors]}}. validate(DerCert, #path_validation_state{working_issuer_name = Issuer, working_public_key = Key, @@ -421,38 +537,50 @@ validate(DerCert, #path_validation_state{working_issuer_name = Issuer, excluded_subtrees = Exclude, last_cert = Last, user_state = UserState0, - acc_errors = AccErr0} = - ValidationState0, ValidateExtensionFun, Verify) -> - {ok, OtpCert} = pkix_decode_cert(DerCert, otp), - %% All validate functions will throw {bad_cert, Reason} if they - %% fail and Verify = true if Verify = false errors - %% will be accumulated in the validationstate - AccErr1 = pubkey_cert:validate_time(OtpCert, AccErr0, Verify), - - AccErr2 = pubkey_cert:validate_issuer(OtpCert, Issuer, AccErr1, Verify), - - AccErr3 = pubkey_cert:validate_names(OtpCert, Permit, Exclude, Last, - AccErr2, Verify), - AccErr4 = - pubkey_cert:validate_revoked_status(OtpCert, Verify, AccErr3), + verify_fun = VerifyFun} = + ValidationState0) -> + OtpCert = pkix_decode_cert(DerCert, otp), + + UserState1 = pubkey_cert:validate_time(OtpCert, UserState0, VerifyFun), + + UserState2 = pubkey_cert:validate_issuer(OtpCert, Issuer, UserState1, VerifyFun), + + UserState3 = pubkey_cert:validate_names(OtpCert, Permit, Exclude, Last, + UserState2,VerifyFun), + + UserState4 = pubkey_cert:validate_revoked_status(OtpCert, UserState3, VerifyFun), - {ValidationState1, UnknownExtensions0, AccErr5} = - pubkey_cert:validate_extensions(OtpCert, ValidationState0, Verify, - AccErr4), - %% We want the key_usage extension to be checked before we validate + {ValidationState1, UserState5} = + pubkey_cert:validate_extensions(OtpCert, ValidationState0, UserState4, + VerifyFun), + + %% We want the key_usage extension to be checked before we validate %% the signature. - AccErr6 = - pubkey_cert:validate_signature(OtpCert, DerCert, Key, KeyParams, - AccErr5, Verify), - - {UnknownExtensions, UserState, AccErr7} = - ValidateExtensionFun(UnknownExtensions0, UserState0, Verify, AccErr6), - - %% Check that all critical extensions have been handled - AccErr = - pubkey_cert:validate_unknown_extensions(UnknownExtensions, AccErr7, - Verify), + UserState = pubkey_cert:validate_signature(OtpCert, DerCert, + Key, KeyParams, UserState5, VerifyFun), ValidationState = - ValidationState1#path_validation_state{user_state = UserState, - acc_errors = AccErr}, + ValidationState1#path_validation_state{user_state = UserState}, pubkey_cert:prepare_for_next_cert(OtpCert, ValidationState). + +sized_binary(Binary) when is_binary(Binary) -> + Size = size(Binary), + <<?UINT32(Size), Binary/binary>>; +sized_binary(List) -> + sized_binary(list_to_binary(List)). + +%%-------------------------------------------------------------------- +%%% Deprecated functions +%%-------------------------------------------------------------------- +pem_to_der(CertSource) -> + {ok, Bin} = file:read_file(CertSource), + pubkey_pem:decode(Bin). + +decode_private_key(KeyInfo) -> + decode_private_key(KeyInfo, no_passwd). + +decode_private_key(KeyInfo = {'RSAPrivateKey', _, _}, Password) -> + DerEncoded = pubkey_pem:decode_key(KeyInfo, Password), + 'OTP-PUB-KEY':decode('RSAPrivateKey', DerEncoded); +decode_private_key(KeyInfo = {'DSAPrivateKey', _, _}, Password) -> + DerEncoded = pubkey_pem:decode_key(KeyInfo, Password), + 'OTP-PUB-KEY':decode('DSAPrivateKey', DerEncoded). diff --git a/lib/public_key/test/Makefile b/lib/public_key/test/Makefile index 5544339ff2..e20b903942 100644 --- a/lib/public_key/test/Makefile +++ b/lib/public_key/test/Makefile @@ -28,7 +28,7 @@ INCLUDES= -I. -I ../include # ---------------------------------------------------- MODULES= \ - pkey_test \ + erl_make_certs \ public_key_SUITE \ pkits_SUITE diff --git a/lib/public_key/test/pkey_test.erl b/lib/public_key/test/erl_make_certs.erl index 4cf20f0174..e31e5552d3 100644 --- a/lib/public_key/test/pkey_test.erl +++ b/lib/public_key/test/erl_make_certs.erl @@ -19,7 +19,7 @@ %% Create test certificates --module(pkey_test). +-module(erl_make_certs). -include_lib("public_key/include/public_key.hrl"). -export([make_cert/1, gen_rsa/1, verify_signature/3, write_pem/3]). @@ -34,7 +34,7 @@ %% version 3 %% subject [] list of the following content %% {name, Name} -%% {email, Email} +%% {email, Email} %% {city, City} %% {state, State} %% {org, Org} @@ -56,7 +56,7 @@ make_cert(Opts) -> SubjectPrivateKey = get_key(Opts), {TBSCert, IssuerKey} = make_tbs(SubjectPrivateKey, Opts), - Cert = public_key:sign(TBSCert, IssuerKey), + Cert = public_key:pkix_sign(TBSCert, IssuerKey), true = verify_signature(Cert, IssuerKey, undef), %% verify that the keys where ok {Cert, encode_key(SubjectPrivateKey)}. @@ -66,8 +66,9 @@ make_cert(Opts) -> %% @end %%-------------------------------------------------------------------- write_pem(Dir, FileName, {Cert, Key = {_,_,not_encrypted}}) when is_binary(Cert) -> - ok = public_key:der_to_pem(filename:join(Dir, FileName ++ ".pem"), [{cert, Cert, not_encrypted}]), - ok = public_key:der_to_pem(filename:join(Dir, FileName ++ "_key.pem"), [Key]). + ok = der_to_pem(filename:join(Dir, FileName ++ ".pem"), + [{'Certificate', Cert, not_encrypted}]), + ok = der_to_pem(filename:join(Dir, FileName ++ "_key.pem"), [Key]). %%-------------------------------------------------------------------- %% @doc Creates a rsa key (OBS: for testing only) @@ -94,18 +95,14 @@ gen_dsa(LSize,NSize) when is_integer(LSize), is_integer(NSize) -> %% @spec (::binary(), ::tuple()) -> ::boolean() %% @end %%-------------------------------------------------------------------- -verify_signature(DerEncodedCert, DerKey, KeyParams) -> +verify_signature(DerEncodedCert, DerKey, _KeyParams) -> Key = decode_key(DerKey), case Key of #'RSAPrivateKey'{modulus=Mod, publicExponent=Exp} -> - public_key:verify_signature(DerEncodedCert, - #'RSAPublicKey'{modulus=Mod, publicExponent=Exp}, - 'NULL'); + public_key:pkix_verify(DerEncodedCert, + #'RSAPublicKey'{modulus=Mod, publicExponent=Exp}); #'DSAPrivateKey'{p=P, q=Q, g=G, y=Y} -> - public_key:verify_signature(DerEncodedCert, Y, #'Dss-Parms'{p=P, q=Q, g=G}); - - _ -> - public_key:verify_signature(DerEncodedCert, Key, KeyParams) + public_key:pkix_verify(DerEncodedCert, {Y, #'Dss-Parms'{p=P, q=Q, g=G}}) end. %%%%%%%%%%%%%%%%%%%%%%%%% Implementation %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -132,59 +129,63 @@ decode_key(#'RSAPrivateKey'{} = Key,_) -> Key; decode_key(#'DSAPrivateKey'{} = Key,_) -> Key; -decode_key(Der = {_,_,_}, Pw) -> - {ok, Key} = public_key:decode_private_key(Der, Pw), - Key; -decode_key(FileOrDer, Pw) -> - {ok, [KeyInfo]} = public_key:pem_to_der(FileOrDer), +decode_key(PemEntry = {_,_,_}, Pw) -> + public_key:pem_entry_decode(PemEntry, Pw); +decode_key(PemBin, Pw) -> + [KeyInfo] = public_key:pem_decode(PemBin), decode_key(KeyInfo, Pw). encode_key(Key = #'RSAPrivateKey'{}) -> {ok, Der} = 'OTP-PUB-KEY':encode('RSAPrivateKey', Key), - {rsa_private_key, list_to_binary(Der), not_encrypted}; + {'RSAPrivateKey', list_to_binary(Der), not_encrypted}; encode_key(Key = #'DSAPrivateKey'{}) -> {ok, Der} = 'OTP-PUB-KEY':encode('DSAPrivateKey', Key), - {dsa_private_key, list_to_binary(Der), not_encrypted}. + {'DSAPrivateKey', list_to_binary(Der), not_encrypted}. make_tbs(SubjectKey, Opts) -> Version = list_to_atom("v"++integer_to_list(proplists:get_value(version, Opts, 3))), - {Issuer, IssuerKey} = issuer(Opts, SubjectKey), + + IssuerProp = proplists:get_value(issuer, Opts, true), + {Issuer, IssuerKey} = issuer(IssuerProp, Opts, SubjectKey), {Algo, Parameters} = sign_algorithm(IssuerKey, Opts), SignAlgo = #'SignatureAlgorithm'{algorithm = Algo, parameters = Parameters}, - + Subject = case IssuerProp of + true -> %% Is a Root Ca + Issuer; + _ -> + subject(proplists:get_value(subject, Opts),false) + end, + {#'OTPTBSCertificate'{serialNumber = trunc(random:uniform()*100000000)*10000 + 1, signature = SignAlgo, issuer = Issuer, validity = validity(Opts), - subject = subject(proplists:get_value(subject, Opts),false), + subject = Subject, subjectPublicKeyInfo = publickey(SubjectKey), version = Version, extensions = extensions(Opts) }, IssuerKey}. -issuer(Opts, SubjectKey) -> - IssuerProp = proplists:get_value(issuer, Opts, true), - case IssuerProp of - true -> %% Self signed - {subject(proplists:get_value(subject, Opts), true), SubjectKey}; - {Issuer, IssuerKey} when is_binary(Issuer) -> - {issuer_der(Issuer), decode_key(IssuerKey)}; - {File, IssuerKey} when is_list(File) -> - {ok, [{cert, Cert, _}|_]} = public_key:pem_to_der(File), - {issuer_der(Cert), decode_key(IssuerKey)} - end. +issuer(true, Opts, SubjectKey) -> + %% Self signed + {subject(proplists:get_value(subject, Opts), true), SubjectKey}; +issuer({Issuer, IssuerKey}, _Opts, _SubjectKey) when is_binary(Issuer) -> + {issuer_der(Issuer), decode_key(IssuerKey)}; +issuer({File, IssuerKey}, _Opts, _SubjectKey) when is_list(File) -> + {ok, [{cert, Cert, _}|_]} = public_key:pem_to_der(File), + {issuer_der(Cert), decode_key(IssuerKey)}. issuer_der(Issuer) -> - {ok, Decoded} = public_key:pkix_decode_cert(Issuer, otp), + Decoded = public_key:pkix_decode_cert(Issuer, otp), #'OTPCertificate'{tbsCertificate=Tbs} = Decoded, #'OTPTBSCertificate'{subject=Subject} = Tbs, Subject. -subject(undefined, IsCA) -> - User = if IsCA -> "CA"; true -> os:getenv("USER") end, +subject(undefined, IsRootCA) -> + User = if IsRootCA -> "RootCA"; true -> os:getenv("USER") end, Opts = [{email, User ++ "@erlang.org"}, {name, User}, {city, "Stockholm"}, @@ -410,3 +411,11 @@ extended_gcd(A, B) -> {X, Y} = extended_gcd(B, N), {Y, X-Y*(A div B)} end. + +pem_to_der(File) -> + {ok, PemBin} = file:read_file(File), + public_key:pem_decode(PemBin). + +der_to_pem(File, Entries) -> + PemBin = public_key:pem_encode(Entries), + file:write_file(File, PemBin). diff --git a/lib/public_key/test/pkits_SUITE.erl b/lib/public_key/test/pkits_SUITE.erl index 5d58b39e26..1d75e1aed2 100644 --- a/lib/public_key/test/pkits_SUITE.erl +++ b/lib/public_key/test/pkits_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2009. All Rights Reserved. +%% Copyright Ericsson AB 2008-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 @@ -187,9 +187,9 @@ run([],_) -> ok. read_certs(Test) -> File = test_file(Test), %% io:format("Read ~p ",[File]), - {ok, Ders} = public_key:pem_to_der(File), + Ders = erl_make_certs:pem_to_der(File), %% io:format("Ders ~p ~n",[length(Ders)]), - [Cert || {cert,Cert,not_encrypted} <- Ders]. + [Cert || {'Certificate', Cert, not_encrypted} <- Ders]. test_file(Test) -> file(?CONV, lists:append(string:tokens(Test, " -")) ++ ".pem"). diff --git a/lib/public_key/test/public_key_SUITE.erl b/lib/public_key/test/public_key_SUITE.erl index dc1015969a..46b8c3db8b 100644 --- a/lib/public_key/test/public_key_SUITE.erl +++ b/lib/public_key/test/public_key_SUITE.erl @@ -101,13 +101,12 @@ all(doc) -> all(suite) -> [app, - dh, - pem_to_der, - decode_private_key, + pk_decode_encode, encrypt_decrypt, sign_verify, pkix, - pkix_path_validation + pkix_path_validation, + deprecated ]. %% Test cases starts here. @@ -120,85 +119,100 @@ app(suite) -> app(Config) when is_list(Config) -> ok = test_server:app_test(public_key). -dh(doc) -> - "Test diffie-hellman functions file is ok"; -dh(suite) -> +pk_decode_encode(doc) -> + ["Tests pem_decode/1, pem_encode/1, " + "der_decode/2, der_encode/2, " + "pem_entry_decode/1, pem_entry_decode/2," + "pem_entry_encode/2, pem_entry_encode/3."]; + +pk_decode_encode(suite) -> []; -dh(Config) when is_list(Config) -> +pk_decode_encode(Config) when is_list(Config) -> Datadir = ?config(data_dir, Config), - {ok,[DerDHparams = {dh_params, _, _}]} = - public_key:pem_to_der(filename:join(Datadir, "dh.pem")), - {ok, DHps = #'DHParameter'{prime=P,base=G}} = public_key:decode_dhparams(DerDHparams), - DHKeys = {Private,_Public} = public_key:gen_key(DHps), - test_server:format("DHparams = ~p~nDH Keys~p~n", [DHps, DHKeys]), - {_Private,_Public2} = pubkey_crypto:gen_key(diffie_hellman, [crypto:erlint(Private), P, G]), - ok. + + [{'DSAPrivateKey', DerDSAKey, not_encrypted} = Entry0 ] = + erl_make_certs:pem_to_der(filename:join(Datadir, "dsa.pem")), + + DSAKey = public_key:der_decode('DSAPrivateKey', DerDSAKey), + + DSAKey = public_key:pem_entry_decode(Entry0), + + [{'RSAPrivateKey', DerRSAKey, not_encrypted} = Entry1 ] = + erl_make_certs:pem_to_der(filename:join(Datadir, "client_key.pem")), + + RSAKey0 = public_key:der_decode('RSAPrivateKey', DerRSAKey), + + RSAKey0 = public_key:pem_entry_decode(Entry1), + + [{'RSAPrivateKey', _, {_,_}} = Entry2] = + erl_make_certs:pem_to_der(filename:join(Datadir, "rsa.pem")), + true = check_entry_type(public_key:pem_entry_decode(Entry2, "abcd1234"), + 'RSAPrivateKey'), -pem_to_der(doc) -> - ["Check that supported PEM files are decoded into the expected entry type"]; -pem_to_der(suite) -> - []; -pem_to_der(Config) when is_list(Config) -> - Datadir = ?config(data_dir, Config), - {ok,DSAKey =[{dsa_private_key, _, not_encrypted}]} = - public_key:pem_to_der(filename:join(Datadir, "dsa.pem")), - {ok,[{rsa_private_key, _, _}]} = - public_key:pem_to_der(filename:join(Datadir, "client_key.pem")), - {ok, [{rsa_private_key, _, _}]} = - public_key:pem_to_der(filename:join(Datadir, "rsa.pem")), - {ok,[{rsa_private_key, _, _}]} = - public_key:pem_to_der(filename:join(Datadir, "rsa.pem"), "abcd1234"), - {ok, Bin0} = file:read_file(filename:join(Datadir, "rsa.pem")), - {ok, [{rsa_private_key, _, _}]} = public_key:pem_to_der(Bin0, "abcd1234"), - - {ok,[{dh_params, _, _}]} = - public_key:pem_to_der(filename:join(Datadir, "dh.pem")), - {ok,[{cert, _, not_encrypted}]} = - public_key:pem_to_der(filename:join(Datadir, "client_cert.pem")), - {ok,[{cert_req, _, _}]} = - public_key:pem_to_der(filename:join(Datadir, "req.pem")), - {ok, Certs = [{cert, _, _}, {cert, _, _}]} = - public_key:pem_to_der(filename:join(Datadir, "cacerts.pem")), - - {ok, Bin1} = file:read_file(filename:join(Datadir, "cacerts.pem")), - {ok, [{cert, _, _}, {cert, _, _}]} = public_key:pem_to_der(Bin1), - - ok = public_key:der_to_pem(filename:join(Datadir, "wcacerts.pem"), Certs), - ok = public_key:der_to_pem(filename:join(Datadir, "wdsa.pem"), DSAKey), + Salt0 = crypto:rand_bytes(8), + Entry3 = public_key:pem_entry_encode('RSAPrivateKey', RSAKey0, + {{"DES-EDE3-CBC", Salt0}, "1234abcd"}), + + RSAKey0 = public_key:pem_entry_decode(Entry3,"1234abcd"), - {ok, Certs} = public_key:pem_to_der(filename:join(Datadir, "wcacerts.pem")), - {ok, DSAKey} = public_key:pem_to_der(filename:join(Datadir, "wdsa.pem")), + Des3KeyFile = filename:join(Datadir, "des3_client_key.pem"), - ok. -%%-------------------------------------------------------------------- -decode_private_key(doc) -> - ["Check that private keys are decode to the expected key type."]; -decode_private_key(suite) -> - []; -decode_private_key(Config) when is_list(Config) -> - Datadir = ?config(data_dir, Config), - {ok,[DsaKey = {dsa_private_key, _DsaKey, _}]} = - public_key:pem_to_der(filename:join(Datadir, "dsa.pem")), - {ok,[RsaKey = {rsa_private_key, _RsaKey,_}]} = - public_key:pem_to_der(filename:join(Datadir, "client_key.pem")), - {ok,[ProtectedRsaKey1 = {rsa_private_key, _ProtectedRsaKey1,_}]} = - public_key:pem_to_der(filename:join(Datadir, "rsa.pem"), "abcd1234"), - {ok,[ProtectedRsaKey2 = {rsa_private_key, _ProtectedRsaKey2,_}]} = - public_key:pem_to_der(filename:join(Datadir, "rsa.pem")), + erl_make_certs:der_to_pem(Des3KeyFile, [Entry3]), - {ok, #'DSAPrivateKey'{}} = public_key:decode_private_key(DsaKey), - {ok, #'RSAPrivateKey'{}} = public_key:decode_private_key(RsaKey), - {ok, #'RSAPrivateKey'{}} = public_key:decode_private_key(ProtectedRsaKey1), - {ok, #'RSAPrivateKey'{}} = public_key:decode_private_key(ProtectedRsaKey2, "abcd1234"), + [{'RSAPrivateKey', _, {"DES-EDE3-CBC", Salt0}}] = erl_make_certs:pem_to_der(Des3KeyFile), + + Salt1 = crypto:rand_bytes(8), + Entry4 = public_key:pem_entry_encode('RSAPrivateKey', RSAKey0, + {{"DES-CBC", Salt1}, "4567efgh"}), + + + DesKeyFile = filename:join(Datadir, "des_client_key.pem"), + + erl_make_certs:der_to_pem(DesKeyFile, [Entry4]), + + [{'RSAPrivateKey', _, {"DES-CBC", Salt1}} =Entry5] = erl_make_certs:pem_to_der(DesKeyFile), + + + true = check_entry_type(public_key:pem_entry_decode(Entry5, "4567efgh"), + 'RSAPrivateKey'), + + [{'DHParameter', DerDH, not_encrypted} = Entry6] = + erl_make_certs:pem_to_der(filename:join(Datadir, "dh.pem")), + + erl_make_certs:der_to_pem(filename:join(Datadir, "new_dh.pem"), [Entry6]), + + DHParameter = public_key:der_decode('DHParameter', DerDH), + DHParameter = public_key:pem_entry_decode(Entry6), + + Entry6 = public_key:pem_entry_encode('DHParameter', DHParameter), + + [{'Certificate', DerCert, not_encrypted} = Entry7] = + 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), + + CertEntries = [{'Certificate', _, not_encrypted} = CertEntry0, + {'Certificate', _, not_encrypted} = CertEntry1] = + 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")), ok. + %%-------------------------------------------------------------------- encrypt_decrypt(doc) -> [""]; encrypt_decrypt(suite) -> []; encrypt_decrypt(Config) when is_list(Config) -> - {PrivateKey, _DerKey} = pkey_test:gen_rsa(64), + {PrivateKey, _DerKey} = erl_make_certs:gen_rsa(64), #'RSAPrivateKey'{modulus=Mod, publicExponent=Exp} = PrivateKey, PublicKey = #'RSAPublicKey'{modulus=Mod, publicExponent=Exp}, Msg = list_to_binary(lists:duplicate(5, "Foo bar 100")), @@ -219,69 +233,81 @@ sign_verify(suite) -> []; sign_verify(Config) when is_list(Config) -> %% Make cert signs and validates the signature using RSA and DSA - Ca = {_, CaKey} = pkey_test:make_cert([]), - {ok, PrivateRSA = #'RSAPrivateKey'{modulus=Mod, publicExponent=Exp}} = - public_key:decode_private_key(CaKey), + Ca = {_, CaKey} = erl_make_certs:make_cert([]), + PrivateRSA = #'RSAPrivateKey'{modulus=Mod, publicExponent=Exp} = + public_key:pem_entry_decode(CaKey), - CertInfo = {Cert1,CertKey1} = pkey_test:make_cert([{key, dsa}, {issuer, Ca}]), + CertInfo = {Cert1,CertKey1} = erl_make_certs:make_cert([{key, dsa}, {issuer, Ca}]), PublicRSA = #'RSAPublicKey'{modulus=Mod, publicExponent=Exp}, - true = public_key:verify_signature(Cert1, PublicRSA, undefined), + true = public_key:pkix_verify(Cert1, PublicRSA), - {Cert2,_CertKey} = pkey_test:make_cert([{issuer, CertInfo}]), + {Cert2,_CertKey} = erl_make_certs:make_cert([{issuer, CertInfo}]), - {ok, #'DSAPrivateKey'{p=P, q=Q, g=G, y=Y, x=_X}} = - public_key:decode_private_key(CertKey1), - true = public_key:verify_signature(Cert2, Y, #'Dss-Parms'{p=P, q=Q, g=G}), + #'DSAPrivateKey'{p=P, q=Q, g=G, y=Y, x=_X} = + public_key:pem_entry_decode(CertKey1), + true = public_key:pkix_verify(Cert2, {Y, #'Dss-Parms'{p=P, q=Q, g=G}}), %% RSA sign Msg0 = lists:duplicate(5, "Foo bar 100"), Msg = list_to_binary(Msg0), - RSASign = public_key:sign(sha, Msg0, PrivateRSA), - RSASign = public_key:sign(Msg, PrivateRSA), - true = public_key:verify_signature(Msg, sha, RSASign, PublicRSA), - false = public_key:verify_signature(<<1:8, Msg/binary>>, sha, RSASign, PublicRSA), - false = public_key:verify_signature(Msg, sha, <<1:8, RSASign/binary>>, PublicRSA), - RSASign = public_key:sign(sha, Msg, PrivateRSA), - - RSASign1 = public_key:sign(md5, Msg, PrivateRSA), - true = public_key:verify_signature(Msg, md5, RSASign1, PublicRSA), + + RSASign = public_key:sign(Msg0, sha, PrivateRSA), + RSASign = public_key:sign(Msg, sha, PrivateRSA), + true = public_key:verify(Msg, sha, RSASign, PublicRSA), + false = public_key:verify(<<1:8, Msg/binary>>, sha, RSASign, PublicRSA), + false = public_key:verify(Msg, sha, <<1:8, RSASign/binary>>, PublicRSA), + + RSASign1 = public_key:sign(Msg, md5, PrivateRSA), + true = public_key:verify(Msg, md5, RSASign1, PublicRSA), %% DSA sign Datadir = ?config(data_dir, Config), - {ok,[DsaKey = {dsa_private_key, _, _}]} = - public_key:pem_to_der(filename:join(Datadir, "dsa.pem")), - {ok, DSAPrivateKey} = public_key:decode_private_key(DsaKey), + [DsaKey = {'DSAPrivateKey', _, _}] = + erl_make_certs:pem_to_der(filename:join(Datadir, "dsa.pem")), + DSAPrivateKey = public_key:pem_entry_decode(DsaKey), #'DSAPrivateKey'{p=P1, q=Q1, g=G1, y=Y1, x=_X1} = DSAPrivateKey, - DSASign = public_key:sign(Msg, DSAPrivateKey), + DSASign = public_key:sign(Msg, sha, DSAPrivateKey), DSAPublicKey = Y1, DSAParams = #'Dss-Parms'{p=P1, q=Q1, g=G1}, - true = public_key:verify_signature(Msg, sha, DSASign, DSAPublicKey, DSAParams), - false = public_key:verify_signature(<<1:8, Msg/binary>>, sha, DSASign, DSAPublicKey, DSAParams), - false = public_key:verify_signature(Msg, sha, <<1:8, DSASign/binary>>, DSAPublicKey, DSAParams), + true = public_key:verify(Msg, sha, DSASign, {DSAPublicKey, DSAParams}), + false = public_key:verify(<<1:8, Msg/binary>>, sha, DSASign, + {DSAPublicKey, DSAParams}), + false = public_key:verify(Msg, sha, <<1:8, DSASign/binary>>, + {DSAPublicKey, DSAParams}), + + Digest = crypto:sha(Msg), + DigestSign = public_key:sign(Digest, none, DSAPrivateKey), + true = public_key:verify(Digest, none, DigestSign, {DSAPublicKey, DSAParams}), + <<_:8, RestDigest/binary>> = Digest, + false = public_key:verify(<<1:8, RestDigest/binary>>, none, DigestSign, + {DSAPublicKey, DSAParams}), + false = public_key:verify(Digest, none, <<1:8, DigestSign/binary>>, + {DSAPublicKey, DSAParams}), ok. - +%%-------------------------------------------------------------------- pkix(doc) -> "Misc pkix tests not covered elsewhere"; pkix(suite) -> []; pkix(Config) when is_list(Config) -> Datadir = ?config(data_dir, Config), - {ok,Certs0} = public_key:pem_to_der(filename:join(Datadir, "cacerts.pem")), - {ok,Certs1} = public_key:pem_to_der(filename:join(Datadir, "client_cert.pem")), - TestTransform = fun({cert, CertDer, not_encrypted}) -> - {ok, PlainCert} = public_key:pkix_decode_cert(CertDer, plain), - {ok, OtpCert} = public_key:pkix_decode_cert(CertDer, otp), - CertDer = public_key:pkix_encode_cert(OtpCert), - CertDer = public_key:pkix_encode_cert(PlainCert), - - OTPSubj = (OtpCert#'OTPCertificate'.tbsCertificate)#'OTPTBSCertificate'.subject, - Subj = public_key:pkix_transform(OTPSubj, encode), - {ok, DNEncoded} = 'OTP-PUB-KEY':encode('Name', Subj), - Subj2 = (PlainCert#'Certificate'.tbsCertificate)#'TBSCertificate'.subject, - {ok, DNEncoded} = 'OTP-PUB-KEY':encode('Name', Subj2), - OTPSubj = public_key:pkix_transform(Subj2, decode), + Certs0 = erl_make_certs:pem_to_der(filename:join(Datadir, "cacerts.pem")), + Certs1 = erl_make_certs:pem_to_der(filename:join(Datadir, "client_cert.pem")), + TestTransform = fun({'Certificate', CertDer, not_encrypted}) -> + PlainCert = public_key:pkix_decode_cert(CertDer, plain), + OtpCert = public_key:pkix_decode_cert(CertDer, otp), + CertDer = + public_key:pkix_encode('OTPCertificate', OtpCert, otp), + CertDer = + public_key:pkix_encode('Certificate', PlainCert, plain), + OTPTBS = OtpCert#'OTPCertificate'.tbsCertificate, + OTPSubj = OTPTBS#'OTPTBSCertificate'.subject, + DNEncoded = public_key:pkix_encode('Name', OTPSubj, otp), + PlainTBS = PlainCert#'Certificate'.tbsCertificate, + Subj2 = PlainTBS#'TBSCertificate'.subject, + DNEncoded = public_key:pkix_encode('Name', Subj2, plain), false = public_key:pkix_is_fixed_dh_cert(CertDer) end, @@ -290,26 +316,31 @@ pkix(Config) when is_list(Config) -> true = public_key:pkix_is_self_signed(element(2,hd(Certs0))), false = public_key:pkix_is_self_signed(element(2,hd(Certs1))), - CaIds = [element(2, public_key:pkix_issuer_id(Cert, self)) || {cert, Cert, _} <- Certs0], - {ok, IssuerId = {_, IssuerName}} = public_key:pkix_issuer_id(element(2,hd(Certs1)), other), + CaIds = [element(2, public_key:pkix_issuer_id(Cert, self)) || + {'Certificate', Cert, _} <- Certs0], + {ok, IssuerId = {_, _IssuerName}} = + public_key:pkix_issuer_id(element(2,hd(Certs1)), other), + true = lists:member(IssuerId, CaIds), %% Should be normalized allready - TestStr = {rdnSequence, [[{'AttributeTypeAndValue', {2,5,4,3},{printableString,"ERLANGCA"}}], - [{'AttributeTypeAndValue', {2,5,4,3},{printableString," erlang ca "}}]]}, - VerifyStr = {rdnSequence, [[{'AttributeTypeAndValue', {2,5,4,3},{printableString,"erlang ca"}}], - [{'AttributeTypeAndValue', {2,5,4,3},{printableString,"erlangca"}}]]}, - VerifyStr = public_key:pkix_normalize_general_name(TestStr), + TestStr = {rdnSequence, + [[{'AttributeTypeAndValue', {2,5,4,3},{printableString,"ERLANGCA"}}], + [{'AttributeTypeAndValue', {2,5,4,3},{printableString," erlang ca "}}]]}, + VerifyStr = {rdnSequence, + [[{'AttributeTypeAndValue', {2,5,4,3},{printableString,"erlang ca"}}], + [{'AttributeTypeAndValue', {2,5,4,3},{printableString,"erlangca"}}]]}, + VerifyStr = public_key:pkix_normalize_name(TestStr), ok. - +%%-------------------------------------------------------------------- pkix_path_validation(doc) -> "Misc pkix tests not covered elsewhere"; pkix_path_validation(suite) -> []; pkix_path_validation(Config) when is_list(Config) -> CaK = {Trusted,_} = - pkey_test:make_cert([{key, dsa}, + erl_make_certs:make_cert([{key, dsa}, {subject, [ {name, "Public Key"}, {?'id-at-name', {printableString, "public_key"}}, @@ -320,26 +351,83 @@ pkix_path_validation(Config) when is_list(Config) -> {org_unit, "testing dep"} ]} ]), - ok = pkey_test:write_pem("./", "public_key_cacert", CaK), + ok = erl_make_certs:write_pem("./", "public_key_cacert", CaK), - CertK1 = {Cert1, _} = pkey_test:make_cert([{issuer, CaK}]), - CertK2 = {Cert2,_} = pkey_test:make_cert([{issuer, CertK1}, {digest, md5}, {extensions, false}]), - ok = pkey_test:write_pem("./", "public_key_cert", CertK2), + CertK1 = {Cert1, _} = erl_make_certs:make_cert([{issuer, CaK}]), + CertK2 = {Cert2,_} = erl_make_certs:make_cert([{issuer, CertK1}, + {digest, md5}, {extensions, false}]), + ok = erl_make_certs:write_pem("./", "public_key_cert", CertK2), {ok, _} = public_key:pkix_path_validation(Trusted, [Cert1], []), - {error, {bad_cert,invalid_issuer}} = public_key:pkix_path_validation(Trusted, [Cert2], []), - %%{error, {bad_cert,invalid_issuer}} = public_key:pkix_path_validation(Trusted, [Cert2], [{verify,false}]), + {error, {bad_cert,invalid_issuer}} = + public_key:pkix_path_validation(Trusted, [Cert2], []), {ok, _} = public_key:pkix_path_validation(Trusted, [Cert1, Cert2], []), {error, issuer_not_found} = public_key:pkix_issuer_id(Cert2, other), - CertK3 = {Cert3,_} = pkey_test:make_cert([{issuer, CertK1}, {extensions, [{basic_constraints, false}]}]), - {Cert4,_} = pkey_test:make_cert([{issuer, CertK3}]), - {error, E={bad_cert,missing_basic_constraint}} = + CertK3 = {Cert3,_} = erl_make_certs:make_cert([{issuer, CertK1}, + {extensions, [{basic_constraints, false}]}]), + {Cert4,_} = erl_make_certs:make_cert([{issuer, CertK3}]), + {error, {bad_cert,missing_basic_constraint}} = public_key:pkix_path_validation(Trusted, [Cert1, Cert3,Cert4], []), - - {ok, {_,_,[E]}} = public_key:pkix_path_validation(Trusted, [Cert1, Cert3,Cert4], [{verify,false}]), - % test_server:format("PV ~p ~n", [Result]), + VerifyFunAndState0 = {fun(_,{bad_cert, missing_basic_constraint}, UserState) -> + {valid, UserState}; + (_,{bad_cert, _} = Reason, _) -> + {fail, Reason}; + (_,{extension, _}, UserState) -> + {unknown, UserState} + end, []}, + {ok, _} = + public_key:pkix_path_validation(Trusted, [Cert1, Cert3,Cert4], + [{verify_fun, VerifyFunAndState0}]), + + {error, {bad_cert, unknown_ca}} = + public_key:pkix_path_validation(unknown_ca, [Cert1, Cert3, Cert4], []), + + VerifyFunAndState1 = + {fun(_,{bad_cert, unknown_ca}, UserState) -> + {valid, UserState}; + (_,{bad_cert, _} = Reason, _) -> + {fail, Reason}; + (_,{extension, _}, UserState) -> + {unknown, UserState} + end, []}, + + {ok, _} = + public_key:pkix_path_validation(unknown_ca, [Cert1], [{verify_fun, + VerifyFunAndState1}]), ok. + +%%-------------------------------------------------------------------- +deprecated(doc) -> + ["Check deprecated functions."]; +deprecated(suite) -> + []; +deprecated(Config) when is_list(Config) -> + Datadir = ?config(data_dir, Config), + [DsaKey = {'DSAPrivateKey', _DsaKey, _}] = + public_key:pem_to_der(filename:join(Datadir, "dsa.pem")), + [RsaKey = {'RSAPrivateKey', _RsaKey,_}] = + public_key:pem_to_der(filename:join(Datadir, "client_key.pem")), + [ProtectedRsaKey = {'RSAPrivateKey', _ProtectedRsaKey,_}] = + public_key:pem_to_der(filename:join(Datadir, "rsa.pem")), + + {ok, #'DSAPrivateKey'{}} = public_key:decode_private_key(DsaKey), + {ok, #'RSAPrivateKey'{}} = public_key:decode_private_key(RsaKey), + {ok, #'RSAPrivateKey'{}} = public_key:decode_private_key(ProtectedRsaKey, "abcd1234"), + ok. + +%%-------------------------------------------------------------------- + +check_entry_type(#'DSAPrivateKey'{}, 'DSAPrivateKey') -> + true; +check_entry_type(#'RSAPrivateKey'{}, 'RSAPrivateKey') -> + true; +check_entry_type(#'DHParameter'{}, 'DHParameter') -> + true; +check_entry_type(#'Certificate'{}, 'Certificate') -> + true; +check_entry_type(_,_) -> + false. diff --git a/lib/public_key/vsn.mk b/lib/public_key/vsn.mk index 4b3071a85b..f70209d891 100644 --- a/lib/public_key/vsn.mk +++ b/lib/public_key/vsn.mk @@ -1,11 +1 @@ -PUBLIC_KEY_VSN = 0.7 - -TICKETS = OTP-8626 OTP-8649 - -#TICKETS_0.6 = OTP-7046 \ -# OTP-8553 -#TICKETS_0.5 = OTP-8372 -#TICKETS_0.4 = OTP-8250 -#TICKETS_0.3 = OTP-8100 OTP-8142 -#TICKETS_0.2 = OTP-7860 -#TICKETS_0.1 = OTP-7637
\ No newline at end of file +PUBLIC_KEY_VSN = 0.8 diff --git a/lib/reltool/vsn.mk b/lib/reltool/vsn.mk index f23a7e84a2..9e0bce1d01 100644 --- a/lib/reltool/vsn.mk +++ b/lib/reltool/vsn.mk @@ -1,28 +1 @@ -# This is an -*-makefile-*- file. -# %CopyrightBegin% -# -# Copyright Ericsson AB 2009-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% - RELTOOL_VSN = 0.5.4 - -TICKETS = OTP-8521 OTP-8590 -TICKETS_0_5_3 = OTP-8057 -TICKETS_0_5_2 = OTP-8254 -TICKETS_0_5_1 = OTP-8199 -TICKETS_0_5 = OTP-7949 -TICKETS_0_2_2 = OTP-7999 -TICKETS_2_2_1 = OTP-7840 -TICKETS_0_2 = OTP-7805 diff --git a/lib/snmp/doc/src/notes.xml b/lib/snmp/doc/src/notes.xml index 3f4954cfbd..d5d6605b64 100644 --- a/lib/snmp/doc/src/notes.xml +++ b/lib/snmp/doc/src/notes.xml @@ -13,12 +13,12 @@ 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>SNMP Release Notes</title> @@ -33,6 +33,34 @@ </header> <section> + <title>SNMP Development Toolkit 4.17.1</title> + <p>Version 4.17.1 supports code replacement in runtime from/to + version 4.17, 4.16.2, 4.16.1, 4.16, 4.15, 4.14 and 4.13.5.</p> + + <section> + <title>Improvements and new features</title> + <p>-</p> + </section> + + <section> + <title>Reported Fixed Bugs and Malfunctions</title> + <list type="bulleted"> + <item> + <p>When the function FilterMod:accept_recv/2 + returned false the SNMP agent stopped collecting messages from UDP.</p> + <p>Own Id: OTP-8761</p> + </item> + </list> + </section> + + <section> + <title>Incompatibilities</title> + <p>-</p> + </section> + </section> <!-- 4.17.1 --> + + + <section> <title>SNMP Development Toolkit 4.17</title> <p>Version 4.17 supports code replacement in runtime from/to version 4.16.2, 4.16.1, 4.16, 4.15, 4.14 and 4.13.5.</p> diff --git a/lib/snmp/src/agent/snmpa_net_if.erl b/lib/snmp/src/agent/snmpa_net_if.erl index 3a91cf4033..97a7a63dee 100644 --- a/lib/snmp/src/agent/snmpa_net_if.erl +++ b/lib/snmp/src/agent/snmpa_net_if.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% +%% %% Copyright Ericsson AB 2004-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(snmpa_net_if). @@ -478,12 +478,13 @@ update_req_counter_outgoing(#state{limit = Limit, rcnt = RCnt} = S, S#state{rcnt = NewRCnt}. -maybe_handle_recv(#state{filter = FilterMod} = S, +maybe_handle_recv(#state{usock = Sock, filter = FilterMod} = S, Ip, Port, Packet) -> case (catch FilterMod:accept_recv(Ip, Port)) of false -> %% Drop the received packet inc(netIfMsgInDrops), + active_once(Sock), S; _ -> handle_recv(S, Ip, Port, Packet) diff --git a/lib/snmp/src/app/snmp.appup.src b/lib/snmp/src/app/snmp.appup.src index 9ad16ffad2..2bd26e11db 100644 --- a/lib/snmp/src/app/snmp.appup.src +++ b/lib/snmp/src/app/snmp.appup.src @@ -1,19 +1,19 @@ %% %% %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% %% @@ -22,6 +22,11 @@ %% ----- U p g r a d e ------------------------------------------------------- [ + {"4.17", + [ + {load_module, snmpa_net_if, soft_purge, soft_purge, []} + ] + }, {"4.16.2", [ {load_module, snmp_log, soft_purge, soft_purge, []}, @@ -29,6 +34,7 @@ {load_module, snmpa_mpd, soft_purge, soft_purge, [snmpa_usm]}, {load_module, snmpa_usm, soft_purge, soft_purge, []}, {update, snmpa_agent, soft, soft_purge, soft_purge, []}, + {load_module, snmpa_net_if, soft_purge, soft_purge, []}, {load_module, snmpm_mpd, soft_purge, soft_purge, []} ] @@ -44,6 +50,7 @@ {load_module, snmpa_usm, soft_purge, soft_purge, [snmp_usm]}, {update, snmpa_mib, soft, soft_purge, soft_purge, []}, {update, snmpa_agent, soft, soft_purge, soft_purge, [snmpa_mib]}, + {load_module, snmpa_net_if, soft_purge, soft_purge, []}, {load_module, snmpm_mpd, soft_purge, soft_purge, []}, {update, snmpm_server, soft, soft_purge, soft_purge, []} @@ -61,6 +68,7 @@ {load_module, snmpa_usm, soft_purge, soft_purge, [snmp_usm]}, {update, snmpa_mib, soft, soft_purge, soft_purge, []}, {update, snmpa_agent, soft, soft_purge, soft_purge, [snmpa_mib]}, + {load_module, snmpa_net_if, soft_purge, soft_purge, []}, {load_module, snmpm_mpd, soft_purge, soft_purge, []}, {update, snmpm_net_if, soft, soft_purge, soft_purge, []}, @@ -149,6 +157,11 @@ %% ------D o w n g r a d e --------------------------------------------------- [ + {"4.17", + [ + {load_module, snmpa_net_if, soft_purge, soft_purge, []} + ] + }, {"4.16.2", [ {load_module, snmp_log, soft_purge, soft_purge, []}, @@ -157,6 +170,7 @@ {load_module, snmpa_mpd, soft_purge, soft_purge, [snmpa_usm]}, {load_module, snmpa_usm, soft_purge, soft_purge, []}, {update, snmpa_agent, soft, soft_purge, soft_purge, []}, + {load_module, snmpa_net_if, soft_purge, soft_purge, []}, {load_module, snmpm_mpd, soft_purge, soft_purge, []} ] @@ -172,6 +186,7 @@ {load_module, snmpa_usm, soft_purge, soft_purge, [snmp_usm]}, {update, snmpa_mib, soft, soft_purge, soft_purge, []}, {update, snmpa_agent, soft, soft_purge, soft_purge, [snmpa_mib]}, + {load_module, snmpa_net_if, soft_purge, soft_purge, []}, {load_module, snmpm_mpd, soft_purge, soft_purge, []}, {update, snmpm_server, soft, soft_purge, soft_purge, []} @@ -189,6 +204,7 @@ {load_module, snmpa_usm, soft_purge, soft_purge, [snmp_usm]}, {update, snmpa_mib, soft, soft_purge, soft_purge, []}, {update, snmpa_agent, soft, soft_purge, soft_purge, [snmpa_mib]}, + {load_module, snmpa_net_if, soft_purge, soft_purge, []}, {load_module, snmpm_mpd, soft_purge, soft_purge, []}, {update, snmpm_net_if, soft, soft_purge, soft_purge, []}, diff --git a/lib/snmp/vsn.mk b/lib/snmp/vsn.mk index 4ca1fb7901..95103433a4 100644 --- a/lib/snmp/vsn.mk +++ b/lib/snmp/vsn.mk @@ -1,57 +1,3 @@ -#-*-makefile-*- ; force emacs to enter makefile-mode - -# %CopyrightBegin% -# -# Copyright Ericsson AB 1997-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% - -SNMP_VSN = 4.17 +SNMP_VSN = 4.17.1 PRE_VSN = APP_VSN = "snmp-$(SNMP_VSN)$(PRE_VSN)" - -TICKETS = OTP-8478 - -TICKETS_4_16_2 = \ - OTP-8563 \ - OTP-8574 \ - OTP-8594 \ - OTP-8595 \ - OTP-8646 \ - OTP-8648 - -TICKETS_4_16_1 = \ - OTP-8480 \ - OTP-8481 - -TICKETS_4_16 = \ - OTP-8395 \ - OTP-8433 \ - OTP-8442 - -TICKETS_4_15 = \ - OTP-8229 \ - OTP-8249 - -TICKETS_4_14 = \ - OTP-8223 \ - OTP-8228 \ - OTP-8237 - -TICKETS_4_13_5 = \ - OTP-8116 \ - OTP-8120 \ - OTP-8181 \ - OTP-8182 - diff --git a/lib/ssh/src/ssh_channel.erl b/lib/ssh/src/ssh_channel.erl index 8a49a44a6c..dcb2d69290 100644 --- a/lib/ssh/src/ssh_channel.erl +++ b/lib/ssh/src/ssh_channel.erl @@ -238,9 +238,19 @@ handle_info(Msg, #state{cm = ConnectionManager, channel_cb = Module, {noreply, State#state{channel_state = ChannelState}}; {ok, ChannelState, Timeout} -> {noreply, State#state{channel_state = ChannelState}, Timeout}; + {stop, Reason, ChannelState} when is_atom(Reason)-> + {stop, Reason, State#state{close_sent = true, + channel_state = ChannelState}}; {stop, ChannelId, ChannelState} -> - ssh_connection:close(ConnectionManager, ChannelId), - {stop, normal, State#state{close_sent = true, + Reason = + case Msg of + {'EXIT', _Pid, shutdown} -> + shutdown; + _ -> + normal + end, + (catch ssh_connection:close(ConnectionManager, ChannelId)), + {stop, Reason, State#state{close_sent = true, channel_state = ChannelState}} end. diff --git a/lib/ssh/src/ssh_cli.erl b/lib/ssh/src/ssh_cli.erl index e3b6ffa125..cb78acb84c 100644 --- a/lib/ssh/src/ssh_cli.erl +++ b/lib/ssh/src/ssh_cli.erl @@ -415,14 +415,12 @@ start_shell(ConnectionManager, State) -> Shell = State#state.shell, ShellFun = case is_function(Shell) of true -> + {ok, User} = + ssh_userreg:lookup_user(ConnectionManager), case erlang:fun_info(Shell, arity) of {arity, 1} -> - {ok, User} = - ssh_userreg:lookup_user(ConnectionManager), fun() -> Shell(User) end; {arity, 2} -> - {ok, User} = - ssh_userreg:lookup_user(ConnectionManager), {ok, PeerAddr} = ssh_connection_manager:peer_addr(ConnectionManager), fun() -> Shell(User, PeerAddr) end; @@ -437,10 +435,28 @@ start_shell(ConnectionManager, State) -> State#state{group = Group, buf = empty_buf()}. start_shell(_ConnectionManager, Cmd, #state{exec={M, F, A}} = State) -> - Group = group:start(self(), {M, F, A++[Cmd]}, [{echo,false}]), + Group = group:start(self(), {M, F, A++[Cmd]}, [{echo, false}]), + State#state{group = Group, buf = empty_buf()}; +start_shell(ConnectionManager, Cmd, #state{exec=Shell} = State) when is_function(Shell) -> + {ok, User} = + ssh_userreg:lookup_user(ConnectionManager), + ShellFun = + case erlang:fun_info(Shell, arity) of + {arity, 1} -> + fun() -> Shell(Cmd) end; + {arity, 2} -> + fun() -> Shell(Cmd, User) end; + {arity, 3} -> + {ok, PeerAddr} = + ssh_connection_manager:peer_addr(ConnectionManager), + fun() -> Shell(Cmd, User, PeerAddr) end; + _ -> + Shell + end, + Echo = get_echo(State#state.pty), + Group = group:start(self(), ShellFun, [{echo,Echo}]), State#state{group = Group, buf = empty_buf()}. - % Pty can be undefined if the client never sets any pty options before % starting the shell. get_echo(undefined) -> diff --git a/lib/ssh/src/ssh_connection_controler.erl b/lib/ssh/src/ssh_connection_controler.erl index 636ecba532..ca3e62dc83 100644 --- a/lib/ssh/src/ssh_connection_controler.erl +++ b/lib/ssh/src/ssh_connection_controler.erl @@ -126,8 +126,8 @@ handle_cast(_, State) -> %% handle_info(ssh_connected, State) -> %% {stop, normal, State}; %% Servant termination. -handle_info({'EXIT', _Pid, normal}, State) -> - {stop, normal, State}. +handle_info({'EXIT', _Pid, Reason}, State) -> + {stop, Reason, State}. %%----------------------------------------------------------------- %% Func: code_change/3 diff --git a/lib/ssh/src/ssh_connection_manager.erl b/lib/ssh/src/ssh_connection_manager.erl index cffeade485..6bf89224cf 100644 --- a/lib/ssh/src/ssh_connection_manager.erl +++ b/lib/ssh/src/ssh_connection_manager.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% +%% %% Copyright Ericsson AB 2008-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% %% %% @@ -146,6 +146,8 @@ adjust_window(ConnectionManager, Channel, Bytes) -> close(ConnectionManager, ChannelId) -> try call(ConnectionManager, {close, ChannelId}) of ok -> + ok; + {error,normal} -> ok catch exit:{noproc, _} -> @@ -155,6 +157,8 @@ close(ConnectionManager, ChannelId) -> stop(ConnectionManager) -> try call(ConnectionManager, stop) of ok -> + ok; + {error,normal} -> ok catch exit:{noproc, _} -> @@ -556,13 +560,18 @@ handle_info({'EXIT', _, _}, State) -> %% The return value is ignored. %%-------------------------------------------------------------------- terminate(Reason, #state{connection_state = - #connection{requests = Requests}, + #connection{requests = Requests, + sub_system_supervisor = SubSysSup}, opts = Opts}) -> SSHOpts = proplists:get_value(ssh_opts, Opts), disconnect_fun(Reason, SSHOpts), (catch lists:foreach(fun({_, From}) -> gen_server:reply(From, {error, connection_closed}) end, Requests)), + Address = proplists:get_value(address, Opts), + Port = proplists:get_value(port, Opts), + SystemSup = ssh_system_sup:system_supervisor(Address, Port), + ssh_system_sup:stop_subsystem(SystemSup, SubSysSup), ok. %%-------------------------------------------------------------------- @@ -593,7 +602,9 @@ call(Pid, Msg, Timeout) -> Result catch exit:{timeout, _} -> - {error, timeout} + {error, timeout}; + exit:{normal, _} -> + {error, normal} end. cast(Pid, Msg) -> diff --git a/lib/ssh/src/ssh_system_sup.erl b/lib/ssh/src/ssh_system_sup.erl index 40db2e4adf..f4570b8a48 100644 --- a/lib/ssh/src/ssh_system_sup.erl +++ b/lib/ssh/src/ssh_system_sup.erl @@ -33,7 +33,8 @@ stop_system/2, system_supervisor/2, subsystem_supervisor/1, channel_supervisor/1, connection_supervisor/1, - acceptor_supervisor/1, start_subsystem/2, restart_subsystem/2, restart_acceptor/2]). + acceptor_supervisor/1, start_subsystem/2, restart_subsystem/2, + restart_acceptor/2, stop_subsystem/2]). %% Supervisor callback -export([init/1]). @@ -83,6 +84,23 @@ start_subsystem(SystemSup, Options) -> Spec = ssh_subsystem_child_spec(Options), supervisor:start_child(SystemSup, Spec). +stop_subsystem(SystemSup, SubSys) -> + case lists:keyfind(SubSys, 2, supervisor:which_children(SystemSup)) of + false -> + {error, not_found}; + {Id, _, _, _} -> + spawn(fun() -> supervisor:terminate_child(SystemSup, Id), + supervisor:delete_child(SystemSup, Id) end), + ok; + {'EXIT', {noproc, _}} -> + %% Already terminated; probably shutting down. + ok; + {'EXIT', {shutdown, _}} -> + %% Already shutting down. + ok + end. + + restart_subsystem(Address, Port) -> SysSupName = make_name(Address, Port), SubSysName = id(ssh_subsystem_sup, Address, Port), diff --git a/lib/ssh/vsn.mk b/lib/ssh/vsn.mk index ccdbfe4f9a..a8821625a2 100644 --- a/lib/ssh/vsn.mk +++ b/lib/ssh/vsn.mk @@ -2,83 +2,3 @@ SSH_VSN = 2.0 APP_VSN = "ssh-$(SSH_VSN)" - -TICKETS = OTP-8524 \ - OTP-8534 \ - OTP-8535 \ - OTP-8550 \ - OTP-8596 \ - OTP-8644 \ - OTP-8645 - -TICKETS_1.1.8 = OTP-8356 \ - OTP-8401 - -TICKETS_1.1.7 = OTP-8121 \ - OTP-8277 \ - OTP-8278 \ - OTP-8201 - -TICKETS_1.1.6 = OTP-8110 \ - OTP-8162 \ - OTP-8173 \ - OTP-8174 \ - OTP-8175 \ - OTP-8176 - -TICKETS_1.1.5 = OTP-8159 \ - OTP-8160 \ - OTP-8161 - -TICKETS_1.1.4 = OTP-8071 - -TICKETS_1.1.3 = OTP-7996 \ - OTP-8034 \ - OTP-8035 - -TICKETS_1.1.2 = OTP-7914 \ - OTP-7917 \ - OTP-7918 \ - OTP-7921 \ - OTP-7919 \ - OTP-7930 \ - OTP-7957 - -TICKETS_1.1.1 = OTP-7828 \ - OTP-7795 \ - OTP-7807 \ - OTP-7808 \ - OTP-7809 - -TICKETS_1.1 = OTP-7676 \ - OTP-7683 \ - OTP-7685 \ - OTP-7766 \ - OTP-7767 \ - OTP-7768 \ - OTP-7770 \ - OTP-7456 \ - OTP-7769 \ - OTP-7516 \ - OTP-7645 \ - -TICKETS_1.0.2 = \ - OTP-7141\ - -TICKETS_1.0.1 = \ - OTP-7318 \ - OTP-7305 \ - OTP-7564 \ - OTP-7565 \ - OTP-7566 \ - -TICKETS_1.0 = \ - OTP-7485 \ - OTP-7504 \ - OTP-7356 \ - OTP-7502 \ - OTP-7503 - -TICKETS_0.9.9.6 = \ - OTP-7246 \ - OTP-7247 \
\ No newline at end of file diff --git a/lib/ssl/Makefile b/lib/ssl/Makefile index b8b51270c9..daad7dc3e6 100644 --- a/lib/ssl/Makefile +++ b/lib/ssl/Makefile @@ -24,22 +24,8 @@ include $(ERL_TOP)/make/$(TARGET)/otp.mk # # Macros # -ifeq ($(findstring win32,$(TARGET)),win32) -ifeq ($(HOST_OS),) -HOST_OS := $(shell $(ERL_TOP)/erts/autoconf/config.guess) -endif -ifeq ($(findstring solaris,$(HOST_OS)),solaris) -SKIP_BUILDING_BINARIES := true -endif -else -SKIP_BUILDING_BINARIES := false -endif - -ifeq ($(SKIP_BUILDING_BINARIES), true) -SUB_DIRECTORIES = src c_src doc/src -else + SUB_DIRECTORIES = src c_src doc/src examples/certs examples/src -endif include vsn.mk VSN = $(SSL_VSN) diff --git a/lib/ssl/examples/certs/Makefile b/lib/ssl/examples/certs/Makefile index 121fcc6950..b811b461dc 100644 --- a/lib/ssl/examples/certs/Makefile +++ b/lib/ssl/examples/certs/Makefile @@ -1,7 +1,7 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 2003-2009. All Rights Reserved. +# Copyright Ericsson AB 2003-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 @@ -21,4 +21,41 @@ # Invoke with GNU make or clearmake -C gnu. # -include $(ERL_TOP)/make/run_make.mk +include $(ERL_TOP)/make/target.mk +include $(ERL_TOP)/make/$(TARGET)/otp.mk + +# ---------------------------------------------------- +# Application version +# ---------------------------------------------------- +include ../../vsn.mk +VSN=$(SSL_VSN) + +# ---------------------------------------------------- +# Release directory specification +# ---------------------------------------------------- +RELSYSDIR = $(RELEASE_PATH)/lib/ssl-$(VSN) + +TARGET_FILES= + +# ---------------------------------------------------- +# Targets +# ---------------------------------------------------- + +debug opt: $(TARGET_FILES) + +clean: + rm -fr $(TARGET_FILES) *~ *.beam + +docs: + +# ---------------------------------------------------- +# Release Target +# ---------------------------------------------------- +include $(ERL_TOP)/make/otp_release_targets.mk + +release_spec: opt + $(INSTALL_DIR) $(RELSYSDIR)/examples/certs + tar cf - etc | \ + (cd $(RELSYSDIR)/examples/certs; tar xf -) + chmod -f -R ug+rw $(RELSYSDIR)/examples +release_docs_spec: diff --git a/lib/ssl/examples/certs/Makefile.in b/lib/ssl/examples/certs/Makefile.in deleted file mode 100644 index 4ea7aaf6dc..0000000000 --- a/lib/ssl/examples/certs/Makefile.in +++ /dev/null @@ -1,80 +0,0 @@ -# -# %CopyrightBegin% -# -# Copyright Ericsson AB 2003-2009. 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% -# - -# - -include $(ERL_TOP)/make/target.mk -include $(ERL_TOP)/make/$(TARGET)/otp.mk - -include ../../vsn.mk -VSN=$(SSL_VSN) - -RELSYSDIR = $(RELEASE_PATH)/lib/ssl-$(VSN) - -EBIN = ebin -ETC = etc -SRC = src - -OPENSSL_CMD = @OPENSSL_CMD@ - -# We are generating more files than in the following list, but we take -# there existence as successful execution of make rules - -PEMS = cacerts.pem cert.pem key.pem - -PEMFILES = $(PEMS:%=$(ETC)/client/%) $(PEMS:%=$(ETC)/server/%) - -debug opt: $(PEMFILES) - -$(PEMFILES): done - -done: $(EBIN)/make_certs.beam - erl -noinput -pa $(EBIN) -run make_certs all $(OPENSSL_CMD) \ - -s erlang halt - echo >done - -$(EBIN)/make_certs.beam: $(SRC)/make_certs.erl - cd src; erlc -W -o ../$(EBIN) make_certs.erl - -clean: - rm -fr $(EBIN)/* $(SRC)/*~ $(SRC)/*.beam $(ETC) done \ - stderr.txt erl_crash.dump *~ - -docs: - -# ---------------------------------------------------- -# Release Target -# ---------------------------------------------------- -include $(ERL_TOP)/make/otp_release_targets.mk - -release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/examples/certs - tar cf - Makefile ebin etc rnd src | \ - (cd $(RELSYSDIR)/examples/certs; tar xf -) - chmod -f -R ug+rw $(RELSYSDIR)/examples - -release_docs_spec: - - - - - - - - diff --git a/lib/ssl/examples/certs/ebin/.gitignore b/lib/ssl/examples/certs/ebin/.gitignore deleted file mode 100644 index e69de29bb2..0000000000 --- a/lib/ssl/examples/certs/ebin/.gitignore +++ /dev/null diff --git a/lib/ssl/examples/certs/etc/client/cacerts.pem b/lib/ssl/examples/certs/etc/client/cacerts.pem new file mode 100644 index 0000000000..cb19d3d41e --- /dev/null +++ b/lib/ssl/examples/certs/etc/client/cacerts.pem @@ -0,0 +1,34 @@ +-----BEGIN CERTIFICATE----- +MIICizCCAfSgAwIBAgIFdMMs9fEwDQYJKoZIhvcNAQEFBQAwfTERMA8GA1UEAxMI +ZXJsYW5nQ0ExIDAeBgkqhkiG9w0BCQEWEXRlc3RlckBlcmxhbmcub3JnMRIwEAYD +VQQHEwlTdG9ja2hvbG0xCzAJBgNVBAYTAlNFMQ8wDQYDVQQKEwZlcmxhbmcxFDAS +BgNVBAsTC3Rlc3RpbmcgZGVwMCIYDzIwMTAwOTAxMDAwMDAwWhgPMjAyNTA4Mjgw +MDAwMDBaMH0xETAPBgNVBAMTCGVybGFuZ0NBMSAwHgYJKoZIhvcNAQkBFhF0ZXN0 +ZXJAZXJsYW5nLm9yZzESMBAGA1UEBxMJU3RvY2tob2xtMQswCQYDVQQGEwJTRTEP +MA0GA1UEChMGZXJsYW5nMRQwEgYDVQQLEwt0ZXN0aW5nIGRlcDCBnzANBgkqhkiG +9w0BAQEFAAOBjQAwgYkCgYEAgmHw2xApZqdzZOOPTzwHr1hRYd1OqbLOsXbAq6kJ +Kuu+qe5jAlMF3vnUhiHomuZeNZVJe3SP+JfBt3BHMjm2CLChCuNgfctKURMlEc/L +xo8fO1Jk9MD5mbG2Utx3m3gM6Liwt9fHVABlCTyB6/jXrK1tYpEG5CrwUXyy8Htl +jHECAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQAl +0tMEXWPgzXTpDuNmuKh6aGq9CuExUuEXXQQWPThzEuluA3aHFmObziQlMY1+KeO1 +AL0kpx0Yhvju/rfAJ+OF6MMni6hJoKlYTVml+fCY89A3nmY1rJHJavjHp0OIPGxh +4Sr+EcjROkqe8jE0DmbwmM6lzpwSJscxte+V6HvGRw== +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIICiDCCAfGgAwIBAgIFSHyFNTEwDQYJKoZIhvcNAQEFBQAwfTERMA8GA1UEAxMI +ZXJsYW5nQ0ExIDAeBgkqhkiG9w0BCQEWEXRlc3RlckBlcmxhbmcub3JnMRIwEAYD +VQQHEwlTdG9ja2hvbG0xCzAJBgNVBAYTAlNFMQ8wDQYDVQQKEwZlcmxhbmcxFDAS +BgNVBAsTC3Rlc3RpbmcgZGVwMCIYDzIwMTAwOTAxMDAwMDAwWhgPMjAyNTA4Mjgw +MDAwMDBaMHoxDjAMBgNVBAMTBW90cENBMSAwHgYJKoZIhvcNAQkBFhF0ZXN0ZXJA +ZXJsYW5nLm9yZzESMBAGA1UEBxMJU3RvY2tob2xtMQswCQYDVQQGEwJTRTEPMA0G +A1UEChMGZXJsYW5nMRQwEgYDVQQLEwt0ZXN0aW5nIGRlcDCBnzANBgkqhkiG9w0B +AQEFAAOBjQAwgYkCgYEAjEt9iy365+mTialKDKb3l2QPg71yavJA1ZC6aGC14X7x +KCm1FhUYsVKOlWjmC1VYJiCS01gvKqMXiogreHJGM93E+URlKkOm9kmOWQwLfFb8 +JLzafPi3/8TUdjl8UuIDHyPsoQiM2ZBDUVWezfl+CBsTYFO3U4Lqf9OKbCxTF78C +AwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQAv6vHw +wK3MvxzlhDJIx7rUasOYJDZJyOt71KdOKeA7+ocbvDIblmV7sTbe3oQNqbSATZ6H +RUqHZdPhKIZ9wjEBSKdBTL8rc0TvbztMvd+i0rkTCL/bspQYchA2zCcjgkWqpaN4 +OhOjQR1+9/ntmaU/r5Ca7KmrXEf5XSQIGLSMag== +-----END CERTIFICATE----- + diff --git a/lib/ssl/examples/certs/etc/client/cert.pem b/lib/ssl/examples/certs/etc/client/cert.pem new file mode 100644 index 0000000000..a2f53aaf82 --- /dev/null +++ b/lib/ssl/examples/certs/etc/client/cert.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +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/ssl/examples/certs/etc/client/key.pem b/lib/ssl/examples/certs/etc/client/key.pem new file mode 100644 index 0000000000..4d55b08f4c --- /dev/null +++ b/lib/ssl/examples/certs/etc/client/key.pem @@ -0,0 +1,16 @@ +-----BEGIN RSA PRIVATE KEY----- +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----- + diff --git a/lib/ssl/examples/certs/etc/erlangCA/cert.pem b/lib/ssl/examples/certs/etc/erlangCA/cert.pem new file mode 100644 index 0000000000..c4386494dc --- /dev/null +++ b/lib/ssl/examples/certs/etc/erlangCA/cert.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICizCCAfSgAwIBAgIFdMMs9fEwDQYJKoZIhvcNAQEFBQAwfTERMA8GA1UEAxMI +ZXJsYW5nQ0ExIDAeBgkqhkiG9w0BCQEWEXRlc3RlckBlcmxhbmcub3JnMRIwEAYD +VQQHEwlTdG9ja2hvbG0xCzAJBgNVBAYTAlNFMQ8wDQYDVQQKEwZlcmxhbmcxFDAS +BgNVBAsTC3Rlc3RpbmcgZGVwMCIYDzIwMTAwOTAxMDAwMDAwWhgPMjAyNTA4Mjgw +MDAwMDBaMH0xETAPBgNVBAMTCGVybGFuZ0NBMSAwHgYJKoZIhvcNAQkBFhF0ZXN0 +ZXJAZXJsYW5nLm9yZzESMBAGA1UEBxMJU3RvY2tob2xtMQswCQYDVQQGEwJTRTEP +MA0GA1UEChMGZXJsYW5nMRQwEgYDVQQLEwt0ZXN0aW5nIGRlcDCBnzANBgkqhkiG +9w0BAQEFAAOBjQAwgYkCgYEAgmHw2xApZqdzZOOPTzwHr1hRYd1OqbLOsXbAq6kJ +Kuu+qe5jAlMF3vnUhiHomuZeNZVJe3SP+JfBt3BHMjm2CLChCuNgfctKURMlEc/L +xo8fO1Jk9MD5mbG2Utx3m3gM6Liwt9fHVABlCTyB6/jXrK1tYpEG5CrwUXyy8Htl +jHECAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQAl +0tMEXWPgzXTpDuNmuKh6aGq9CuExUuEXXQQWPThzEuluA3aHFmObziQlMY1+KeO1 +AL0kpx0Yhvju/rfAJ+OF6MMni6hJoKlYTVml+fCY89A3nmY1rJHJavjHp0OIPGxh +4Sr+EcjROkqe8jE0DmbwmM6lzpwSJscxte+V6HvGRw== +-----END CERTIFICATE----- + diff --git a/lib/ssl/examples/certs/etc/otpCA/cert.pem b/lib/ssl/examples/certs/etc/otpCA/cert.pem new file mode 100644 index 0000000000..8610621695 --- /dev/null +++ b/lib/ssl/examples/certs/etc/otpCA/cert.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICiDCCAfGgAwIBAgIFSHyFNTEwDQYJKoZIhvcNAQEFBQAwfTERMA8GA1UEAxMI +ZXJsYW5nQ0ExIDAeBgkqhkiG9w0BCQEWEXRlc3RlckBlcmxhbmcub3JnMRIwEAYD +VQQHEwlTdG9ja2hvbG0xCzAJBgNVBAYTAlNFMQ8wDQYDVQQKEwZlcmxhbmcxFDAS +BgNVBAsTC3Rlc3RpbmcgZGVwMCIYDzIwMTAwOTAxMDAwMDAwWhgPMjAyNTA4Mjgw +MDAwMDBaMHoxDjAMBgNVBAMTBW90cENBMSAwHgYJKoZIhvcNAQkBFhF0ZXN0ZXJA +ZXJsYW5nLm9yZzESMBAGA1UEBxMJU3RvY2tob2xtMQswCQYDVQQGEwJTRTEPMA0G +A1UEChMGZXJsYW5nMRQwEgYDVQQLEwt0ZXN0aW5nIGRlcDCBnzANBgkqhkiG9w0B +AQEFAAOBjQAwgYkCgYEAjEt9iy365+mTialKDKb3l2QPg71yavJA1ZC6aGC14X7x +KCm1FhUYsVKOlWjmC1VYJiCS01gvKqMXiogreHJGM93E+URlKkOm9kmOWQwLfFb8 +JLzafPi3/8TUdjl8UuIDHyPsoQiM2ZBDUVWezfl+CBsTYFO3U4Lqf9OKbCxTF78C +AwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQAv6vHw +wK3MvxzlhDJIx7rUasOYJDZJyOt71KdOKeA7+ocbvDIblmV7sTbe3oQNqbSATZ6H +RUqHZdPhKIZ9wjEBSKdBTL8rc0TvbztMvd+i0rkTCL/bspQYchA2zCcjgkWqpaN4 +OhOjQR1+9/ntmaU/r5Ca7KmrXEf5XSQIGLSMag== +-----END CERTIFICATE----- + diff --git a/lib/ssl/examples/certs/etc/server/cacerts.pem b/lib/ssl/examples/certs/etc/server/cacerts.pem new file mode 100644 index 0000000000..cb19d3d41e --- /dev/null +++ b/lib/ssl/examples/certs/etc/server/cacerts.pem @@ -0,0 +1,34 @@ +-----BEGIN CERTIFICATE----- +MIICizCCAfSgAwIBAgIFdMMs9fEwDQYJKoZIhvcNAQEFBQAwfTERMA8GA1UEAxMI +ZXJsYW5nQ0ExIDAeBgkqhkiG9w0BCQEWEXRlc3RlckBlcmxhbmcub3JnMRIwEAYD +VQQHEwlTdG9ja2hvbG0xCzAJBgNVBAYTAlNFMQ8wDQYDVQQKEwZlcmxhbmcxFDAS +BgNVBAsTC3Rlc3RpbmcgZGVwMCIYDzIwMTAwOTAxMDAwMDAwWhgPMjAyNTA4Mjgw +MDAwMDBaMH0xETAPBgNVBAMTCGVybGFuZ0NBMSAwHgYJKoZIhvcNAQkBFhF0ZXN0 +ZXJAZXJsYW5nLm9yZzESMBAGA1UEBxMJU3RvY2tob2xtMQswCQYDVQQGEwJTRTEP +MA0GA1UEChMGZXJsYW5nMRQwEgYDVQQLEwt0ZXN0aW5nIGRlcDCBnzANBgkqhkiG +9w0BAQEFAAOBjQAwgYkCgYEAgmHw2xApZqdzZOOPTzwHr1hRYd1OqbLOsXbAq6kJ +Kuu+qe5jAlMF3vnUhiHomuZeNZVJe3SP+JfBt3BHMjm2CLChCuNgfctKURMlEc/L +xo8fO1Jk9MD5mbG2Utx3m3gM6Liwt9fHVABlCTyB6/jXrK1tYpEG5CrwUXyy8Htl +jHECAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQAl +0tMEXWPgzXTpDuNmuKh6aGq9CuExUuEXXQQWPThzEuluA3aHFmObziQlMY1+KeO1 +AL0kpx0Yhvju/rfAJ+OF6MMni6hJoKlYTVml+fCY89A3nmY1rJHJavjHp0OIPGxh +4Sr+EcjROkqe8jE0DmbwmM6lzpwSJscxte+V6HvGRw== +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIICiDCCAfGgAwIBAgIFSHyFNTEwDQYJKoZIhvcNAQEFBQAwfTERMA8GA1UEAxMI +ZXJsYW5nQ0ExIDAeBgkqhkiG9w0BCQEWEXRlc3RlckBlcmxhbmcub3JnMRIwEAYD +VQQHEwlTdG9ja2hvbG0xCzAJBgNVBAYTAlNFMQ8wDQYDVQQKEwZlcmxhbmcxFDAS +BgNVBAsTC3Rlc3RpbmcgZGVwMCIYDzIwMTAwOTAxMDAwMDAwWhgPMjAyNTA4Mjgw +MDAwMDBaMHoxDjAMBgNVBAMTBW90cENBMSAwHgYJKoZIhvcNAQkBFhF0ZXN0ZXJA +ZXJsYW5nLm9yZzESMBAGA1UEBxMJU3RvY2tob2xtMQswCQYDVQQGEwJTRTEPMA0G +A1UEChMGZXJsYW5nMRQwEgYDVQQLEwt0ZXN0aW5nIGRlcDCBnzANBgkqhkiG9w0B +AQEFAAOBjQAwgYkCgYEAjEt9iy365+mTialKDKb3l2QPg71yavJA1ZC6aGC14X7x +KCm1FhUYsVKOlWjmC1VYJiCS01gvKqMXiogreHJGM93E+URlKkOm9kmOWQwLfFb8 +JLzafPi3/8TUdjl8UuIDHyPsoQiM2ZBDUVWezfl+CBsTYFO3U4Lqf9OKbCxTF78C +AwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQAv6vHw +wK3MvxzlhDJIx7rUasOYJDZJyOt71KdOKeA7+ocbvDIblmV7sTbe3oQNqbSATZ6H +RUqHZdPhKIZ9wjEBSKdBTL8rc0TvbztMvd+i0rkTCL/bspQYchA2zCcjgkWqpaN4 +OhOjQR1+9/ntmaU/r5Ca7KmrXEf5XSQIGLSMag== +-----END CERTIFICATE----- + diff --git a/lib/ssl/examples/certs/etc/server/cert.pem b/lib/ssl/examples/certs/etc/server/cert.pem new file mode 100644 index 0000000000..f26adb7f5c --- /dev/null +++ b/lib/ssl/examples/certs/etc/server/cert.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +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/ssl/examples/certs/etc/server/key.pem b/lib/ssl/examples/certs/etc/server/key.pem new file mode 100644 index 0000000000..c1392ca557 --- /dev/null +++ b/lib/ssl/examples/certs/etc/server/key.pem @@ -0,0 +1,16 @@ +-----BEGIN RSA PRIVATE KEY----- +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----- + diff --git a/lib/ssl/examples/certs/rnd/RAND b/lib/ssl/examples/certs/rnd/RAND Binary files differdeleted file mode 100644 index 70997bd01f..0000000000 --- a/lib/ssl/examples/certs/rnd/RAND +++ /dev/null diff --git a/lib/ssl/examples/certs/src/make_certs.erl b/lib/ssl/examples/certs/src/make_certs.erl index c374836568..fe267bed28 100644 --- a/lib/ssl/examples/certs/src/make_certs.erl +++ b/lib/ssl/examples/certs/src/make_certs.erl @@ -1,261 +1,48 @@ -%% The purpose of this module is to create example certificates for -%% testing. -%% Run it as: -%% -%% erl -noinput -run make_certs all "/path/to/openssl" -s erlang halt -%% +%% The purpose of this module is to log how the example certs where created, +%% it requires erl_make_certs found in the test directory. -module(make_certs). --export([all/0, all/1]). - --record(dn, {commonName, - organizationalUnitName = "Erlang OTP", - organizationName = "Ericsson AB", - localityName = "Stockholm", - countryName = "SE", - emailAddress = "[email protected]"}). +-export([all/0]). all() -> - all(["openssl"]). - -all([OpenSSLCmd]) -> - Root = filename:dirname(filename:dirname((code:which(?MODULE)))), - %% io:fwrite("Root : ~s~n", [Root]), - NRoot = filename:join([Root, "etc"]), - file:make_dir(NRoot), - create_rnd(Root, "etc"), % For all requests - rootCA(NRoot, OpenSSLCmd, "erlangCA"), - intermediateCA(NRoot, OpenSSLCmd, "otpCA", "erlangCA"), - endusers(NRoot, OpenSSLCmd, "otpCA", ["client", "server"]), - collect_certs(NRoot, ["erlangCA", "otpCA"], ["client", "server"]), - remove_rnd(Root, "etc"). - -rootCA(Root, OpenSSLCmd, Name) -> - create_ca_dir(Root, Name, ca_cnf(Name)), - DN = #dn{commonName = Name}, - create_self_signed_cert(Root, OpenSSLCmd, Name, req_cnf(DN)), - ok. - -intermediateCA(Root, OpenSSLCmd, CA, ParentCA) -> - CA = "otpCA", - create_ca_dir(Root, CA, ca_cnf(CA)), - CARoot = filename:join([Root, CA]), - DN = #dn{commonName = CA}, - CnfFile = filename:join([CARoot, "req.cnf"]), - file:write_file(CnfFile, req_cnf(DN)), - KeyFile = filename:join([CARoot, "private", "key.pem"]), - ReqFile = filename:join([CARoot, "req.pem"]), - create_req(Root, OpenSSLCmd, CnfFile, KeyFile, ReqFile), - CertFile = filename:join([CARoot, "cert.pem"]), - sign_req(Root, OpenSSLCmd, ParentCA, "ca_cert", ReqFile, CertFile). - -endusers(Root, OpenSSLCmd, CA, Users) -> - lists:foreach(fun(User) -> enduser(Root, OpenSSLCmd, CA, User) end, Users). - -enduser(Root, OpenSSLCmd, CA, User) -> - UsrRoot = filename:join([Root, User]), - file:make_dir(UsrRoot), - CnfFile = filename:join([UsrRoot, "req.cnf"]), - DN = #dn{commonName = User}, - file:write_file(CnfFile, req_cnf(DN)), - KeyFile = filename:join([UsrRoot, "key.pem"]), - ReqFile = filename:join([UsrRoot, "req.pem"]), - create_req(Root, OpenSSLCmd, CnfFile, KeyFile, ReqFile), - CertFile = filename:join([UsrRoot, "cert.pem"]), - sign_req(Root, OpenSSLCmd, CA, "user_cert", ReqFile, CertFile). - -collect_certs(Root, CAs, Users) -> - Bins = lists:foldr( - fun(CA, Acc) -> - File = filename:join([Root, CA, "cert.pem"]), - {ok, Bin} = file:read_file(File), - [Bin, "\n" | Acc] - end, [], CAs), - lists:foreach( - fun(User) -> - File = filename:join([Root, User, "cacerts.pem"]), - file:write_file(File, Bins) - end, Users). - -create_self_signed_cert(Root, OpenSSLCmd, CAName, Cnf) -> - CARoot = filename:join([Root, CAName]), - CnfFile = filename:join([CARoot, "req.cnf"]), - file:write_file(CnfFile, Cnf), - KeyFile = filename:join([CARoot, "private", "key.pem"]), - CertFile = filename:join([CARoot, "cert.pem"]), - Cmd = [OpenSSLCmd, " req" - " -new" - " -x509" - " -config ", CnfFile, - " -keyout ", KeyFile, - " -out ", CertFile], - Env = [{"ROOTDIR", Root}], - cmd(Cmd, Env). - -create_ca_dir(Root, CAName, Cnf) -> - CARoot = filename:join([Root, CAName]), - file:make_dir(CARoot), - create_dirs(CARoot, ["certs", "crl", "newcerts", "private"]), - create_rnd(Root, filename:join([CAName, "private"])), - create_files(CARoot, [{"serial", "01\n"}, - {"index.txt", ""}, - {"ca.cnf", Cnf}]). - -create_req(Root, OpenSSLCmd, CnfFile, KeyFile, ReqFile) -> - Cmd = [OpenSSLCmd, " req" - " -new" - " -config ", CnfFile, - " -keyout ", KeyFile, - " -out ", ReqFile], - Env = [{"ROOTDIR", Root}], - cmd(Cmd, Env). - -sign_req(Root, OpenSSLCmd, CA, CertType, ReqFile, CertFile) -> - CACnfFile = filename:join([Root, CA, "ca.cnf"]), - Cmd = [OpenSSLCmd, " ca" - " -batch" - " -notext" - " -config ", CACnfFile, - " -extensions ", CertType, - " -in ", ReqFile, - " -out ", CertFile], - Env = [{"ROOTDIR", Root}], - cmd(Cmd, Env). + LongTime = calendar:gregorian_days_to_date(calendar:date_to_gregorian_days(date())+15*365), + Validity = {date(), LongTime}, + Subject = [{email, "[email protected]"}, + {city, "Stockholm"}, + {country, "SE"}, + {org, "erlang"}, + {org_unit, "testing dep"}], + + RootCa = erl_make_certs:make_cert([{validity, Validity}, {subject, [{name, "erlangCA"}|Subject]}]), + ImedCa = erl_make_certs:make_cert([{issuer, RootCa}, {validity, Validity}, + {subject, [{name, "otpCA"}|Subject]}]), + ClientCa = erl_make_certs:make_cert([{issuer, ImedCa}, {validity, Validity}, + {subject, [{name, "client"}|Subject]}]), + ServerCa = erl_make_certs:make_cert([{issuer, ImedCa}, {validity, Validity}, + {subject, [{name, "server"}|Subject]}]), + + Root0 = filename:dirname(filename:dirname((code:which(?MODULE)))), + Root = filename:join([Root0, "etc"]), file:make_dir(Root), + CaPath = filename:join([Root, "erlangCA"]), file:make_dir(CaPath), + IPath = filename:join([Root, "otpCA"]), file:make_dir(IPath), + CPath = filename:join([Root, "client"]), file:make_dir(CPath), + SPath = filename:join([Root, "server"]), file:make_dir(SPath), + + erl_make_certs:write_pem(CaPath,"cert", RootCa), + erl_make_certs:write_pem(IPath, "cert", ImedCa), + + {ok, CaBin0} = file:read_file(filename:join(CaPath, "cert.pem")), + {ok, CaBin1} = file:read_file(filename:join(IPath, "cert.pem")), + CaBin = <<CaBin0/binary, CaBin1/binary>>, + + erl_make_certs:write_pem(CPath, "cert", ClientCa), + ok = file:write_file(filename:join(CPath, "cacerts.pem"), CaBin), + erl_make_certs:write_pem(SPath, "cert", ServerCa), + ok = file:write_file(filename:join(SPath, "cacerts.pem"), CaBin), -%% -%% Misc -%% - -create_dirs(Root, Dirs) -> - lists:foreach(fun(Dir) -> - file:make_dir(filename:join([Root, Dir])) end, - Dirs). - -create_files(Root, NameContents) -> - lists:foreach( - fun({Name, Contents}) -> - file:write_file(filename:join([Root, Name]), Contents) end, - NameContents). - -create_rnd(Root, Dir) -> - From = filename:join([Root, "rnd", "RAND"]), - To = filename:join([Root, Dir, "RAND"]), - file:copy(From, To). - -remove_rnd(Root, Dir) -> - File = filename:join([Root, Dir, "RAND"]), - file:delete(File). - -cmd(Cmd, Env) -> - FCmd = lists:flatten(Cmd), - Port = open_port({spawn, FCmd}, [stream, eof, exit_status, - {env, Env}]), - eval_cmd(Port). - -eval_cmd(Port) -> - receive - {Port, {data, _}} -> - eval_cmd(Port); - {Port, eof} -> - ok - end, - receive - {Port, {exit_status, Status}} when Status /= 0 -> - %% io:fwrite("exit status: ~w~n", [Status]), - erlang:halt(Status) - after 0 -> - ok - end. - -%% -%% Contents of configuration files -%% - -req_cnf(DN) -> - ["# Purpose: Configuration for requests (end users and CAs)." - "\n" - "ROOTDIR = $ENV::ROOTDIR\n" - "\n" - - "[req]\n" - "input_password = secret\n" - "output_password = secret\n" - "default_bits = 1024\n" - "RANDFILE = $ROOTDIR/RAND\n" - "encrypt_key = no\n" - "default_md = sha1\n" - "#string_mask = pkix\n" - "x509_extensions = ca_ext\n" - "prompt = no\n" - "distinguished_name= name\n" - "\n" - - "[name]\n" - "commonName = ", DN#dn.commonName, "\n" - "organizationalUnitName = ", DN#dn.organizationalUnitName, "\n" - "organizationName = ", DN#dn.organizationName, "\n" - "localityName = ", DN#dn.localityName, "\n" - "countryName = ", DN#dn.countryName, "\n" - "emailAddress = ", DN#dn.emailAddress, "\n" - "\n" - - "[ca_ext]\n" - "basicConstraints = critical, CA:true\n" - "keyUsage = cRLSign, keyCertSign\n" - "subjectKeyIdentifier = hash\n" - "subjectAltName = email:copy\n"]. - - -ca_cnf(CA) -> - ["# Purpose: Configuration for CAs.\n" - "\n" - "ROOTDIR = $ENV::ROOTDIR\n" - "default_ca = ca\n" - "\n" - - "[ca]\n" - "dir = $ROOTDIR/", CA, "\n" - "certs = $dir/certs\n" - "crl_dir = $dir/crl\n" - "database = $dir/index.txt\n" - "new_certs_dir = $dir/newcerts\n" - "certificate = $dir/cert.pem\n" - "serial = $dir/serial\n" - "crl = $dir/crl.pem\n" - "private_key = $dir/private/key.pem\n" - "RANDFILE = $dir/private/RAND\n" - "\n" - "x509_extensions = user_cert\n" - "default_days = 3600\n" - "default_md = sha1\n" - "preserve = no\n" - "policy = policy_match\n" - "\n" - - "[policy_match]\n" - "commonName = supplied\n" - "organizationalUnitName = optional\n" - "organizationName = match\n" - "countryName = match\n" - "localityName = match\n" - "emailAddress = supplied\n" - "\n" - - "[user_cert]\n" - "basicConstraints = CA:false\n" - "keyUsage = nonRepudiation, digitalSignature, keyEncipherment\n" - "subjectKeyIdentifier = hash\n" - "authorityKeyIdentifier = keyid,issuer:always\n" - "subjectAltName = email:copy\n" - "issuerAltName = issuer:copy\n" - "\n" - - "[ca_cert]\n" - "basicConstraints = critical,CA:true\n" - "keyUsage = cRLSign, keyCertSign\n" - "subjectKeyIdentifier = hash\n" - "authorityKeyIdentifier = keyid:always,issuer:always\n" - "subjectAltName = email:copy\n" - "issuerAltName = issuer:copy\n"]. - + file:delete(filename:join(CaPath, "cert_key.pem")), + file:delete(filename:join(IPath, "cert_key.pem")), + file:rename(filename:join(CPath, "cert_key.pem"), filename:join(CPath, "key.pem")), + file:rename(filename:join(SPath, "cert_key.pem"), filename:join(SPath, "key.pem")), + ok. diff --git a/lib/ssl/src/ssl.appup.src b/lib/ssl/src/ssl.appup.src index 65f23e2f74..88cd73be74 100644 --- a/lib/ssl/src/ssl.appup.src +++ b/lib/ssl/src/ssl.appup.src @@ -1,6 +1,7 @@ %% -*- erlang -*- {"%VSN%", [ + {"4.0", [{restart_application, ssl}]}, {"3.11.1", [{restart_application, ssl}]}, {"3.11", [{restart_application, ssl}]}, {"3.10", [{restart_application, ssl}]}, @@ -15,6 +16,7 @@ {"3.10.9", [{restart_application, ssl}]} ], [ + {"4.0", [{restart_application, ssl}]}, {"3.11.1", [{restart_application, ssl}]}, {"3.11", [{restart_application, ssl}]}, {"3.10", [{restart_application, ssl}]}, diff --git a/lib/ssl/src/ssl.erl b/lib/ssl/src/ssl.erl index df4cd7c84d..dbc5faff14 100644 --- a/lib/ssl/src/ssl.erl +++ b/lib/ssl/src/ssl.erl @@ -77,8 +77,10 @@ stop() -> application:stop(ssl). %%-------------------------------------------------------------------- --spec connect(host() | port(), port_num(), list()) -> {ok, #sslsocket{}}. --spec connect(host() | port(), port_num(), list(), timeout()) -> {ok, #sslsocket{}}. +-spec connect(host() | port(), list()) -> {ok, #sslsocket{}}. +-spec connect(host() | port(), list() | port_num(), timeout() | list()) -> {ok, #sslsocket{}}. +-spec connect(host() | port(), port_num(), list(), timeout()) -> {ok, #sslsocket{}}. + %% %% Description: Connect to a ssl server. %%-------------------------------------------------------------------- @@ -215,8 +217,8 @@ ssl_accept(Socket, SslOptions, Timeout) when is_port(Socket) -> {ok, #config{cb=CbInfo,ssl=SslOpts, emulated=EmOpts}} -> {ok, Port} = inet:port(Socket), ssl_connection:ssl_accept(Port, Socket, - {SslOpts, EmOpts}, - self(), CbInfo, Timeout) + {SslOpts, EmOpts}, + self(), CbInfo, Timeout) catch Error = {error, _Reason} -> Error end. @@ -326,7 +328,7 @@ decode_peercert(BinCert, Opts) -> {ok, BinCert} end. -select_part(otp, {ok, Cert}, Opts) -> +select_part(otp, Cert, Opts) -> case lists:member(subject, Opts) of true -> TBS = Cert#'OTPCertificate'.tbsCertificate, @@ -335,7 +337,7 @@ select_part(otp, {ok, Cert}, Opts) -> {ok, Cert} end; -select_part(plain, {ok, Cert}, Opts) -> +select_part(plain, Cert, Opts) -> case lists:member(subject, Opts) of true -> TBS = Cert#'Certificate'.tbsCertificate, @@ -374,7 +376,7 @@ cipher_suites(openssl) -> [ssl_cipher:openssl_suite_name(S) || S <- ssl_cipher:suites(Version)]. %%-------------------------------------------------------------------- --spec getopts(#sslsocket{}, [atom()]) -> {ok, [{atom(), term()}]}| {error, reason()}. +-spec getopts(#sslsocket{}, [atom()]) -> {ok, [{atom(), term()}]}| {error, reason()}. %% %% Description: %%-------------------------------------------------------------------- @@ -446,8 +448,8 @@ session_info(#sslsocket{pid = Pid, fd = new_ssl}) -> ssl_connection:session_info(Pid). %%--------------------------------------------------------------- --spec versions() -> [{{ssl_app, string()}, {supported, [tls_version()]}, - {available, [tls_version()]}}]. +-spec versions() -> [{ssl_app, string()} | {supported, [tls_atom_version()]} | + {available, [tls_atom_version()]}]. %% %% Description: Returns a list of relevant versions. %%-------------------------------------------------------------------- @@ -457,6 +459,7 @@ versions() -> AvailableVsns = ?DEFAULT_SUPPORTED_VERSIONS, [{ssl_app, ?VSN}, {supported, SupportedVsns}, {available, AvailableVsns}]. + %%--------------------------------------------------------------- -spec renegotiate(#sslsocket{}) -> ok | {error, reason()}. %% @@ -520,58 +523,62 @@ old_listen(Port, Options) -> {ok, Pid} = ssl_broker:start_broker(listener), ssl_broker:listen(Pid, Port, Options). -handle_options(Opts0, Role) -> +handle_options(Opts0, _Role) -> Opts = proplists:expand([{binary, [{mode, binary}]}, {list, [{mode, list}]}], Opts0), ReuseSessionFun = fun(_, _, _, _) -> true end, - AcceptBadCa = fun({bad_cert,unknown_ca}, Acc) -> Acc; - (Other, Acc) -> [Other | Acc] - end, - - VerifyFun = - fun(ErrorList) -> - case lists:foldl(AcceptBadCa, [], ErrorList) of - [] -> true; - [_|_] -> false - end - end, + VerifyNoneFun = + {fun(_,{bad_cert, unknown_ca}, UserState) -> + {valid, UserState}; + (_,{bad_cert, _} = Reason, _) -> + {fail, Reason}; + (_,{extension, _}, UserState) -> + {unknown, UserState} + end, []}, - UserFailIfNoPeerCert = validate_option(fail_if_no_peer_cert, - proplists:get_value(fail_if_no_peer_cert, Opts, false)), + UserFailIfNoPeerCert = handle_option(fail_if_no_peer_cert, Opts, false), + UserVerifyFun = handle_option(verify_fun, Opts, undefined), + CaCerts = handle_option(cacerts, Opts, undefined), - {Verify, FailIfNoPeerCert, CaCertDefault} = + {Verify, FailIfNoPeerCert, CaCertDefault, VerifyFun} = %% Handle 0, 1, 2 for backwards compatibility case proplists:get_value(verify, Opts, verify_none) of 0 -> - {verify_none, false, ca_cert_default(verify_none, Role)}; + {verify_none, false, + ca_cert_default(verify_none, VerifyNoneFun, CaCerts), VerifyNoneFun}; 1 -> - {verify_peer, false, ca_cert_default(verify_peer, Role)}; + {verify_peer, false, + ca_cert_default(verify_peer, UserVerifyFun, CaCerts), UserVerifyFun}; 2 -> - {verify_peer, true, ca_cert_default(verify_peer, Role)}; + {verify_peer, true, + ca_cert_default(verify_peer, UserVerifyFun, CaCerts), UserVerifyFun}; verify_none -> - {verify_none, false, ca_cert_default(verify_none, Role)}; + {verify_none, false, + ca_cert_default(verify_none, VerifyNoneFun, CaCerts), VerifyNoneFun}; verify_peer -> - {verify_peer, UserFailIfNoPeerCert, ca_cert_default(verify_peer, Role)}; + {verify_peer, UserFailIfNoPeerCert, + ca_cert_default(verify_peer, UserVerifyFun, CaCerts), UserVerifyFun}; Value -> throw({error, {eoptions, {verify, Value}}}) - end, + end, CertFile = handle_option(certfile, Opts, ""), SSLOptions = #ssl_options{ versions = handle_option(versions, Opts, []), verify = validate_option(verify, Verify), - verify_fun = handle_option(verify_fun, Opts, VerifyFun), + verify_fun = VerifyFun, fail_if_no_peer_cert = FailIfNoPeerCert, verify_client_once = handle_option(verify_client_once, Opts, false), - validate_extensions_fun = handle_option(validate_extensions_fun, Opts, undefined), depth = handle_option(depth, Opts, 1), + cert = handle_option(cert, Opts, undefined), certfile = CertFile, - keyfile = handle_option(keyfile, Opts, CertFile), key = handle_option(key, Opts, undefined), + keyfile = handle_option(keyfile, Opts, CertFile), password = handle_option(password, Opts, ""), + cacerts = CaCerts, cacertfile = handle_option(cacertfile, Opts, CaCertDefault), dhfile = handle_option(dhfile, Opts, undefined), ciphers = handle_option(ciphers, Opts, []), @@ -584,10 +591,10 @@ handle_options(Opts0, Role) -> }, CbInfo = proplists:get_value(cb_info, Opts, {gen_tcp, tcp, tcp_closed, tcp_error}), - SslOptions = [versions, verify, verify_fun, validate_extensions_fun, + SslOptions = [versions, verify, verify_fun, fail_if_no_peer_cert, verify_client_once, - depth, certfile, keyfile, - key, password, cacertfile, dhfile, ciphers, + depth, cert, certfile, key, keyfile, + password, cacerts, cacertfile, dhfile, ciphers, debug, reuse_session, reuse_sessions, ssl_imp, cb_info, renegotiate_at, secure_renegotiate], @@ -611,7 +618,21 @@ validate_option(ssl_imp, Value) when Value == new; Value == old -> validate_option(verify, Value) when Value == verify_none; Value == verify_peer -> Value; -validate_option(verify_fun, Value) when is_function(Value) -> +validate_option(verify_fun, undefined) -> + undefined; +%% Backwards compatibility +validate_option(verify_fun, Fun) when is_function(Fun) -> + {fun(_,{bad_cert, _} = Reason, OldFun) -> + case OldFun([Reason]) of + true -> + {valid, OldFun}; + false -> + {fail, Reason} + end; + (_,{extension, _}, UserState) -> + {unknown, UserState} + end, Fun}; +validate_option(verify_fun, {Fun, _} = Value) when is_function(Fun) -> Value; validate_option(fail_if_no_peer_cert, Value) when Value == true; Value == false -> @@ -619,23 +640,29 @@ validate_option(fail_if_no_peer_cert, Value) validate_option(verify_client_once, Value) when Value == true; Value == false -> Value; - -validate_option(validate_extensions_fun, Value) when Value == undefined; is_function(Value) -> - Value; validate_option(depth, Value) when is_integer(Value), Value >= 0, Value =< 255-> Value; +validate_option(cert, Value) when Value == undefined; + is_binary(Value) -> + Value; validate_option(certfile, Value) when is_list(Value) -> Value; + +validate_option(key, undefined) -> + undefined; +validate_option(key, {KeyType, Value}) when is_binary(Value), + KeyType == rsa; + KeyType == dsa -> + {KeyType, Value}; validate_option(keyfile, Value) when is_list(Value) -> Value; -validate_option(key, Value) when Value == undefined; - is_tuple(Value) -> - %% element(1, Value)=='RSAPrivateKey' -> - Value; validate_option(password, Value) when is_list(Value) -> Value; +validate_option(cacerts, Value) when Value == undefined; + is_list(Value) -> + Value; %% certfile must be present in some cases otherwhise it can be set %% to the empty string. validate_option(cacertfile, undefined) -> @@ -699,14 +726,16 @@ validate_inet_option(active, Value) validate_inet_option(_, _) -> ok. -ca_cert_default(verify_none, _) -> +%% The option cacerts overrides cacertsfile +ca_cert_default(_,_, [_|_]) -> + undefined; +ca_cert_default(verify_none, _, _) -> undefined; -%% Client may leave verification up to the user -ca_cert_default(verify_peer, client) -> +ca_cert_default(verify_peer, {Fun,_}, _) when is_function(Fun) -> undefined; -%% Server that wants to verify_peer must have +%% Server that wants to verify_peer and has no verify_fun must have %% some trusted certs. -ca_cert_default(verify_peer, server) -> +ca_cert_default(verify_peer, undefined, _) -> "". emulated_options() -> diff --git a/lib/ssl/src/ssl_app.erl b/lib/ssl/src/ssl_app.erl index d9a354086d..8d50fd7bdb 100644 --- a/lib/ssl/src/ssl_app.erl +++ b/lib/ssl/src/ssl_app.erl @@ -29,14 +29,14 @@ %%-------------------------------------------------------------------- -spec start(normal | {takeover, node()} | {failover, node()}, list()) -> - {ok, pid()} | {ok, pid(), term()} | {error, term()}. + ignore | {ok, pid()} | {error, term()}. %%-------------------------------------------------------------------- start(_Type, _StartArgs) -> ssl_sup:start_link(). %-------------------------------------------------------------------- -spec stop(term())-> ok. -%%-------------------------------------------------------------------- +%%-------------------------------------------------------------------- stop(_State) -> ok. diff --git a/lib/ssl/src/ssl_certificate.erl b/lib/ssl/src/ssl_certificate.erl index 8a79f75725..6cf57ced81 100644 --- a/lib/ssl/src/ssl_certificate.erl +++ b/lib/ssl/src/ssl_certificate.erl @@ -31,10 +31,11 @@ -include("ssl_debug.hrl"). -include_lib("public_key/include/public_key.hrl"). --export([trusted_cert_and_path/3, +-export([trusted_cert_and_path/2, certificate_chain/2, file_to_certificats/1, - validate_extensions/6, + %validate_extensions/6, + validate_extension/3, is_valid_extkey_usage/2, is_valid_key_usage/2, select_extension/2, @@ -47,61 +48,59 @@ %%==================================================================== %%-------------------------------------------------------------------- --spec trusted_cert_and_path([der_cert()], certdb_ref(), boolean()) -> - {der_cert(), [der_cert()], list()}. +-spec trusted_cert_and_path([der_cert()], certdb_ref()) -> + {der_cert() | unknown_ca, [der_cert()]}. %% %% Description: Extracts the root cert (if not presents tries to %% look it up, if not found {bad_cert, unknown_ca} will be added verification %% errors. Returns {RootCert, Path, VerifyErrors} %%-------------------------------------------------------------------- -trusted_cert_and_path(CertChain, CertDbRef, Verify) -> - [Cert | RestPath] = lists:reverse(CertChain), - {ok, OtpCert} = public_key:pkix_decode_cert(Cert, otp), - IssuerAnPath = +trusted_cert_and_path(CertChain, CertDbRef) -> + Path = [Cert | _] = lists:reverse(CertChain), + OtpCert = public_key:pkix_decode_cert(Cert, otp), + IssuerID = case public_key:pkix_is_self_signed(OtpCert) of true -> {ok, IssuerId} = public_key:pkix_issuer_id(OtpCert, self), - {IssuerId, RestPath}; - false -> + IssuerId; + false -> case public_key:pkix_issuer_id(OtpCert, other) of {ok, IssuerId} -> - {IssuerId, [Cert | RestPath]}; + IssuerId; {error, issuer_not_found} -> case find_issuer(OtpCert, no_candidate) of {ok, IssuerId} -> - {IssuerId, [Cert | RestPath]}; + IssuerId; Other -> - {Other, RestPath} + Other end end end, - case IssuerAnPath of - {{error, issuer_not_found}, _ } -> - %% The root CA was not sent and can not be found, we fail if verify = true - not_valid(?ALERT_REC(?FATAL, ?UNKNOWN_CA), Verify, {Cert, RestPath}); - {{SerialNr, Issuer}, Path} -> - case ssl_manager:lookup_trusted_cert(CertDbRef, - SerialNr, Issuer) of + case IssuerID of + {error, issuer_not_found} -> + %% The root CA was not sent and can not be found. + {unknown_ca, Path}; + {SerialNr, Issuer} -> + case ssl_manager:lookup_trusted_cert(CertDbRef, SerialNr, Issuer) of {ok, {BinCert,_}} -> - {BinCert, Path, []}; + {BinCert, Path}; _ -> - %% Fail if verify = true - not_valid(?ALERT_REC(?FATAL, ?UNKNOWN_CA), - Verify, {Cert, RestPath}) + %% Root CA could not be verified + {unknown_ca, Path} end end. %%-------------------------------------------------------------------- -spec certificate_chain(undefined | binary(), certdb_ref()) -> - {error, no_cert} | [der_cert()]. + {error, no_cert} | {ok, [der_cert()]}. %% %% Description: Return the certificate chain to send to peer. %%-------------------------------------------------------------------- certificate_chain(undefined, _CertsDbRef) -> {error, no_cert}; certificate_chain(OwnCert, CertsDbRef) -> - {ok, ErlCert} = public_key:pkix_decode_cert(OwnCert, otp), + ErlCert = public_key:pkix_decode_cert(OwnCert, otp), certificate_chain(ErlCert, OwnCert, CertsDbRef, [OwnCert]). %%-------------------------------------------------------------------- -spec file_to_certificats(string()) -> [der_cert()]. @@ -110,34 +109,27 @@ certificate_chain(OwnCert, CertsDbRef) -> %%-------------------------------------------------------------------- file_to_certificats(File) -> {ok, List} = ssl_manager:cache_pem_file(File), - [Bin || {cert, Bin, not_encrypted} <- List]. + [Bin || {'Certificate', Bin, not_encrypted} <- List]. %%-------------------------------------------------------------------- --spec validate_extensions([#'Extension'{}], term(), [#'Extension'{}], - boolean(), list(), client | server) -> {[#'Extension'{}], term(), list()}. +-spec validate_extension(term(), #'Extension'{}, term()) -> {valid, term()} | + {fail, tuple()} | + {unknown, term()}. %% %% Description: Validates ssl/tls specific extensions %%-------------------------------------------------------------------- -validate_extensions([], ValidationState, UnknownExtensions, _, AccErr, _) -> - {UnknownExtensions, ValidationState, AccErr}; - -validate_extensions([#'Extension'{extnID = ?'id-ce-extKeyUsage', - extnValue = KeyUse, - critical = true} | Rest], - ValidationState, UnknownExtensions, Verify, AccErr0, Role) -> +validate_extension(_,{extension, #'Extension'{extnID = ?'id-ce-extKeyUsage', + extnValue = KeyUse, + critical = true}}, Role) -> case is_valid_extkey_usage(KeyUse, Role) of true -> - validate_extensions(Rest, ValidationState, UnknownExtensions, - Verify, AccErr0, Role); + {valid, Role}; false -> - AccErr = - not_valid_extension({bad_cert, invalid_ext_key_usage}, Verify, AccErr0), - validate_extensions(Rest, ValidationState, UnknownExtensions, Verify, AccErr, Role) + {fail, {bad_cert, invalid_ext_key_usage}} end; - -validate_extensions([Extension | Rest], ValidationState, UnknownExtensions, - Verify, AccErr, Role) -> - validate_extensions(Rest, ValidationState, [Extension | UnknownExtensions], - Verify, AccErr, Role). +validate_extension(_, {bad_cert, _} = Reason, _) -> + {fail, Reason}; +validate_extension(_, _, Role) -> + {unknown, Role}. %%-------------------------------------------------------------------- -spec is_valid_key_usage(list(), term()) -> boolean(). @@ -219,7 +211,7 @@ certificate_chain(CertsDbRef, Chain, SerialNr, Issuer, _SelfSigned) -> case ssl_manager:lookup_trusted_cert(CertsDbRef, SerialNr, Issuer) of {ok, {IssuerCert, ErlCert}} -> - {ok, ErlCert} = public_key:pkix_decode_cert(IssuerCert, otp), + ErlCert = public_key:pkix_decode_cert(IssuerCert, otp), certificate_chain(ErlCert, IssuerCert, CertsDbRef, [IssuerCert | Chain]); _ -> @@ -244,19 +236,9 @@ find_issuer(OtpCert, PrevCandidateKey) -> end end. -not_valid(Alert, true, _) -> - throw(Alert); -not_valid(_, false, {ErlCert, Path}) -> - {ErlCert, Path, [{bad_cert, unknown_ca}]}. - is_valid_extkey_usage(KeyUse, client) -> %% Client wants to verify server is_valid_key_usage(KeyUse,?'id-kp-serverAuth'); is_valid_extkey_usage(KeyUse, server) -> %% Server wants to verify client is_valid_key_usage(KeyUse, ?'id-kp-clientAuth'). - -not_valid_extension(Error, true, _) -> - throw(Error); -not_valid_extension(Error, false, AccErrors) -> - [Error | AccErrors]. diff --git a/lib/ssl/src/ssl_certificate_db.erl b/lib/ssl/src/ssl_certificate_db.erl index e953821057..86477f369d 100644 --- a/lib/ssl/src/ssl_certificate_db.erl +++ b/lib/ssl/src/ssl_certificate_db.erl @@ -54,10 +54,9 @@ remove(Dbs) -> lists:foreach(fun(Db) -> true = ets:delete(Db) end, Dbs). %%-------------------------------------------------------------------- --spec lookup_trusted_cert(reference(), serialnumber(), issuer()) -> {der_cert(), #'OTPCertificate'{}}. +-spec lookup_trusted_cert(reference(), serialnumber(), issuer()) -> + undefined | {ok, {der_cert(), #'OTPCertificate'{}}}. -%% SerialNumber = integer() -%% Issuer = {rdnSequence, IssuerAttrs} %% %% Description: Retrives the trusted certificate identified by %% <SerialNumber, Issuer>. Ref is used as it is specified @@ -75,12 +74,16 @@ lookup_cached_certs(File) -> ets:lookup(certificate_db_name(), {file, File}). %%-------------------------------------------------------------------- --spec add_trusted_certs(pid(), string(), certdb_ref()) -> {ok, certdb_ref()}. +-spec add_trusted_certs(pid(), string() | {der, list()}, certdb_ref()) -> {ok, certdb_ref()}. %% %% Description: Adds the trusted certificates from file <File> to the %% runtime database. Returns Ref that should be handed to lookup_trusted_cert %% together with the cert serialnumber and issuer. %%-------------------------------------------------------------------- +add_trusted_certs(_Pid, {der, DerList}, [CerDb, _,_]) -> + NewRef = make_ref(), + add_certs_from_der(DerList, NewRef, CerDb), + {ok, NewRef}; add_trusted_certs(Pid, File, [CertsDb, FileToRefDb, PidToFileDb]) -> Ref = case lookup(File, FileToRefDb) of undefined -> @@ -94,17 +97,17 @@ add_trusted_certs(Pid, File, [CertsDb, FileToRefDb, PidToFileDb]) -> end, insert(Pid, File, PidToFileDb), {ok, Ref}. - %%-------------------------------------------------------------------- -spec cache_pem_file(pid(), string(), certdb_ref()) -> term(). %% %% Description: Cache file as binary in DB %%-------------------------------------------------------------------- cache_pem_file(Pid, File, [CertsDb, _FileToRefDb, PidToFileDb]) -> - Res = {ok, Content} = public_key:pem_to_der(File), + {ok, PemBin} = file:read_file(File), + Content = public_key:pem_decode(PemBin), insert({file, File}, Content, CertsDb), insert(Pid, File, PidToFileDb), - Res. + {ok, Content}. %%-------------------------------------------------------------------- -spec remove_trusted_certs(pid(), certdb_ref()) -> term(). @@ -138,13 +141,13 @@ remove_trusted_certs(Pid, [CertsDb, FileToRefDb, PidToFileDb]) -> end. %%-------------------------------------------------------------------- --spec issuer_candidate(no_candidate | cert_key()) -> - {cert_key(), der_cert()} | no_more_candidates. +-spec issuer_candidate(no_candidate | cert_key() | {file, term()}) -> + {cert_key(),{der_cert(), #'OTPCertificate'{}}} | no_more_candidates. %% %% Description: If a certificat does not define its issuer through %% the extension 'ce-authorityKeyIdentifier' we can %% try to find the issuer in the database over known -%% certificates. +%% certificates. %%-------------------------------------------------------------------- issuer_candidate(no_candidate) -> Db = certificate_db_name(), @@ -202,15 +205,20 @@ lookup(Key, Db) -> remove_certs(Ref, CertsDb) -> ets:match_delete(CertsDb, {{Ref, '_', '_'}, '_'}). +add_certs_from_der(DerList, Ref, CertsDb) -> + Add = fun(Cert) -> add_certs(Cert, Ref, CertsDb) end, + [Add(Cert) || Cert <- DerList]. + add_certs_from_file(File, Ref, CertsDb) -> - Decode = fun(Cert) -> - {ok, ErlCert} = public_key:pkix_decode_cert(Cert, otp), - TBSCertificate = ErlCert#'OTPCertificate'.tbsCertificate, - SerialNumber = TBSCertificate#'OTPTBSCertificate'.serialNumber, - Issuer = public_key:pkix_normalize_general_name( - TBSCertificate#'OTPTBSCertificate'.issuer), - insert({Ref, SerialNumber, Issuer}, {Cert,ErlCert}, CertsDb) - end, - {ok,Der} = public_key:pem_to_der(File), - [Decode(Cert) || {cert, Cert, not_encrypted} <- Der]. + Add = fun(Cert) -> add_certs(Cert, Ref, CertsDb) end, + {ok, PemBin} = file:read_file(File), + PemEntries = public_key:pem_decode(PemBin), + [Add(Cert) || {'Certificate', Cert, not_encrypted} <- PemEntries]. +add_certs(Cert, Ref, CertsDb) -> + ErlCert = public_key:pkix_decode_cert(Cert, otp), + TBSCertificate = ErlCert#'OTPCertificate'.tbsCertificate, + SerialNumber = TBSCertificate#'OTPTBSCertificate'.serialNumber, + Issuer = public_key:pkix_normalize_name( + TBSCertificate#'OTPTBSCertificate'.issuer), + insert({Ref, SerialNumber, Issuer}, {Cert,ErlCert}, CertsDb). diff --git a/lib/ssl/src/ssl_cipher.erl b/lib/ssl/src/ssl_cipher.erl index a6e80047c2..8230149304 100644 --- a/lib/ssl/src/ssl_cipher.erl +++ b/lib/ssl/src/ssl_cipher.erl @@ -40,7 +40,7 @@ -compile(inline). %%-------------------------------------------------------------------- --spec security_parameters(erl_cipher_suite(), #security_parameters{}) -> +-spec security_parameters(cipher_suite(), #security_parameters{}) -> #security_parameters{}. %% %% Description: Returns a security parameters record where the @@ -119,7 +119,7 @@ block_cipher(Fun, BlockSz, #cipher_state{key=Key, iv=IV} = CS0, %%-------------------------------------------------------------------- -spec decipher(cipher_enum(), integer(), #cipher_state{}, binary(), tls_version()) -> - {binary(), #cipher_state{}}. + {binary(), binary(), #cipher_state{}} | #alert{}. %% %% Description: Decrypts the data and the MAC using cipher described %% by cipher_enum() and updating the cipher state. @@ -370,7 +370,7 @@ openssl_suite_name(Cipher) -> filter(undefined, Ciphers) -> Ciphers; filter(DerCert, Ciphers) -> - {ok, OtpCert} = public_key:pkix_decode_cert(DerCert, otp), + OtpCert = public_key:pkix_decode_cert(DerCert, otp), SigAlg = OtpCert#'OTPCertificate'.signatureAlgorithm, case ssl_certificate:signature_type(SigAlg#'SignatureAlgorithm'.algorithm) of rsa -> @@ -506,6 +506,12 @@ generic_stream_cipher_from_bin(T, HashSz) -> is_correct_padding(_, {3, 0}) -> true; +%% For interoperability reasons we do not check the padding in TLS 1.0 as it +%% is not strictly required and breaks interopability with for instance +%% Google. +is_correct_padding(_, {3, 1}) -> + true; +%% Padding must be check in TLS 1.1 and after is_correct_padding(#generic_block_cipher{padding_length = Len, padding = Padding}, _) -> list_to_binary(lists:duplicate(Len, Len)) == Padding. diff --git a/lib/ssl/src/ssl_cipher.hrl b/lib/ssl/src/ssl_cipher.hrl index 19de709d9c..8bd68cc190 100644 --- a/lib/ssl/src/ssl_cipher.hrl +++ b/lib/ssl/src/ssl_cipher.hrl @@ -28,7 +28,7 @@ -type cipher() :: null |rc4_128 | idea_cbc | des40_cbc | des_cbc | '3des_ede_cbc' | aes_128_cbc | aes_256_cbc. --type hash() :: sha | md5. +-type hash() :: null | sha | md5. -type erl_cipher_suite() :: {key_algo(), cipher(), hash()}. -type cipher_suite() :: binary(). -type cipher_enum() :: integer(). diff --git a/lib/ssl/src/ssl_connection.erl b/lib/ssl/src/ssl_connection.erl index 5b4b129e30..7689976ff6 100644 --- a/lib/ssl/src/ssl_connection.erl +++ b/lib/ssl/src/ssl_connection.erl @@ -125,8 +125,9 @@ send(Pid, Data) -> recv(Pid, Length, Timeout) -> sync_send_all_state_event(Pid, {recv, Length}, Timeout). %%-------------------------------------------------------------------- --spec connect(host(), port_num(), port(), list(), pid(), tuple(), timeout()) -> - {ok, #sslsocket{}} | {error, reason()}. +-spec connect(host(), port_num(), port(), {#ssl_options{}, #socket_options{}}, + pid(), tuple(), timeout()) -> + {ok, #sslsocket{}} | {error, reason()}. %% %% Description: Connect to a ssl server. %%-------------------------------------------------------------------- @@ -138,7 +139,8 @@ connect(Host, Port, Socket, Options, User, CbInfo, Timeout) -> {error, ssl_not_started} end. %%-------------------------------------------------------------------- --spec ssl_accept(port_num(), port(), list(), pid(), tuple(), timeout()) -> +-spec ssl_accept(port_num(), port(), {#ssl_options{}, #socket_options{}}, + pid(), tuple(), timeout()) -> {ok, #sslsocket{}} | {error, reason()}. %% %% Description: Performs accept on a ssl listen socket. e.i. performs @@ -253,7 +255,7 @@ session_info(ConnectionPid) -> sync_send_all_state_event(ConnectionPid, session_info). %%-------------------------------------------------------------------- --spec peer_certificate(pid()) -> {ok, binary()} | {error, reason()}. +-spec peer_certificate(pid()) -> {ok, binary()| undefined} | {error, reason()}. %% %% Description: Returns the peer cert %%-------------------------------------------------------------------- @@ -288,9 +290,10 @@ start_link(Role, Host, Port, Socket, Options, User, CbInfo) -> %% gen_fsm callbacks %%==================================================================== %%-------------------------------------------------------------------- --spec init(list()) -> {ok, state_name(), #state{}} - | {ok, state_name(), #state{}, timeout()} | - ignore | {stop, term()}. +-spec init(list()) -> {ok, state_name(), #state{}} | {stop, term()}. +%% Possible return values not used now. +%% | {ok, state_name(), #state{}, timeout()} | +%% ignore %% Description:Whenever a gen_fsm is started using gen_fsm:start/[3,4] or %% gen_fsm:start_link/3,4, this function is called by the new process to %% initialize. @@ -331,14 +334,12 @@ hello(start, #state{host = Host, port = Port, role = client, ssl_options = SslOpts, transport_cb = Transport, socket = Socket, connection_states = ConnectionStates, - own_cert = Cert, renegotiation = {Renegotiation, _}} = State0) -> Hello = ssl_handshake:client_hello(Host, Port, ConnectionStates, - SslOpts, Cert, - Renegotiation), + SslOpts, Renegotiation), Version = Hello#client_hello.client_version, Hashes0 = ssl_handshake:init_hashes(), @@ -350,7 +351,7 @@ hello(start, #state{host = Host, port = Port, role = client, session = #session{session_id = Hello#client_hello.session_id, is_resumable = false}, - tls_handshake_hashes = Hashes1}, + tls_handshake_hashes = Hashes1}, {Record, State} = next_record(State1), next_state(hello, Record, State); @@ -499,8 +500,7 @@ certify(#certificate{} = Cert, ssl_options = Opts} = State) -> case ssl_handshake:certify(Cert, CertDbRef, Opts#ssl_options.depth, Opts#ssl_options.verify, - Opts#ssl_options.verify_fun, - Opts#ssl_options.validate_extensions_fun, Role) of + Opts#ssl_options.verify_fun, Role) of {PeerCert, PublicKeyInfo} -> handle_peer_cert(PeerCert, PublicKeyInfo, State#state{client_certificate_requested = false}); @@ -576,58 +576,61 @@ certify(#client_key_exchange{} = Msg, %% We expect a certificate here handle_unexpected_message(Msg, certify_client_key_exchange, State); -certify(#client_key_exchange{exchange_keys - = #encrypted_premaster_secret{premaster_secret - = EncPMS}}, - #state{negotiated_version = Version, - connection_states = ConnectionStates0, - session = Session0, - private_key = Key} = State0) -> - try ssl_handshake:decrypt_premaster_secret(EncPMS, Key) of - PremasterSecret -> - case ssl_handshake:master_secret(Version, PremasterSecret, - ConnectionStates0, server) of - {MasterSecret, ConnectionStates} -> - Session = Session0#session{master_secret = MasterSecret}, - State1 = State0#state{connection_states = ConnectionStates, - session = Session}, - {Record, State} = next_record(State1), - next_state(cipher, Record, State); - #alert{} = Alert -> - handle_own_alert(Alert, Version, - certify_client_key_exchange, State0), - {stop, normal, State0} - end +certify(#client_key_exchange{exchange_keys = Keys}, + State = #state{key_algorithm = KeyAlg, negotiated_version = Version}) -> + try + certify_client_key_exchange(ssl_handshake:decode_client_key(Keys, KeyAlg, Version), State) catch #alert{} = Alert -> - handle_own_alert(Alert, Version, certify_client_key_exchange, - State0), + handle_own_alert(Alert, Version, certify_client_key_exchange, State), + {stop, normal, State} + end; + +certify(Msg, State) -> + handle_unexpected_message(Msg, certify, State). + +certify_client_key_exchange(#encrypted_premaster_secret{premaster_secret= EncPMS}, + #state{negotiated_version = Version, + connection_states = ConnectionStates0, + session = Session0, + private_key = Key} = State0) -> + PremasterSecret = ssl_handshake:decrypt_premaster_secret(EncPMS, Key), + case ssl_handshake:master_secret(Version, PremasterSecret, + ConnectionStates0, server) of + {MasterSecret, ConnectionStates} -> + Session = Session0#session{master_secret = MasterSecret}, + State1 = State0#state{connection_states = ConnectionStates, + session = Session}, + {Record, State} = next_record(State1), + next_state(cipher, Record, State); + #alert{} = Alert -> + handle_own_alert(Alert, Version, + certify_client_key_exchange, State0), {stop, normal, State0} end; -certify(#client_key_exchange{exchange_keys = #client_diffie_hellman_public{ - dh_public = ClientPublicDhKey}}, - #state{negotiated_version = Version, - diffie_hellman_params = #'DHParameter'{prime = P, - base = G}, - diffie_hellman_keys = {_, ServerDhPrivateKey}, - role = Role, - session = Session, - connection_states = ConnectionStates0} = State0) -> - +certify_client_key_exchange(#client_diffie_hellman_public{dh_public = ClientPublicDhKey}, + #state{negotiated_version = Version, + diffie_hellman_params = #'DHParameter'{prime = P, + base = G}, + diffie_hellman_keys = {_, ServerDhPrivateKey}, + role = Role, + session = Session, + connection_states = ConnectionStates0} = State0) -> + PMpint = crypto:mpint(P), GMpint = crypto:mpint(G), PremasterSecret = crypto:dh_compute_key(mpint_binary(ClientPublicDhKey), ServerDhPrivateKey, [PMpint, GMpint]), - + case ssl_handshake:master_secret(Version, PremasterSecret, ConnectionStates0, Role) of {MasterSecret, ConnectionStates} -> State1 = State0#state{session = - Session#session{master_secret - = MasterSecret}, - connection_states = ConnectionStates}, + Session#session{master_secret + = MasterSecret}, + connection_states = ConnectionStates}, {Record, State} = next_record(State1), next_state(cipher, Record, State); @@ -635,10 +638,7 @@ certify(#client_key_exchange{exchange_keys = #client_diffie_hellman_public{ handle_own_alert(Alert, Version, certify_client_key_exchange, State0), {stop, normal, State0} - end; - -certify(Msg, State) -> - handle_unexpected_message(Msg, certify, State). + end. %%-------------------------------------------------------------------- -spec cipher(#hello_request{} | #certificate_verify{} | #finished{} | term(), @@ -698,14 +698,13 @@ connection(#hello_request{}, #state{host = Host, port = Port, socket = Socket, ssl_options = SslOpts, negotiated_version = Version, - own_cert = Cert, transport_cb = Transport, connection_states = ConnectionStates0, renegotiation = {Renegotiation, _}, tls_handshake_hashes = Hashes0} = State0) -> - Hello = ssl_handshake:client_hello(Host, Port, - ConnectionStates0, SslOpts, Cert, Renegotiation), + Hello = ssl_handshake:client_hello(Host, Port, ConnectionStates0, + SslOpts, Renegotiation), {BinMsg, ConnectionStates1, Hashes1} = encode_handshake(Hello, Version, ConnectionStates0, Hashes0), @@ -720,7 +719,9 @@ connection(#client_hello{} = Hello, #state{role = server} = State) -> connection(Msg, State) -> handle_unexpected_message(Msg, connection, State). %%-------------------------------------------------------------------- --spec handle_event(term(), state_name(), #state{}) -> gen_fsm_state_return(). +-spec handle_event(term(), state_name(), #state{}) -> term(). +%% As it is not currently used gen_fsm_state_return() makes +%% dialyzer unhappy! %% %% Description: Whenever a gen_fsm receives an event sent using %% gen_fsm:send_all_state_event/2, this function is called to handle @@ -1036,26 +1037,37 @@ ssl_init(SslOpts, Role) -> DHParams = init_diffie_hellman(SslOpts#ssl_options.dhfile, Role), {ok, CertDbRef, CacheRef, OwnCert, PrivateKey, DHParams}. -init_certificates(#ssl_options{cacertfile = CACertFile, - certfile = CertFile}, Role) -> - case ssl_manager:connection_init(CACertFile, Role) of - {ok, CertDbRef, CacheRef} -> - init_certificates(CertDbRef, CacheRef, CertFile, Role); - {error, Reason} -> - handle_file_error(?LINE, error, Reason, CACertFile, ecacertfile, - erlang:get_stacktrace()) - end. +init_certificates(#ssl_options{cacerts = CaCerts, + cacertfile = CACertFile, + certfile = CertFile, + cert = Cert}, Role) -> + {ok, CertDbRef, CacheRef} = + try + Certs = case CaCerts of + undefined -> + CACertFile; + _ -> + {der, CaCerts} + end, + {ok, _, _} = ssl_manager:connection_init(Certs, Role) + catch + Error:Reason -> + handle_file_error(?LINE, Error, Reason, CACertFile, ecacertfile, + erlang:get_stacktrace()) + end, + init_certificates(Cert, CertDbRef, CacheRef, CertFile, Role). + -init_certificates(CertDbRef, CacheRef, CertFile, client) -> +init_certificates(undefined, CertDbRef, CacheRef, CertFile, client) -> try [OwnCert] = ssl_certificate:file_to_certificats(CertFile), {ok, CertDbRef, CacheRef, OwnCert} - catch _E:_R -> + catch _Error:_Reason -> {ok, CertDbRef, CacheRef, undefined} end; -init_certificates(CertDbRef, CacheRef, CertFile, server) -> +init_certificates(undefined, CertDbRef, CacheRef, CertFile, server) -> try [OwnCert] = ssl_certificate:file_to_certificats(CertFile), {ok, CertDbRef, CacheRef, OwnCert} @@ -1063,31 +1075,36 @@ init_certificates(CertDbRef, CacheRef, CertFile, server) -> Error:Reason -> handle_file_error(?LINE, Error, Reason, CertFile, ecertfile, erlang:get_stacktrace()) - end. + end; +init_certificates(Cert, CertDbRef, CacheRef, _, _) -> + {ok, CertDbRef, CacheRef, Cert}. init_private_key(undefined, "", _Password, client) -> undefined; init_private_key(undefined, KeyFile, Password, _) -> - case ssl_manager:cache_pem_file(KeyFile) of - {ok, List} -> - [Der] = [Der || Der = {PKey, _ , _} <- List, - PKey =:= rsa_private_key orelse - PKey =:= dsa_private_key], - {ok, Decoded} = public_key:decode_private_key(Der,Password), - Decoded; - {error, Reason} -> - handle_file_error(?LINE, error, Reason, KeyFile, ekeyfile, + try + {ok, List} = ssl_manager:cache_pem_file(KeyFile), + [PemEntry] = [PemEntry || PemEntry = {PKey, _ , _} <- List, + PKey =:= 'RSAPrivateKey' orelse + PKey =:= 'DSAPrivateKey'], + public_key:pem_entry_decode(PemEntry, Password) + catch + Error:Reason -> + handle_file_error(?LINE, Error, Reason, KeyFile, ekeyfile, erlang:get_stacktrace()) end; -init_private_key(PrivateKey, _, _,_) -> - PrivateKey. +init_private_key({rsa, PrivateKey}, _, _,_) -> + public_key:der_decode('RSAPrivateKey', PrivateKey); +init_private_key({dsa, PrivateKey},_,_,_) -> + public_key:der_decode('DSAPrivateKey', PrivateKey). handle_file_error(Line, Error, {badmatch, Reason}, File, Throw, Stack) -> file_error(Line, Error, Reason, File, Throw, Stack); handle_file_error(Line, Error, Reason, File, Throw, Stack) -> file_error(Line, Error, Reason, File, Throw, Stack). +-spec(file_error/6 :: (_,_,_,_,_,_) -> no_return()). file_error(Line, Error, Reason, File, Throw, Stack) -> Report = io_lib:format("SSL: ~p: ~p:~p ~s~n ~p~n", [Line, Error, Reason, File, Stack]), @@ -1099,17 +1116,18 @@ init_diffie_hellman(_, client) -> init_diffie_hellman(undefined, _) -> ?DEFAULT_DIFFIE_HELLMAN_PARAMS; init_diffie_hellman(DHParamFile, server) -> - case ssl_manager:cache_pem_file(DHParamFile) of - {ok, List} -> - case [Der || Der = {dh_params, _ , _} <- List] of - [Der] -> - {ok, Decoded} = public_key:decode_dhparams(Der), - Decoded; - [] -> - ?DEFAULT_DIFFIE_HELLMAN_PARAMS - end; - {error, Reason} -> - handle_file_error(?LINE, error, Reason, DHParamFile, edhfile, erlang:get_stacktrace()) + try + {ok, List} = ssl_manager:cache_pem_file(DHParamFile), + case [Entry || Entry = {'DHParameter', _ , _} <- List] of + [Entry] -> + public_key:pem_entry_decode(Entry); + [] -> + ?DEFAULT_DIFFIE_HELLMAN_PARAMS + end + catch + Error:Reason -> + handle_file_error(?LINE, Error, Reason, + DHParamFile, edhfile, erlang:get_stacktrace()) end. sync_send_all_state_event(FsmPid, Event) -> @@ -1178,7 +1196,7 @@ verify_client_cert(#state{client_certificate_requested = true, role = client, tls_handshake_hashes = Hashes1}; ignore -> State; - #alert{} = Alert -> + #alert{} = Alert -> handle_own_alert(Alert, Version, certify, State) end; @@ -1186,18 +1204,19 @@ verify_client_cert(#state{client_certificate_requested = false} = State) -> State. do_server_hello(Type, #state{negotiated_version = Version, - session = Session, + session = #session{session_id = SessId} = Session, connection_states = ConnectionStates0, renegotiation = {Renegotiation, _}} = State0) when is_atom(Type) -> + ServerHello = - ssl_handshake:server_hello(Session#session.session_id, Version, + ssl_handshake:server_hello(SessId, Version, ConnectionStates0, Renegotiation), State1 = server_hello(ServerHello, State0), case Type of new -> - do_server_hello(ServerHello, State1); + new_server_hello(ServerHello, State1); resumed -> ConnectionStates1 = State1#state.connection_states, case ssl_handshake:master_secret(Version, Session, @@ -1216,9 +1235,9 @@ do_server_hello(Type, #state{negotiated_version = Version, handle_own_alert(Alert, Version, hello, State1), {stop, normal, State1} end - end; + end. -do_server_hello(#server_hello{cipher_suite = CipherSuite, +new_server_hello(#server_hello{cipher_suite = CipherSuite, compression_method = Compression, session_id = SessionId}, #state{session = Session0, @@ -1343,7 +1362,7 @@ certify_server(#state{transport_cb = Transport, key_exchange(#state{role = server, key_algorithm = rsa} = State) -> State; key_exchange(#state{role = server, key_algorithm = Algo, - diffie_hellman_params = Params, + diffie_hellman_params = #'DHParameter'{prime = P, base = G} = Params, private_key = PrivateKey, connection_states = ConnectionStates0, negotiated_version = Version, @@ -1354,7 +1373,7 @@ key_exchange(#state{role = server, key_algorithm = Algo, when Algo == dhe_dss; Algo == dhe_rsa -> - Keys = public_key:gen_key(Params), + Keys = crypto:dh_generate_key([crypto:mpint(P), crypto:mpint(G)]), ConnectionState = ssl_record:pending_connection_state(ConnectionStates0, read), SecParams = ConnectionState#connection_state.security_parameters, @@ -1406,6 +1425,8 @@ key_exchange(#state{role = client, State#state{connection_states = ConnectionStates1, tls_handshake_hashes = Hashes1}. +-spec(rsa_key_exchange/2 :: (_,_) -> no_return()). + rsa_key_exchange(PremasterSecret, PublicKeyInfo = {Algorithm, _, _}) when Algorithm == ?rsaEncryption; Algorithm == ?md2WithRSAEncryption; @@ -1536,7 +1557,7 @@ verify_dh_params(Signed, Hashes, {?rsaEncryption, PubKey, _PubKeyParams}) -> false end; verify_dh_params(Signed, Hash, {?'id-dsa', PublicKey, PublicKeyParams}) -> - public_key:verify_signature(Hash, none, Signed, PublicKey, PublicKeyParams). + public_key:verify(Hash, none, Signed, {PublicKey, PublicKeyParams}). cipher_role(client, Data, Session, #state{connection_states = ConnectionStates0} = State) -> @@ -1563,7 +1584,7 @@ encode_change_cipher(#change_cipher_spec{}, Version, ConnectionStates) -> ssl_record:encode_change_cipher_spec(Version, ConnectionStates). encode_handshake(HandshakeRec, Version, ConnectionStates, Hashes) -> - encode_handshake(HandshakeRec, undefined, Version, + encode_handshake(HandshakeRec, null, Version, ConnectionStates, Hashes). encode_handshake(HandshakeRec, SigAlg, Version, ConnectionStates0, Hashes0) -> @@ -1626,8 +1647,6 @@ application_data(Data, #state{user_application = {_Mon, Pid}, true -> <<Buffer0/binary, Data/binary>> end, case get_data(SOpts, BytesToRead, Buffer1) of - {ok, <<>>, Buffer} -> % no reply, we need more data - next_record(State0#state{user_data_buffer = Buffer}); {ok, ClientData, Buffer} -> % Send data SocketOpt = deliver_app_data(SOpts, ClientData, Pid, From), State = State0#state{user_data_buffer = Buffer, @@ -1643,12 +1662,16 @@ application_data(Data, #state{user_application = {_Mon, Pid}, true -> %% We have more data application_data(<<>>, State) end; + {more, Buffer} -> % no reply, we need more data + next_record(State0#state{user_data_buffer = Buffer}); {error,_Reason} -> %% Invalid packet in packet mode deliver_packet_error(SOpts, Buffer1, Pid, From), {stop, normal, State0} end. %% Picks ClientData +get_data(_, _, <<>>) -> + {more, <<>>}; get_data(#socket_options{active=Active, packet=Raw}, BytesToRead, Buffer) when Raw =:= raw; Raw =:= 0 -> %% Raw Mode if @@ -1661,13 +1684,13 @@ get_data(#socket_options{active=Active, packet=Raw}, BytesToRead, Buffer) {ok, Data, Rest}; true -> %% Passive Mode not enough data - {ok, <<>>, Buffer} + {more, Buffer} end; get_data(#socket_options{packet=Type, packet_size=Size}, _, Buffer) -> PacketOpts = [{packet_size, Size}], case decode_packet(Type, Buffer, PacketOpts) of {more, _} -> - {ok, <<>>, Buffer}; + {more, Buffer}; Decoded -> Decoded end. @@ -1726,11 +1749,13 @@ format_packet_error(#socket_options{active = _, mode = Mode}, Data) -> format_reply(binary, _, N, Data) when N > 0 -> % Header mode header(N, Data); -format_reply(binary, _, _, Data) -> Data; -format_reply(list, Packet, _, Data) when is_integer(Packet); Packet == raw -> - binary_to_list(Data); +format_reply(binary, _, _, Data) -> + Data; +format_reply(list, Packet, _, Data) + when Packet == http; Packet == {http, headers}; Packet == http_bin; Packet == {http_bin, headers} -> + Data; format_reply(list, _,_, Data) -> - Data. + binary_to_list(Data). header(0, <<>>) -> <<>>; @@ -1780,9 +1805,7 @@ next_state(Next, #ssl_tls{type = ?ALERT, fragment = EncAlerts}, State) -> handle_alerts(Alerts, {next_state, Next, State}); next_state(StateName, #ssl_tls{type = ?HANDSHAKE, fragment = Data}, - State0 = #state{key_algorithm = KeyAlg, - tls_handshake_buffer = Buf0, - negotiated_version = Version}) -> + State0 = #state{tls_handshake_buffer = Buf0, negotiated_version = Version}) -> Handle = fun({#hello_request{} = Packet, _}, {next_state, connection = SName, State}) -> %% This message should not be included in handshake @@ -1805,7 +1828,7 @@ next_state(StateName, #ssl_tls{type = ?HANDSHAKE, fragment = Data}, (_, StopState) -> StopState end, try - {Packets, Buf} = ssl_handshake:get_tls_handshake(Data,Buf0, KeyAlg,Version), + {Packets, Buf} = ssl_handshake:get_tls_handshake(Data,Buf0), State = State0#state{tls_packets = Packets, tls_handshake_buffer = Buf}, handle_tls_handshake(Handle, StateName, State) catch throw:#alert{} = Alert -> @@ -1817,7 +1840,7 @@ next_state(StateName, #ssl_tls{type = ?APPLICATION_DATA, fragment = Data}, State case application_data(Data, State0) of Stop = {stop,_,_} -> Stop; - {Record, State} -> + {Record, State} -> next_state(StateName, Record, State) end; next_state(StateName, #ssl_tls{type = ?CHANGE_CIPHER_SPEC, fragment = <<1>>} = @@ -2154,7 +2177,7 @@ renegotiate(#state{role = server, negotiated_version = Version, connection_states = ConnectionStates0} = State0) -> HelloRequest = ssl_handshake:hello_request(), - Frag = ssl_handshake:encode_handshake(HelloRequest, Version, undefined), + Frag = ssl_handshake:encode_handshake(HelloRequest, Version, null), Hs0 = ssl_handshake:init_hashes(), {BinMsg, ConnectionStates} = ssl_record:encode_handshake(Frag, Version, ConnectionStates0), diff --git a/lib/ssl/src/ssl_handshake.erl b/lib/ssl/src/ssl_handshake.erl index fcc30f6137..99bc47f04b 100644 --- a/lib/ssl/src/ssl_handshake.erl +++ b/lib/ssl/src/ssl_handshake.erl @@ -31,32 +31,32 @@ -include("ssl_debug.hrl"). -include_lib("public_key/include/public_key.hrl"). --export([master_secret/4, client_hello/6, server_hello/4, hello/4, - hello_request/0, certify/7, certificate/3, - client_certificate_verify/6, - certificate_verify/6, certificate_request/2, - key_exchange/2, server_key_exchange_hash/2, finished/4, - verify_connection/5, - get_tls_handshake/4, - server_hello_done/0, sig_alg/1, - encode_handshake/3, init_hashes/0, - update_hashes/2, decrypt_premaster_secret/2]). - --type tls_handshake() :: #client_hello{} | #server_hello{} | #server_hello_done{} | -#certificate{} | #client_key_exchange{} | #finished{} | #certificate_verify{}. +-export([master_secret/4, client_hello/5, server_hello/4, hello/4, + hello_request/0, certify/6, certificate/3, + client_certificate_verify/6, certificate_verify/6, + certificate_request/2, key_exchange/2, server_key_exchange_hash/2, + finished/4, verify_connection/5, get_tls_handshake/2, + decode_client_key/3, server_hello_done/0, sig_alg/1, + encode_handshake/3, init_hashes/0, update_hashes/2, + decrypt_premaster_secret/2]). + +-type tls_handshake() :: #client_hello{} | #server_hello{} | + #server_hello_done{} | #certificate{} | #certificate_request{} | + #client_key_exchange{} | #finished{} | #certificate_verify{} | + #hello_request{}. %%==================================================================== %% Internal application API %%==================================================================== %%-------------------------------------------------------------------- -spec client_hello(host(), port_num(), #connection_states{}, - #ssl_options{}, binary(), boolean()) -> #client_hello{}. + #ssl_options{}, boolean()) -> #client_hello{}. %% %% Description: Creates a client hello message. %%-------------------------------------------------------------------- client_hello(Host, Port, ConnectionStates, #ssl_options{versions = Versions, ciphers = UserSuites} - = SslOpts, Cert, Renegotiation) -> + = SslOpts, Renegotiation) -> Fun = fun(Version) -> ssl_record:protocol_version(Version) @@ -64,7 +64,7 @@ client_hello(Host, Port, ConnectionStates, #ssl_options{versions = Versions, Version = ssl_record:highest_protocol_version(lists:map(Fun, Versions)), Pending = ssl_record:pending_connection_state(ConnectionStates, read), SecParams = Pending#connection_state.security_parameters, - Ciphers = available_suites(Cert, UserSuites, Version), + Ciphers = available_suites(UserSuites, Version), Id = ssl_manager:client_session_id(Host, Port, SslOpts), @@ -110,7 +110,7 @@ hello_request() -> #connection_states{} | {port_num(), #session{}, cache_ref(), atom(), #connection_states{}, binary()}, boolean()) -> {tls_version(), session_id(), #connection_states{}}| - {tls_version(), {resumed | new, session_id()}, + {tls_version(), {resumed | new, #session{}}, #connection_states{}} | #alert{}. %% %% Description: Handles a recieved hello message @@ -175,64 +175,57 @@ hello(#client_hello{client_version = ClientVersion, random = Random, %%-------------------------------------------------------------------- -spec certify(#certificate{}, term(), integer() | nolimit, - verify_peer | verify_none, fun(), fun(), + 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}, CertDbRef, - MaxPathLen, Verify, VerifyFun, ValidateFun, Role) -> +certify(#certificate{asn1_certificates = ASN1Certs}, CertDbRef, + MaxPathLen, _Verify, VerifyFunAndState, Role) -> [PeerCert | _] = ASN1Certs, - VerifyBool = verify_bool(Verify), - ValidateExtensionFun = - case ValidateFun of + ValidationFunAndState = + case VerifyFunAndState of undefined -> - fun(Extensions, ValidationState, Verify0, AccError) -> - ssl_certificate:validate_extensions(Extensions, ValidationState, - [], Verify0, AccError, Role) - end; - Fun -> - fun(Extensions, ValidationState, Verify0, AccError) -> - {NewExtensions, NewValidationState, NewAccError} - = ssl_certificate:validate_extensions(Extensions, ValidationState, - [], Verify0, AccError, Role), - Fun(NewExtensions, NewValidationState, Verify0, NewAccError) - end + {fun(OtpCert, ExtensionOrError, SslState) -> + ssl_certificate:validate_extension(OtpCert, + ExtensionOrError, SslState) + end, Role}; + {Fun, UserState0} -> + {fun(OtpCert, ExtensionOrError, {SslState, UserState}) -> + case ssl_certificate:validate_extension(OtpCert, + ExtensionOrError, + SslState) of + {valid, _} -> + apply_user_fun(Fun, OtpCert, + ExtensionOrError, UserState, + SslState); + {fail, Reason} -> + apply_user_fun(Fun, OtpCert, Reason, UserState, + SslState); + {unknown, _} -> + apply_user_fun(Fun, OtpCert, + ExtensionOrError, UserState, SslState) + end + end, {Role, UserState0}} end, - try - %% Allow missing root_cert and check that with VerifyFun - ssl_certificate:trusted_cert_and_path(ASN1Certs, CertDbRef, false) of - {TrustedErlCert, CertPath, VerifyErrors} -> - Result = public_key:pkix_path_validation(TrustedErlCert, - CertPath, - [{max_path_length, - MaxPathLen}, - {verify, VerifyBool}, - {validate_extensions_fun, - ValidateExtensionFun}, - {acc_errors, - VerifyErrors}]), - case Result of - {error, Reason} -> - path_validation_alert(Reason, Verify); - {ok, {PublicKeyInfo,_, []}} -> - {PeerCert, PublicKeyInfo}; - {ok, {PublicKeyInfo,_, AccErrors = [Error | _]}} -> - case VerifyFun(AccErrors) of - true -> - {PeerCert, PublicKeyInfo}; - false -> - path_validation_alert(Error, Verify) - end - end - catch - throw:Alert -> - Alert + + {TrustedErlCert, CertPath} = + ssl_certificate:trusted_cert_and_path(ASN1Certs, 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. - + %%-------------------------------------------------------------------- --spec certificate(der_cert(), term(), client | server) -> #certificate{}. +-spec certificate(der_cert(), term(), client | server) -> #certificate{} | #alert{}. %% %% Description: Creates a certificate message. %%-------------------------------------------------------------------- @@ -260,8 +253,8 @@ certificate(OwnCert, CertDbRef, server) -> %%-------------------------------------------------------------------- -spec client_certificate_verify(undefined | der_cert(), binary(), tls_version(), key_algo(), private_key(), - {binary(), binary()}) -> - #certificate_verify{} | ignore. + {{binary(), binary()},{binary(), binary()}}) -> + #certificate_verify{} | ignore | #alert{}. %% %% Description: Creates a certificate_verify message, called by the client. %%-------------------------------------------------------------------- @@ -283,9 +276,9 @@ client_certificate_verify(OwnCert, MasterSecret, Version, Algorithm, end. %%-------------------------------------------------------------------- --spec certificate_verify(binary(), public_key_info(), tls_version(), - binary(), key_algo(), - {binary(), binary()}) -> valid | #alert{}. +%% -spec certificate_verify(binary(), public_key_info(), tls_version(), +%% binary(), key_algo(), +%% {_, {binary(), binary()}}) -> valid | #alert{}. %% %% Description: Checks that the certificate_verify message is valid. %%-------------------------------------------------------------------- @@ -306,7 +299,7 @@ certificate_verify(Signature, {_, PublicKey, PublicKeyParams}, Version, MasterSecret, dhe_dss = Algorithm, {_, Hashes0}) -> Hashes = calc_certificate_verify(Version, MasterSecret, Algorithm, Hashes0), - case public_key:verify_signature(Hashes, none, Signature, PublicKey, PublicKeyParams) of + case public_key:verify(Hashes, none, Signature, {PublicKey, PublicKeyParams}) of true -> valid; false -> @@ -335,7 +328,7 @@ certificate_request(ConnectionStates, CertDbRef) -> -spec key_exchange(client | server, {premaster_secret, binary(), public_key_info()} | {dh, binary()} | - {dh, binary(), #'DHParameter'{}, key_algo(), + {dh, {binary(), binary()}, #'DHParameter'{}, key_algo(), binary(), binary(), private_key()}) -> #client_key_exchange{} | #server_key_exchange{}. %% @@ -412,7 +405,7 @@ master_secret(Version, PremasterSecret, ConnectionStates, Role) -> end. %%-------------------------------------------------------------------- --spec finished(tls_version(), client | server, binary(), {binary(), binary()}) -> +-spec finished(tls_version(), client | server, binary(), {{binary(), binary()},_}) -> #finished{}. %% %% Description: Creates a handshake finished message @@ -423,7 +416,7 @@ finished(Version, Role, MasterSecret, {Hashes, _}) -> % use the current hashes %%-------------------------------------------------------------------- -spec verify_connection(tls_version(), #finished{}, client | server, binary(), - {binary(), binary()}) -> verified | #alert{}. + {_, {binary(), binary()}}) -> verified | #alert{}. %% %% Description: Checks the ssl handshake finished message to verify %% the connection. @@ -448,7 +441,7 @@ server_hello_done() -> #server_hello_done{}. %%-------------------------------------------------------------------- --spec encode_handshake(tls_handshake(), tls_version(), key_algo()) -> binary(). +-spec encode_handshake(tls_handshake(), tls_version(), key_algo()) -> iolist(). %% %% Description: Encode a handshake packet to binary %%-------------------------------------------------------------------- @@ -459,49 +452,53 @@ encode_handshake(Package, Version, KeyAlg) -> [MsgType, ?uint24(Len), Bin]. %%-------------------------------------------------------------------- --spec get_tls_handshake(binary(), binary(), key_algo(), tls_version()) -> - {[tls_handshake()], [binary()], binary()}. +-spec get_tls_handshake(binary(), binary() | iolist()) -> + {[tls_handshake()], binary()}. %% %% Description: Given buffered and new data from ssl_record, collects %% and returns it as a list of handshake messages, also returns leftover %% data. %%-------------------------------------------------------------------- -get_tls_handshake(Data, <<>>, KeyAlg, Version) -> - get_tls_handshake_aux(Data, KeyAlg, Version, []); -get_tls_handshake(Data, Buffer, KeyAlg, Version) -> - get_tls_handshake_aux(list_to_binary([Buffer, Data]), - KeyAlg, Version, []). +get_tls_handshake(Data, <<>>) -> + get_tls_handshake_aux(Data, []); +get_tls_handshake(Data, Buffer) -> + get_tls_handshake_aux(list_to_binary([Buffer, Data]), []). + +%%-------------------------------------------------------------------- +-spec decode_client_key(binary(), key_algo(), tls_version()) -> + #encrypted_premaster_secret{} | #client_diffie_hellman_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). %%-------------------------------------------------------------------- %%% Internal functions %%-------------------------------------------------------------------- get_tls_handshake_aux(<<?BYTE(Type), ?UINT24(Length), - Body:Length/binary,Rest/binary>>, KeyAlg, - Version, Acc) -> + Body:Length/binary,Rest/binary>>, Acc) -> Raw = <<?BYTE(Type), ?UINT24(Length), Body/binary>>, - H = dec_hs(Type, Body, key_exchange_alg(KeyAlg), Version), - get_tls_handshake_aux(Rest, KeyAlg, Version, [{H,Raw} | Acc]); -get_tls_handshake_aux(Data, _KeyAlg, _Version, Acc) -> + H = dec_hs(Type, Body), + get_tls_handshake_aux(Rest, [{H,Raw} | Acc]); +get_tls_handshake_aux(Data, Acc) -> {lists:reverse(Acc), Data}. -verify_bool(verify_peer) -> - true; -verify_bool(verify_none) -> - false. - -path_validation_alert({bad_cert, cert_expired}, _) -> +path_validation_alert({bad_cert, cert_expired}) -> ?ALERT_REC(?FATAL, ?CERTIFICATE_EXPIRED); -path_validation_alert({bad_cert, invalid_issuer}, _) -> +path_validation_alert({bad_cert, invalid_issuer}) -> ?ALERT_REC(?FATAL, ?BAD_CERTIFICATE); -path_validation_alert({bad_cert, invalid_signature} , _) -> +path_validation_alert({bad_cert, invalid_signature}) -> ?ALERT_REC(?FATAL, ?BAD_CERTIFICATE); -path_validation_alert({bad_cert, name_not_permitted}, _) -> +path_validation_alert({bad_cert, name_not_permitted}) -> ?ALERT_REC(?FATAL, ?BAD_CERTIFICATE); -path_validation_alert({bad_cert, unknown_critical_extension}, _) -> +path_validation_alert({bad_cert, unknown_critical_extension}) -> ?ALERT_REC(?FATAL, ?UNSUPPORTED_CERTIFICATE); -path_validation_alert({bad_cert, cert_revoked}, _) -> +path_validation_alert({bad_cert, cert_revoked}) -> ?ALERT_REC(?FATAL, ?CERTIFICATE_REVOKED); -path_validation_alert(_, _) -> +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, @@ -524,13 +521,16 @@ select_session(Hello, Port, Session, Version, {resumed, CacheCb:lookup(Cache, {Port, SessionId})} end. -available_suites(Cert, UserSuites, Version) -> +available_suites(UserSuites, Version) -> case UserSuites of [] -> - ssl_cipher:filter(Cert, ssl_cipher:suites(Version)); + ssl_cipher:suites(Version); _ -> - ssl_cipher:filter(Cert, UserSuites) + 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]; @@ -724,7 +724,7 @@ master_secret(Version, MasterSecret, #security_parameters{ ServerCipherState, Role)}. -dec_hs(?HELLO_REQUEST, <<>>, _, _) -> +dec_hs(?HELLO_REQUEST, <<>>) -> #hello_request{}; %% Client hello v2. @@ -734,8 +734,7 @@ dec_hs(?CLIENT_HELLO, <<?BYTE(Major), ?BYTE(Minor), ?UINT16(CSLength), ?UINT16(0), ?UINT16(CDLength), CipherSuites:CSLength/binary, - ChallengeData:CDLength/binary>>, - _, _) -> + ChallengeData:CDLength/binary>>) -> ?DBG_HEX(CipherSuites), ?DBG_HEX(CipherSuites), #client_hello{client_version = {Major, Minor}, @@ -749,8 +748,7 @@ dec_hs(?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>>, - _, _) -> + Extensions/binary>>) -> RenegotiationInfo = proplists:get_value(renegotiation_info, dec_hello_extensions(Extensions), undefined), @@ -765,7 +763,7 @@ dec_hs(?CLIENT_HELLO, <<?BYTE(Major), ?BYTE(Minor), Random:32/binary, dec_hs(?SERVER_HELLO, <<?BYTE(Major), ?BYTE(Minor), Random:32/binary, ?BYTE(SID_length), Session_ID:SID_length/binary, - Cipher_suite:2/binary, ?BYTE(Comp_method)>>, _, _) -> + Cipher_suite:2/binary, ?BYTE(Comp_method)>>) -> #server_hello{ server_version = {Major,Minor}, random = Random, @@ -777,7 +775,7 @@ dec_hs(?SERVER_HELLO, <<?BYTE(Major), ?BYTE(Minor), Random:32/binary, dec_hs(?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>>, _, _) -> + ?UINT16(ExtLen), Extensions:ExtLen/binary>>) -> RenegotiationInfo = proplists:get_value(renegotiation_info, dec_hello_extensions(Extensions, []), undefined), @@ -788,44 +786,42 @@ dec_hs(?SERVER_HELLO, <<?BYTE(Major), ?BYTE(Minor), Random:32/binary, cipher_suite = Cipher_suite, compression_method = Comp_method, renegotiation_info = RenegotiationInfo}; -dec_hs(?CERTIFICATE, <<?UINT24(ACLen), ASN1Certs:ACLen/binary>>, _, _) -> +dec_hs(?CERTIFICATE, <<?UINT24(ACLen), ASN1Certs:ACLen/binary>>) -> #certificate{asn1_certificates = certs_to_list(ASN1Certs)}; dec_hs(?SERVER_KEY_EXCHANGE, <<?UINT16(PLen), P:PLen/binary, ?UINT16(GLen), G:GLen/binary, ?UINT16(YLen), Y:YLen/binary, - ?UINT16(Len), Sig:Len/binary>>, - ?KEY_EXCHANGE_DIFFIE_HELLMAN, _) -> + ?UINT16(Len), Sig:Len/binary>>) -> #server_key_exchange{params = #server_dh_params{dh_p = P,dh_g = G, dh_y = Y}, signed_params = Sig}; dec_hs(?CERTIFICATE_REQUEST, <<?BYTE(CertTypesLen), CertTypes:CertTypesLen/binary, - ?UINT16(CertAuthsLen), CertAuths:CertAuthsLen/binary>>, _, _) -> + ?UINT16(CertAuthsLen), CertAuths:CertAuthsLen/binary>>) -> #certificate_request{certificate_types = CertTypes, certificate_authorities = CertAuths}; -dec_hs(?SERVER_HELLO_DONE, <<>>, _, _) -> +dec_hs(?SERVER_HELLO_DONE, <<>>) -> #server_hello_done{}; -dec_hs(?CERTIFICATE_VERIFY,<<?UINT16(_), Signature/binary>>, _, _)-> +dec_hs(?CERTIFICATE_VERIFY,<<?UINT16(_), Signature/binary>>)-> #certificate_verify{signature = Signature}; -dec_hs(?CLIENT_KEY_EXCHANGE, PKEPMS, ?KEY_EXCHANGE_RSA, {3, 0}) -> - PreSecret = #encrypted_premaster_secret{premaster_secret = PKEPMS}, - #client_key_exchange{exchange_keys = PreSecret}; -dec_hs(?CLIENT_KEY_EXCHANGE, <<?UINT16(_), PKEPMS/binary>>, - ?KEY_EXCHANGE_RSA, _) -> - PreSecret = #encrypted_premaster_secret{premaster_secret = PKEPMS}, - #client_key_exchange{exchange_keys = PreSecret}; -dec_hs(?CLIENT_KEY_EXCHANGE, <<>>, ?KEY_EXCHANGE_DIFFIE_HELLMAN, _) -> - throw(?ALERT_REC(?FATAL, ?UNSUPPORTED_CERTIFICATE)); -dec_hs(?CLIENT_KEY_EXCHANGE, <<?UINT16(DH_YLen), DH_Y:DH_YLen/binary>>, - ?KEY_EXCHANGE_DIFFIE_HELLMAN, _) -> - #client_key_exchange{exchange_keys = - #client_diffie_hellman_public{dh_public = DH_Y}}; -dec_hs(?FINISHED, VerifyData, _, _) -> +dec_hs(?CLIENT_KEY_EXCHANGE, PKEPMS) -> + #client_key_exchange{exchange_keys = PKEPMS}; +dec_hs(?FINISHED, VerifyData) -> #finished{verify_data = VerifyData}; -dec_hs(_, _, _, _) -> +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_hello_extensions(<<>>) -> []; dec_hello_extensions(<<?UINT16(ExtLen), Extensions:ExtLen/binary>>) -> @@ -1042,9 +1038,10 @@ certificate_authorities(CertDbRef) -> Authorities = certificate_authorities_from_db(CertDbRef), Enc = fun(#'OTPCertificate'{tbsCertificate=TBSCert}) -> OTPSubj = TBSCert#'OTPTBSCertificate'.subject, - Subj = public_key:pkix_transform(OTPSubj, encode), - {ok, DNEncoded} = 'OTP-PUB-KEY':encode('Name', Subj), - DNEncodedBin = iolist_to_binary(DNEncoded), + DNEncodedBin = public_key:pkix_encode('Name', OTPSubj, otp), + %%Subj = public_key:pkix_transform(OTPSubj, encode), + %% {ok, DNEncoded} = 'OTP-PUB-KEY':encode('Name', Subj), + %% DNEncodedBin = iolist_to_binary(DNEncoded), DNEncodedLen = byte_size(DNEncodedBin), <<?UINT16(DNEncodedLen), DNEncodedBin/binary>> end, @@ -1068,7 +1065,7 @@ digitally_signed(Hash, #'RSAPrivateKey'{} = Key) -> public_key:encrypt_private(Hash, Key, [{rsa_pad, rsa_pkcs1_padding}]); digitally_signed(Hash, #'DSAPrivateKey'{} = Key) -> - public_key:sign(none, Hash, Key). + public_key:sign(Hash, none, Key). calc_master_secret({3,0}, PremasterSecret, ClientRandom, ServerRandom) -> ssl_ssl3:master_secret(PremasterSecret, ClientRandom, ServerRandom); @@ -1120,7 +1117,17 @@ sig_alg(_) -> 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 -> + Alg == dh_dss; Alg == dh_rsa -> ?KEY_EXCHANGE_DIFFIE_HELLMAN; 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}} + end. diff --git a/lib/ssl/src/ssl_internal.hrl b/lib/ssl/src/ssl_internal.hrl index ddace02dea..3862dc75de 100644 --- a/lib/ssl/src/ssl_internal.hrl +++ b/lib/ssl/src/ssl_internal.hrl @@ -63,9 +63,11 @@ validate_extensions_fun, depth, % integer() certfile, % file() + cert, % der_encoded() keyfile, % file() - key, % + key, % der_encoded() password, % + cacerts, % [der_encoded()] cacertfile, % file() dhfile, % file() ciphers, % @@ -96,12 +98,12 @@ -type from() :: term(). -type host() :: string() | tuple(). -type port_num() :: integer(). --type session_id() :: binary(). +-type session_id() :: 0 | binary(). -type tls_version() :: {integer(), integer()}. -type tls_atom_version() :: sslv3 | tlsv1. -type cache_ref() :: term(). -type certdb_ref() :: term(). --type key_algo() :: rsa | dhe_rsa | dhe_dss. +-type key_algo() :: null | rsa | dhe_rsa | dhe_dss. -type enum_algo() :: integer(). -type public_key() :: #'RSAPublicKey'{} | integer(). -type public_key_params() :: #'Dss-Parms'{} | term(). diff --git a/lib/ssl/src/ssl_manager.erl b/lib/ssl/src/ssl_manager.erl index af30f78dbf..0116466677 100644 --- a/lib/ssl/src/ssl_manager.erl +++ b/lib/ssl/src/ssl_manager.erl @@ -29,7 +29,8 @@ %% Internal application API -export([start_link/1, connection_init/2, cache_pem_file/1, - lookup_trusted_cert/3, issuer_candidate/1, client_session_id/3, server_session_id/3, + lookup_trusted_cert/3, issuer_candidate/1, client_session_id/3, + server_session_id/3, register_session/2, register_session/3, invalidate_session/2, invalidate_session/3]). @@ -68,12 +69,12 @@ start_link(Opts) -> gen_server:start_link({local, ?MODULE}, ?MODULE, [Opts], []). %%-------------------------------------------------------------------- --spec connection_init(string(), client | server) -> {ok, reference(), cache_ref()}. +-spec connection_init(string()| {der, list()}, client | server) -> {ok, reference(), cache_ref()}. %% %% Description: Do necessary initializations for a new connection. %%-------------------------------------------------------------------- -connection_init(TrustedcertsFile, Role) -> - call({connection_init, TrustedcertsFile, Role}). +connection_init(Trustedcerts, Role) -> + call({connection_init, Trustedcerts, Role}). %%-------------------------------------------------------------------- -spec cache_pem_file(string()) -> {ok, term()}. %% @@ -88,14 +89,17 @@ cache_pem_file(File) -> end. %%-------------------------------------------------------------------- -spec lookup_trusted_cert(reference(), serialnumber(), issuer()) -> - {der_cert(), #'OTPCertificate'{}}. + undefined | + {ok, {der_cert(), #'OTPCertificate'{}}}. %% -%% Description: Lookup the trusted cert with Key = {reference(), serialnumber(), issuer()}. -%%-------------------------------------------------------------------- +%% Description: Lookup the trusted cert with Key = {reference(), +%% serialnumber(), issuer()}. +%% -------------------------------------------------------------------- lookup_trusted_cert(Ref, SerialNumber, Issuer) -> ssl_certificate_db:lookup_trusted_cert(Ref, SerialNumber, Issuer). %%-------------------------------------------------------------------- --spec issuer_candidate(cert_key()) -> {cert_key(), der_cert()} | no_more_candidates. +-spec issuer_candidate(cert_key() | no_candidate) -> + {cert_key(), {der_cert(), #'OTPCertificate'{}}} | no_more_candidates. %% %% Description: Return next issuer candidate. %%-------------------------------------------------------------------- @@ -143,8 +147,9 @@ invalidate_session(Port, Session) -> %%==================================================================== %%-------------------------------------------------------------------- --spec init(list()) -> {ok, #state{}} | {ok, #state{}, timeout()} | - ignore | {stop, term()}. +-spec init(list()) -> {ok, #state{}}. +%% Possible return values not used now. +%% | {ok, #state{}, timeout()} | ignore | {stop, term()}. %% %% Description: Initiates the server %%-------------------------------------------------------------------- @@ -164,12 +169,13 @@ init([Opts]) -> session_validation_timer = Timer}}. %%-------------------------------------------------------------------- --spec handle_call(msg(), from(), #state{}) -> {reply, reply(), #state{}} | - {reply, reply(), #state{}, timeout()} | - {noreply, #state{}} | - {noreply, #state{}, timeout()} | - {stop, reason(), reply(), #state{}} | - {stop, reason(), #state{}}. +-spec handle_call(msg(), from(), #state{}) -> {reply, reply(), #state{}}. +%% Possible return values not used now. +%% {reply, reply(), #state{}, timeout()} | +%% {noreply, #state{}} | +%% {noreply, #state{}, timeout()} | +%% {stop, reason(), reply(), #state{}} | +%% {stop, reason(), #state{}}. %% %% Description: Handling call messages %%-------------------------------------------------------------------- @@ -179,13 +185,13 @@ handle_call({{connection_init, "", _Role}, Pid}, _From, Result = {ok, make_ref(), Cache}, {reply, Result, State}; -handle_call({{connection_init, TrustedcertsFile, _Role}, Pid}, _From, +handle_call({{connection_init, Trustedcerts, _Role}, Pid}, _From, #state{certificate_db = Db, session_cache = Cache} = State) -> erlang:monitor(process, Pid), Result = try - {ok, Ref} = ssl_certificate_db:add_trusted_certs(Pid, TrustedcertsFile, Db), + {ok, Ref} = ssl_certificate_db:add_trusted_certs(Pid, Trustedcerts, Db), {ok, Ref, Cache} catch _:Reason -> @@ -216,9 +222,10 @@ handle_call({{cache_pem, File},Pid}, _, State = #state{certificate_db = Db}) -> {reply, {error, Reason}, State} end. %%-------------------------------------------------------------------- --spec handle_cast(msg(), #state{}) -> {noreply, #state{}} | - {noreply, #state{}, timeout()} | - {stop, reason(), #state{}}. +-spec handle_cast(msg(), #state{}) -> {noreply, #state{}}. +%% Possible return values not used now. +%% | {noreply, #state{}, timeout()} | +%% {stop, reason(), #state{}}. %% %% Description: Handling cast messages %%-------------------------------------------------------------------- @@ -253,9 +260,10 @@ handle_cast({invalidate_session, Port, #session{session_id = ID}}, {noreply, State}. %%-------------------------------------------------------------------- --spec handle_info(msg(), #state{}) -> {noreply, #state{}} | - {noreply, #state{}, timeout()} | - {stop, reason(), #state{}}. +-spec handle_info(msg(), #state{}) -> {noreply, #state{}}. +%% Possible return values not used now. +%% |{noreply, #state{}, timeout()} | +%% {stop, reason(), #state{}}. %% %% Description: Handling all non call/cast messages %%-------------------------------------------------------------------- diff --git a/lib/ssl/src/ssl_record.erl b/lib/ssl/src/ssl_record.erl index 90615c22a1..acd0d49c19 100644 --- a/lib/ssl/src/ssl_record.erl +++ b/lib/ssl/src/ssl_record.erl @@ -149,7 +149,7 @@ set_mac_secret(ReadMacSecret, WriteMacSecret, %%-------------------------------------------------------------------- --spec set_master_secret(binary(), #connection_state{}) -> #connection_states{}. +-spec set_master_secret(binary(), #connection_states{}) -> #connection_states{}. %% %% Description: Set master_secret in pending connection states %%-------------------------------------------------------------------- @@ -306,7 +306,7 @@ set_pending_cipher_state(#connection_states{pending_read = Read, pending_write = Write#connection_state{cipher_state = ClientState}}. %%-------------------------------------------------------------------- --spec get_tls_records(binary(), binary()) -> {[binary()], binary()}. +-spec get_tls_records(binary(), binary()) -> {[binary()], binary()} | #alert{}. %% %% Description: Given old buffer and new data from TCP, packs up a records %% and returns it as a list of tls_compressed binaries also returns leftover @@ -372,7 +372,8 @@ get_tls_records_aux(Data, Acc) -> {lists:reverse(Acc), Data}. %%-------------------------------------------------------------------- --spec protocol_version(tls_atom_version()) -> tls_version(). +-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. @@ -467,7 +468,7 @@ is_acceptable_version(_) -> false. %%-------------------------------------------------------------------- --spec compressions() -> binary(). +-spec compressions() -> [binary()]. %% %% Description: return a list of compressions supported (currently none) %%-------------------------------------------------------------------- @@ -476,7 +477,7 @@ compressions() -> %%-------------------------------------------------------------------- -spec decode_cipher_text(#ssl_tls{}, #connection_states{}) -> - {#ssl_tls{}, #connection_states{}}. + {#ssl_tls{}, #connection_states{}}| #alert{}. %% %% Description: Decode cipher text %%-------------------------------------------------------------------- diff --git a/lib/ssl/src/ssl_session.erl b/lib/ssl/src/ssl_session.erl index e9755cb0e1..25e7445180 100644 --- a/lib/ssl/src/ssl_session.erl +++ b/lib/ssl/src/ssl_session.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2007-2009. All Rights Reserved. +%% Copyright Ericsson AB 2007-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 @@ -35,7 +35,7 @@ -type seconds() :: integer(). %%-------------------------------------------------------------------- --spec is_new(binary(), binary()) -> boolean(). +-spec is_new(session_id(), session_id()) -> boolean(). %% %% Description: Checks if the session id decided by the server is a %% new or resumed sesion id. @@ -113,7 +113,7 @@ select_session(Sessions, #ssl_options{ciphers = Ciphers, List -> hd(List) end. - + %% If we can not generate a not allready in use session ID in %% ?GEN_UNIQUE_ID_MAX_TRIES we make the new session uncacheable The %% value of ?GEN_UNIQUE_ID_MAX_TRIES is stolen from open SSL which diff --git a/lib/ssl/src/ssl_ssl3.erl b/lib/ssl/src/ssl_ssl3.erl index 375adf263a..1add203fb0 100644 --- a/lib/ssl/src/ssl_ssl3.erl +++ b/lib/ssl/src/ssl_ssl3.erl @@ -121,9 +121,10 @@ mac_hash(Method, Mac_write_secret, Seq_num, Type, Length, Fragment) -> ?DBG_HEX(Mac), Mac. --spec setup_keys(binary(), binary(), binary(), binary(), - integer(), integer(), binary()) -> {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, diff --git a/lib/ssl/src/ssl_sup.erl b/lib/ssl/src/ssl_sup.erl index b7cb5c3ab3..316ed8a4e9 100644 --- a/lib/ssl/src/ssl_sup.erl +++ b/lib/ssl/src/ssl_sup.erl @@ -32,14 +32,17 @@ %%%========================================================================= %%% API %%%========================================================================= + +-spec start_link() -> {ok, pid()} | ignore | {error, term()}. + start_link() -> supervisor:start_link({local, ?MODULE}, ?MODULE, []). %%%========================================================================= %%% Supervisor callback %%%========================================================================= -%% init([]) -> {ok, {SupFlags, [ChildSpec]}} -%% +-spec init([]) -> {ok, {SupFlags :: tuple(), [ChildSpec :: tuple()]}}. + init([]) -> %% OLD ssl - moved start to ssl.erl only if old %% ssl is acctualy run! diff --git a/lib/ssl/test/erl_make_certs.erl b/lib/ssl/test/erl_make_certs.erl index 1d2cea6c72..f8aef55754 100644 --- a/lib/ssl/test/erl_make_certs.erl +++ b/lib/ssl/test/erl_make_certs.erl @@ -56,7 +56,7 @@ make_cert(Opts) -> SubjectPrivateKey = get_key(Opts), {TBSCert, IssuerKey} = make_tbs(SubjectPrivateKey, Opts), - Cert = public_key:sign(TBSCert, IssuerKey), + Cert = public_key:pkix_sign(TBSCert, IssuerKey), true = verify_signature(Cert, IssuerKey, undef), %% verify that the keys where ok {Cert, encode_key(SubjectPrivateKey)}. @@ -66,8 +66,9 @@ make_cert(Opts) -> %% @end %%-------------------------------------------------------------------- write_pem(Dir, FileName, {Cert, Key = {_,_,not_encrypted}}) when is_binary(Cert) -> - ok = public_key:der_to_pem(filename:join(Dir, FileName ++ ".pem"), [{cert, Cert, not_encrypted}]), - ok = public_key:der_to_pem(filename:join(Dir, FileName ++ "_key.pem"), [Key]). + ok = der_to_pem(filename:join(Dir, FileName ++ ".pem"), + [{'Certificate', Cert, not_encrypted}]), + ok = der_to_pem(filename:join(Dir, FileName ++ "_key.pem"), [Key]). %%-------------------------------------------------------------------- %% @doc Creates a rsa key (OBS: for testing only) @@ -94,18 +95,14 @@ gen_dsa(LSize,NSize) when is_integer(LSize), is_integer(NSize) -> %% @spec (::binary(), ::tuple()) -> ::boolean() %% @end %%-------------------------------------------------------------------- -verify_signature(DerEncodedCert, DerKey, KeyParams) -> +verify_signature(DerEncodedCert, DerKey, _KeyParams) -> Key = decode_key(DerKey), case Key of #'RSAPrivateKey'{modulus=Mod, publicExponent=Exp} -> - public_key:verify_signature(DerEncodedCert, - #'RSAPublicKey'{modulus=Mod, publicExponent=Exp}, - 'NULL'); + public_key:pkix_verify(DerEncodedCert, + #'RSAPublicKey'{modulus=Mod, publicExponent=Exp}); #'DSAPrivateKey'{p=P, q=Q, g=G, y=Y} -> - public_key:verify_signature(DerEncodedCert, Y, #'Dss-Parms'{p=P, q=Q, g=G}); - - _ -> - public_key:verify_signature(DerEncodedCert, Key, KeyParams) + public_key:pkix_verify(DerEncodedCert, {Y, #'Dss-Parms'{p=P, q=Q, g=G}}) end. %%%%%%%%%%%%%%%%%%%%%%%%% Implementation %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -132,59 +129,63 @@ decode_key(#'RSAPrivateKey'{} = Key,_) -> Key; decode_key(#'DSAPrivateKey'{} = Key,_) -> Key; -decode_key(Der = {_,_,_}, Pw) -> - {ok, Key} = public_key:decode_private_key(Der, Pw), - Key; -decode_key(FileOrDer, Pw) -> - {ok, [KeyInfo]} = public_key:pem_to_der(FileOrDer), +decode_key(PemEntry = {_,_,_}, Pw) -> + public_key:pem_entry_decode(PemEntry, Pw); +decode_key(PemBin, Pw) -> + [KeyInfo] = public_key:pem_decode(PemBin), decode_key(KeyInfo, Pw). encode_key(Key = #'RSAPrivateKey'{}) -> {ok, Der} = 'OTP-PUB-KEY':encode('RSAPrivateKey', Key), - {rsa_private_key, list_to_binary(Der), not_encrypted}; + {'RSAPrivateKey', list_to_binary(Der), not_encrypted}; encode_key(Key = #'DSAPrivateKey'{}) -> {ok, Der} = 'OTP-PUB-KEY':encode('DSAPrivateKey', Key), - {dsa_private_key, list_to_binary(Der), not_encrypted}. + {'DSAPrivateKey', list_to_binary(Der), not_encrypted}. make_tbs(SubjectKey, Opts) -> Version = list_to_atom("v"++integer_to_list(proplists:get_value(version, Opts, 3))), - {Issuer, IssuerKey} = issuer(Opts, SubjectKey), + + IssuerProp = proplists:get_value(issuer, Opts, true), + {Issuer, IssuerKey} = issuer(IssuerProp, Opts, SubjectKey), {Algo, Parameters} = sign_algorithm(IssuerKey, Opts), SignAlgo = #'SignatureAlgorithm'{algorithm = Algo, parameters = Parameters}, - + Subject = case IssuerProp of + true -> %% Is a Root Ca + Issuer; + _ -> + subject(proplists:get_value(subject, Opts),false) + end, + {#'OTPTBSCertificate'{serialNumber = trunc(random:uniform()*100000000)*10000 + 1, signature = SignAlgo, issuer = Issuer, validity = validity(Opts), - subject = subject(proplists:get_value(subject, Opts),false), + subject = Subject, subjectPublicKeyInfo = publickey(SubjectKey), version = Version, extensions = extensions(Opts) }, IssuerKey}. -issuer(Opts, SubjectKey) -> - IssuerProp = proplists:get_value(issuer, Opts, true), - case IssuerProp of - true -> %% Self signed - {subject(proplists:get_value(subject, Opts), true), SubjectKey}; - {Issuer, IssuerKey} when is_binary(Issuer) -> - {issuer_der(Issuer), decode_key(IssuerKey)}; - {File, IssuerKey} when is_list(File) -> - {ok, [{cert, Cert, _}|_]} = public_key:pem_to_der(File), - {issuer_der(Cert), decode_key(IssuerKey)} - end. +issuer(true, Opts, SubjectKey) -> + %% Self signed + {subject(proplists:get_value(subject, Opts), true), SubjectKey}; +issuer({Issuer, IssuerKey}, _Opts, _SubjectKey) when is_binary(Issuer) -> + {issuer_der(Issuer), decode_key(IssuerKey)}; +issuer({File, IssuerKey}, _Opts, _SubjectKey) when is_list(File) -> + {ok, [{cert, Cert, _}|_]} = public_key:pem_to_der(File), + {issuer_der(Cert), decode_key(IssuerKey)}. issuer_der(Issuer) -> - {ok, Decoded} = public_key:pkix_decode_cert(Issuer, otp), + Decoded = public_key:pkix_decode_cert(Issuer, otp), #'OTPCertificate'{tbsCertificate=Tbs} = Decoded, #'OTPTBSCertificate'{subject=Subject} = Tbs, Subject. -subject(undefined, IsCA) -> - User = if IsCA -> "CA"; true -> os:getenv("USER") end, +subject(undefined, IsRootCA) -> + User = if IsRootCA -> "RootCA"; true -> os:getenv("USER") end, Opts = [{email, User ++ "@erlang.org"}, {name, User}, {city, "Stockholm"}, @@ -271,7 +272,7 @@ publickey(#'DSAPrivateKey'{p=P, q=Q, g=G, y=Y}) -> #'OTPSubjectPublicKeyInfo'{algorithm = Algo, subjectPublicKey = Y}. validity(Opts) -> - DefFrom0 = date(), + DefFrom0 = calendar:gregorian_days_to_date(calendar:date_to_gregorian_days(date())-1), DefTo0 = calendar:gregorian_days_to_date(calendar:date_to_gregorian_days(date())+7), {DefFrom, DefTo} = proplists:get_value(validity, Opts, {DefFrom0, DefTo0}), Format = fun({Y,M,D}) -> lists:flatten(io_lib:format("~w~2..0w~2..0w000000Z",[Y,M,D])) end, @@ -410,3 +411,11 @@ extended_gcd(A, B) -> {X, Y} = extended_gcd(B, N), {Y, X-Y*(A div B)} end. + +pem_to_der(File) -> + {ok, PemBin} = file:read_file(File), + public_key:pem_decode(PemBin). + +der_to_pem(File, Entries) -> + PemBin = public_key:pem_encode(Entries), + file:write_file(File, PemBin). diff --git a/lib/ssl/test/make_certs.erl b/lib/ssl/test/make_certs.erl index 0cdf33c3e2..3c18a905b4 100644 --- a/lib/ssl/test/make_certs.erl +++ b/lib/ssl/test/make_certs.erl @@ -90,8 +90,10 @@ enduser(Root, OpenSSLCmd, CA, User) -> KeyFile = filename:join([UsrRoot, "key.pem"]), ReqFile = filename:join([UsrRoot, "req.pem"]), create_req(Root, OpenSSLCmd, CnfFile, KeyFile, ReqFile), - CertFile = filename:join([UsrRoot, "cert.pem"]), - sign_req(Root, OpenSSLCmd, CA, "user_cert", ReqFile, CertFile). + CertFileAllUsage = filename:join([UsrRoot, "cert.pem"]), + sign_req(Root, OpenSSLCmd, CA, "user_cert", ReqFile, CertFileAllUsage), + CertFileDigitalSigOnly = filename:join([UsrRoot, "digital_signature_only_cert.pem"]), + sign_req(Root, OpenSSLCmd, CA, "user_cert_digital_signature_only", ReqFile, CertFileDigitalSigOnly). collect_certs(Root, CAs, Users) -> Bins = lists:foldr( @@ -255,6 +257,7 @@ ca_cnf(CA) -> "RANDFILE = $dir/private/RAND\n" "\n" "x509_extensions = user_cert\n" + "unique_subject = no\n" "default_days = 3600\n" "default_md = sha1\n" "preserve = no\n" @@ -279,6 +282,15 @@ ca_cnf(CA) -> "issuerAltName = issuer:copy\n" "\n" + "[user_cert_digital_signature_only]\n" + "basicConstraints = CA:false\n" + "keyUsage = digitalSignature\n" + "subjectKeyIdentifier = hash\n" + "authorityKeyIdentifier = keyid,issuer:always\n" + "subjectAltName = email:copy\n" + "issuerAltName = issuer:copy\n" + "\n" + "[ca_cert]\n" "basicConstraints = critical,CA:true\n" "keyUsage = cRLSign, keyCertSign\n" diff --git a/lib/ssl/test/ssl_basic_SUITE.erl b/lib/ssl/test/ssl_basic_SUITE.erl index 8a1b90ed98..47c7407a2e 100644 --- a/lib/ssl/test/ssl_basic_SUITE.erl +++ b/lib/ssl/test/ssl_basic_SUITE.erl @@ -7,7 +7,7 @@ %% 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/. +%% 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 @@ -232,8 +232,11 @@ all(suite) -> server_renegotiate, client_renegotiate_reused_session, server_renegotiate_reused_session, client_no_wrap_sequence_number, server_no_wrap_sequence_number, extended_key_usage, - validate_extensions_fun, no_authority_key_identifier, - invalid_signature_client, invalid_signature_server, cert_expired + no_authority_key_identifier, + invalid_signature_client, invalid_signature_server, cert_expired, + client_with_cert_cipher_suites_handshake, unknown_server_ca_fail, + der_input, unknown_server_ca_accept_verify_none, unknown_server_ca_accept_verify_peer, + unknown_server_ca_accept_backwardscompatibilty ]. %% Test cases starts here. @@ -578,8 +581,8 @@ peercert(Config) when is_list(Config) -> {options, ClientOpts}]), CertFile = proplists:get_value(certfile, ServerOpts), - {ok, [{cert, BinCert, _}]} = public_key:pem_to_der(CertFile), - {ok, ErlCert} = public_key:pkix_decode_cert(BinCert, otp), + [{'Certificate', BinCert, _}]= ssl_test_lib:pem_to_der(CertFile), + ErlCert = public_key:pkix_decode_cert(BinCert, otp), ServerMsg = {{error, no_peercert}, {error, no_peercert}}, ClientMsg = {{ok, BinCert}, {ok, ErlCert}}, @@ -1258,7 +1261,6 @@ eoptions(Config) when is_list(Config) -> {verify_fun, function}, {fail_if_no_peer_cert, 0}, {verify_client_once, 1}, - {validate_extensions_fun, function}, {depth, four}, {certfile, 'cert.pem'}, {keyfile,'key.pem' }, @@ -1552,25 +1554,26 @@ cipher(CipherSuite, Version, Config, ClientOpts, ServerOpts) -> process_flag(trap_exit, true), test_server:format("Testing CipherSuite ~p~n", [CipherSuite]), {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config), + + ErlangCipherSuite = erlang_cipher_suite(CipherSuite), + + ConnectionInfo = {ok, {Version, ErlangCipherSuite}}, + Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0}, {from, self()}, - {mfa, {?MODULE, connection_info_result, []}}, + {mfa, {ssl_test_lib, cipher_result, [ConnectionInfo]}}, {options, ServerOpts}]), Port = ssl_test_lib:inet_port(Server), Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port}, {host, Hostname}, {from, self()}, - {mfa, {?MODULE, connection_info_result, []}}, + {mfa, {ssl_test_lib, cipher_result, [ConnectionInfo]}}, {options, [{ciphers,[CipherSuite]} | ClientOpts]}]), - - ErlangCipherSuite = erlang_cipher_suite(CipherSuite), - - ServerMsg = ClientMsg = {ok, {Version, ErlangCipherSuite}}, - - Result = ssl_test_lib:wait_for_result(Server, ServerMsg, - Client, ClientMsg), + + Result = ssl_test_lib:wait_for_result(Server, ok, Client, ok), + ssl_test_lib:close(Server), receive {'EXIT', Server, normal} -> @@ -2268,14 +2271,7 @@ client_verify_none_active_once(Config) when is_list(Config) -> {mfa, {?MODULE, send_recv_result_active_once, []}}, {options, [{active, once} | ServerOpts]}]), Port = ssl_test_lib:inet_port(Server), - %% TODO: send message to test process to make sure - %% verifyfun has beeen run as it has the same behavior as - %% the default fun - VerifyFun = fun([{bad_cert, unknown_ca}]) -> - true; - (_) -> - false - end, + Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port}, {host, Hostname}, {from, self()}, @@ -2283,8 +2279,7 @@ client_verify_none_active_once(Config) when is_list(Config) -> send_recv_result_active_once, []}}, {options, [{active, once}, - {verify, verify_none}, - {verify_fun, VerifyFun} + {verify, verify_none} | ClientOpts]}]), ssl_test_lib:check_result(Server, ok, Client, ok), @@ -2525,35 +2520,35 @@ extended_key_usage(Config) when is_list(Config) -> PrivDir = ?config(priv_dir, Config), KeyFile = filename:join(PrivDir, "otpCA/private/key.pem"), - {ok, [KeyInfo]} = public_key:pem_to_der(KeyFile), - {ok, Key} = public_key:decode_private_key(KeyInfo), + [KeyEntry] = ssl_test_lib:pem_to_der(KeyFile), + Key = public_key:pem_entry_decode(KeyEntry), ServerCertFile = proplists:get_value(certfile, ServerOpts), NewServerCertFile = filename:join(PrivDir, "server/new_cert.pem"), - {ok, [{cert, ServerDerCert, _}]} = public_key:pem_to_der(ServerCertFile), - {ok, ServerOTPCert} = public_key:pkix_decode_cert(ServerDerCert, otp), + [{'Certificate', ServerDerCert, _}] = ssl_test_lib:pem_to_der(ServerCertFile), + ServerOTPCert = public_key:pkix_decode_cert(ServerDerCert, otp), ServerExtKeyUsageExt = {'Extension', ?'id-ce-extKeyUsage', true, [?'id-kp-serverAuth']}, ServerOTPTbsCert = ServerOTPCert#'OTPCertificate'.tbsCertificate, ServerExtensions = ServerOTPTbsCert#'OTPTBSCertificate'.extensions, NewServerOTPTbsCert = ServerOTPTbsCert#'OTPTBSCertificate'{extensions = [ServerExtKeyUsageExt | ServerExtensions]}, - NewServerDerCert = public_key:sign(NewServerOTPTbsCert, Key), - public_key:der_to_pem(NewServerCertFile, [{cert, NewServerDerCert, not_encrypted}]), + NewServerDerCert = public_key:pkix_sign(NewServerOTPTbsCert, Key), + ssl_test_lib:der_to_pem(NewServerCertFile, [{'Certificate', NewServerDerCert, not_encrypted}]), NewServerOpts = [{certfile, NewServerCertFile} | proplists:delete(certfile, ServerOpts)], ClientCertFile = proplists:get_value(certfile, ClientOpts), NewClientCertFile = filename:join(PrivDir, "client/new_cert.pem"), - {ok, [{cert, ClientDerCert, _}]} = public_key:pem_to_der(ClientCertFile), - {ok, ClientOTPCert} = public_key:pkix_decode_cert(ClientDerCert, otp), + [{'Certificate', ClientDerCert, _}] = ssl_test_lib:pem_to_der(ClientCertFile), + ClientOTPCert = public_key:pkix_decode_cert(ClientDerCert, otp), ClientExtKeyUsageExt = {'Extension', ?'id-ce-extKeyUsage', true, [?'id-kp-clientAuth']}, ClientOTPTbsCert = ClientOTPCert#'OTPCertificate'.tbsCertificate, ClientExtensions = ClientOTPTbsCert#'OTPTBSCertificate'.extensions, NewClientOTPTbsCert = ClientOTPTbsCert#'OTPTBSCertificate'{extensions = [ClientExtKeyUsageExt | ClientExtensions]}, - NewClientDerCert = public_key:sign(NewClientOTPTbsCert, Key), - public_key:der_to_pem(NewClientCertFile, [{cert, NewClientDerCert, not_encrypted}]), + NewClientDerCert = public_key:pkix_sign(NewClientOTPTbsCert, Key), + ssl_test_lib:der_to_pem(NewClientCertFile, [{'Certificate', NewClientDerCert, not_encrypted}]), NewClientOpts = [{certfile, NewClientCertFile} | proplists:delete(certfile, ClientOpts)], {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config), @@ -2575,59 +2570,25 @@ extended_key_usage(Config) when is_list(Config) -> ssl_test_lib:close(Client). %%-------------------------------------------------------------------- -validate_extensions_fun(doc) -> - ["Test that it is possible to specify a validate_extensions_fun"]; - -validate_extensions_fun(suite) -> - []; - -validate_extensions_fun(Config) when is_list(Config) -> - ClientOpts = ?config(client_verification_opts, Config), - ServerOpts = ?config(server_verification_opts, Config), - - Fun = fun(Extensions, State, _, AccError) -> - {Extensions, State, AccError} - end, - - {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config), - - Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0}, - {from, self()}, - {mfa, {?MODULE, send_recv_result_active, []}}, - {options, [{validate_extensions_fun, Fun}, - {verify, verify_peer} | ServerOpts]}]), - Port = ssl_test_lib:inet_port(Server), - - Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port}, - {host, Hostname}, - {from, self()}, - {mfa, {?MODULE, send_recv_result_active, []}}, - {options,[{validate_extensions_fun, Fun} | ClientOpts]}]), - - ssl_test_lib:check_result(Server, ok, Client, ok), - - ssl_test_lib:close(Server), - ssl_test_lib:close(Client). - -%%-------------------------------------------------------------------- no_authority_key_identifier(doc) -> - ["Test cert that does not have authorityKeyIdentifier extension"]; + ["Test cert that does not have authorityKeyIdentifier extension" + " but are present in trusted certs db."]; no_authority_key_identifier(suite) -> []; no_authority_key_identifier(Config) when is_list(Config) -> - ClientOpts = ?config(client_opts, Config), + ClientOpts = ?config(client_verification_opts, Config), ServerOpts = ?config(server_opts, Config), PrivDir = ?config(priv_dir, Config), KeyFile = filename:join(PrivDir, "otpCA/private/key.pem"), - {ok, [KeyInfo]} = public_key:pem_to_der(KeyFile), - {ok, Key} = public_key:decode_private_key(KeyInfo), + [KeyEntry] = ssl_test_lib:pem_to_der(KeyFile), + Key = public_key:pem_entry_decode(KeyEntry), CertFile = proplists:get_value(certfile, ServerOpts), NewCertFile = filename:join(PrivDir, "server/new_cert.pem"), - {ok, [{cert, DerCert, _}]} = public_key:pem_to_der(CertFile), - {ok, OTPCert} = public_key:pkix_decode_cert(DerCert, otp), + [{'Certificate', DerCert, _}] = ssl_test_lib:pem_to_der(CertFile), + OTPCert = public_key:pkix_decode_cert(DerCert, otp), OTPTbsCert = OTPCert#'OTPCertificate'.tbsCertificate, Extensions = OTPTbsCert#'OTPTBSCertificate'.extensions, NewExtensions = delete_authority_key_extension(Extensions, []), @@ -2635,8 +2596,8 @@ no_authority_key_identifier(Config) when is_list(Config) -> test_server:format("Extensions ~p~n, NewExtensions: ~p~n", [Extensions, NewExtensions]), - NewDerCert = public_key:sign(NewOTPTbsCert, Key), - public_key:der_to_pem(NewCertFile, [{cert, NewDerCert, not_encrypted}]), + NewDerCert = public_key:pkix_sign(NewOTPTbsCert, Key), + ssl_test_lib:der_to_pem(NewCertFile, [{'Certificate', NewDerCert, not_encrypted}]), NewServerOpts = [{certfile, NewCertFile} | proplists:delete(certfile, ServerOpts)], {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config), @@ -2674,21 +2635,21 @@ invalid_signature_server(suite) -> []; invalid_signature_server(Config) when is_list(Config) -> - ClientOpts = ?config(client_opts, Config), + ClientOpts = ?config(client_verification_opts, Config), ServerOpts = ?config(server_verification_opts, Config), PrivDir = ?config(priv_dir, Config), KeyFile = filename:join(PrivDir, "server/key.pem"), - {ok, [KeyInfo]} = public_key:pem_to_der(KeyFile), - {ok, Key} = public_key:decode_private_key(KeyInfo), + [KeyEntry] = ssl_test_lib:pem_to_der(KeyFile), + Key = public_key:pem_entry_decode(KeyEntry), ServerCertFile = proplists:get_value(certfile, ServerOpts), NewServerCertFile = filename:join(PrivDir, "server/invalid_cert.pem"), - {ok, [{cert, ServerDerCert, _}]} = public_key:pem_to_der(ServerCertFile), - {ok, ServerOTPCert} = public_key:pkix_decode_cert(ServerDerCert, otp), + [{'Certificate', ServerDerCert, _}] = ssl_test_lib:pem_to_der(ServerCertFile), + ServerOTPCert = public_key:pkix_decode_cert(ServerDerCert, otp), ServerOTPTbsCert = ServerOTPCert#'OTPCertificate'.tbsCertificate, - NewServerDerCert = public_key:sign(ServerOTPTbsCert, Key), - public_key:der_to_pem(NewServerCertFile, [{cert, NewServerDerCert, not_encrypted}]), + NewServerDerCert = public_key:pkix_sign(ServerOTPTbsCert, Key), + ssl_test_lib:der_to_pem(NewServerCertFile, [{'Certificate', NewServerDerCert, not_encrypted}]), NewServerOpts = [{certfile, NewServerCertFile} | proplists:delete(certfile, ServerOpts)], {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config), @@ -2719,16 +2680,16 @@ invalid_signature_client(Config) when is_list(Config) -> PrivDir = ?config(priv_dir, Config), KeyFile = filename:join(PrivDir, "client/key.pem"), - {ok, [KeyInfo]} = public_key:pem_to_der(KeyFile), - {ok, Key} = public_key:decode_private_key(KeyInfo), + [KeyEntry] = ssl_test_lib:pem_to_der(KeyFile), + Key = public_key:pem_entry_decode(KeyEntry), ClientCertFile = proplists:get_value(certfile, ClientOpts), NewClientCertFile = filename:join(PrivDir, "client/invalid_cert.pem"), - {ok, [{cert, ClientDerCert, _}]} = public_key:pem_to_der(ClientCertFile), - {ok, ClientOTPCert} = public_key:pkix_decode_cert(ClientDerCert, otp), + [{'Certificate', ClientDerCert, _}] = ssl_test_lib:pem_to_der(ClientCertFile), + ClientOTPCert = public_key:pkix_decode_cert(ClientDerCert, otp), ClientOTPTbsCert = ClientOTPCert#'OTPCertificate'.tbsCertificate, - NewClientDerCert = public_key:sign(ClientOTPTbsCert, Key), - public_key:der_to_pem(NewClientCertFile, [{cert, NewClientDerCert, not_encrypted}]), + NewClientDerCert = public_key:pkix_sign(ClientOTPTbsCert, Key), + ssl_test_lib:der_to_pem(NewClientCertFile, [{'Certificate', NewClientDerCert, not_encrypted}]), NewClientOpts = [{certfile, NewClientCertFile} | proplists:delete(certfile, ClientOpts)], {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config), @@ -2745,7 +2706,7 @@ invalid_signature_client(Config) when is_list(Config) -> tcp_delivery_workaround(Server, {error, "bad certificate"}, Client, {error,"bad certificate"}). -tcp_delivery_workaround(Server, ServMsg, Client, ClientMsg) -> +tcp_delivery_workaround(Server, ServerMsg, Client, ClientMsg) -> receive {Server, ServerMsg} -> receive @@ -2791,18 +2752,18 @@ cert_expired(suite) -> []; cert_expired(Config) when is_list(Config) -> - ClientOpts = ?config(client_opts, Config), + ClientOpts = ?config(client_verification_opts, Config), ServerOpts = ?config(server_verification_opts, Config), PrivDir = ?config(priv_dir, Config), KeyFile = filename:join(PrivDir, "otpCA/private/key.pem"), - {ok, [KeyInfo]} = public_key:pem_to_der(KeyFile), - {ok, Key} = public_key:decode_private_key(KeyInfo), + [KeyEntry] = ssl_test_lib:pem_to_der(KeyFile), + Key = public_key:pem_entry_decode(KeyEntry), ServerCertFile = proplists:get_value(certfile, ServerOpts), NewServerCertFile = filename:join(PrivDir, "server/expired_cert.pem"), - {ok, [{cert, DerCert, _}]} = public_key:pem_to_der(ServerCertFile), - {ok, OTPCert} = public_key:pkix_decode_cert(DerCert, otp), + [{'Certificate', DerCert, _}] = ssl_test_lib:pem_to_der(ServerCertFile), + OTPCert = public_key:pkix_decode_cert(DerCert, otp), OTPTbsCert = OTPCert#'OTPCertificate'.tbsCertificate, {Year, Month, Day} = date(), @@ -2825,8 +2786,8 @@ cert_expired(Config) when is_list(Config) -> [OTPTbsCert#'OTPTBSCertificate'.validity, NewValidity]), NewOTPTbsCert = OTPTbsCert#'OTPTBSCertificate'{validity = NewValidity}, - NewServerDerCert = public_key:sign(NewOTPTbsCert, Key), - public_key:der_to_pem(NewServerCertFile, [{cert, NewServerDerCert, not_encrypted}]), + NewServerDerCert = public_key:pkix_sign(NewOTPTbsCert, Key), + ssl_test_lib:der_to_pem(NewServerCertFile, [{'Certificate', NewServerDerCert, not_encrypted}]), NewServerOpts = [{certfile, NewServerCertFile} | proplists:delete(certfile, ServerOpts)], {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config), @@ -2849,6 +2810,225 @@ two_digits_str(N) -> lists:flatten(io_lib:format("~p", [N])). %%-------------------------------------------------------------------- + +client_with_cert_cipher_suites_handshake(doc) -> + ["Test that client with a certificate without keyEncipherment usage " + " extension can connect to a server with restricted cipher suites "]; + +client_with_cert_cipher_suites_handshake(suite) -> + []; + +client_with_cert_cipher_suites_handshake(Config) when is_list(Config) -> + ClientOpts = ?config(client_verification_opts_digital_signature_only, Config), + ServerOpts = ?config(server_verification_opts, Config), + {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config), + Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0}, + {from, self()}, + {mfa, {?MODULE, + send_recv_result_active, []}}, + {options, [{active, true}, + {ciphers, ssl_test_lib:rsa_non_signed_suites()} + | ServerOpts]}]), + Port = ssl_test_lib:inet_port(Server), + Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port}, + {host, Hostname}, + {from, self()}, + {mfa, {?MODULE, + send_recv_result_active, []}}, + {options, [{active, true} + | ClientOpts]}]), + + ssl_test_lib:check_result(Server, ok, Client, ok), + ssl_test_lib:close(Server), + ssl_test_lib:close(Client). +%%-------------------------------------------------------------------- +unknown_server_ca_fail(doc) -> + ["Test that the client fails if the ca is unknown in verify_peer mode"]; +unknown_server_ca_fail(suite) -> + []; +unknown_server_ca_fail(Config) when is_list(Config) -> + ClientOpts = ?config(client_opts, Config), + ServerOpts = ?config(server_opts, Config), + {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config), + Server = ssl_test_lib:start_server_error([{node, ServerNode}, {port, 0}, + {from, self()}, + {mfa, {ssl_test_lib, + no_result, []}}, + {options, ServerOpts}]), + Port = ssl_test_lib:inet_port(Server), + + FunAndState = {fun(_,{bad_cert, _} = Reason, _) -> + {fail, Reason}; + (_,{extension, _}, UserState) -> + {unknown, UserState} + end, []}, + + Client = ssl_test_lib:start_client_error([{node, ClientNode}, {port, Port}, + {host, Hostname}, + {from, self()}, + {mfa, {ssl_test_lib, + no_result, []}}, + {options, + [{verify, verify_peer}, + {verify_fun, FunAndState} + | ClientOpts]}]), + + ssl_test_lib:check_result(Server, {error,"unknown ca"}, + Client, {error, "unknown ca"}), + ssl_test_lib:close(Server), + ssl_test_lib:close(Client). + +%%-------------------------------------------------------------------- +unknown_server_ca_accept_verify_none(doc) -> + ["Test that the client succeds if the ca is unknown in verify_none mode"]; +unknown_server_ca_accept_verify_none(suite) -> + []; +unknown_server_ca_accept_verify_none(Config) when is_list(Config) -> + ClientOpts = ?config(client_opts, Config), + ServerOpts = ?config(server_opts, Config), + {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config), + Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0}, + {from, self()}, + {mfa, {?MODULE, + send_recv_result_active, []}}, + {options, ServerOpts}]), + Port = ssl_test_lib:inet_port(Server), + Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port}, + {host, Hostname}, + {from, self()}, + {mfa, {?MODULE, + send_recv_result_active, []}}, + {options, + [{verify, verify_none}| ClientOpts]}]), + + ssl_test_lib:check_result(Server, ok, Client, ok), + ssl_test_lib:close(Server), + ssl_test_lib:close(Client). +%%-------------------------------------------------------------------- +unknown_server_ca_accept_verify_peer(doc) -> + ["Test that the client succeds if the ca is unknown in verify_peer mode" + " with a verify_fun that accepts the unknown ca error"]; +unknown_server_ca_accept_verify_peer(suite) -> + []; +unknown_server_ca_accept_verify_peer(Config) when is_list(Config) -> + ClientOpts = ?config(client_opts, Config), + ServerOpts = ?config(server_opts, Config), + {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config), + Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0}, + {from, self()}, + {mfa, {?MODULE, + send_recv_result_active, []}}, + {options, ServerOpts}]), + Port = ssl_test_lib:inet_port(Server), + + FunAndState = {fun(_,{bad_cert, unknown_ca}, UserState) -> + {valid, UserState}; + (_,{bad_cert, _} = Reason, _) -> + {fail, Reason}; + (_,{extension, _}, UserState) -> + {unknown, UserState} + end, []}, + + Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port}, + {host, Hostname}, + {from, self()}, + {mfa, {?MODULE, + send_recv_result_active, []}}, + {options, + [{verify, verify_peer}, + {verify_fun, FunAndState}| ClientOpts]}]), + + ssl_test_lib:check_result(Server, ok, Client, ok), + ssl_test_lib:close(Server), + ssl_test_lib:close(Client). + +%%-------------------------------------------------------------------- +unknown_server_ca_accept_backwardscompatibilty(doc) -> + ["Test that the client succeds if the ca is unknown in verify_none mode"]; +unknown_server_ca_accept_backwardscompatibilty(suite) -> + []; +unknown_server_ca_accept_backwardscompatibilty(Config) when is_list(Config) -> + ClientOpts = ?config(client_opts, Config), + ServerOpts = ?config(server_opts, Config), + {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config), + Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0}, + {from, self()}, + {mfa, {?MODULE, + send_recv_result_active, []}}, + {options, ServerOpts}]), + Port = ssl_test_lib:inet_port(Server), + + AcceptBadCa = fun({bad_cert,unknown_ca}, Acc) -> Acc; + (Other, Acc) -> [Other | Acc] + end, + VerifyFun = + fun(ErrorList) -> + case lists:foldl(AcceptBadCa, [], ErrorList) of + [] -> true; + [_|_] -> false + end + end, + + Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port}, + {host, Hostname}, + {from, self()}, + {mfa, {?MODULE, + send_recv_result_active, []}}, + {options, + [{verify, verify_peer}, + {verify_fun, VerifyFun}| ClientOpts]}]), + + ssl_test_lib:check_result(Server, ok, Client, ok), + ssl_test_lib:close(Server), + ssl_test_lib:close(Client). + +%%-------------------------------------------------------------------- +der_input(doc) -> + ["Test to input certs and key as der"]; + +der_input(suite) -> + []; + +der_input(Config) when is_list(Config) -> + + SeverVerifyOpts = ?config(server_verification_opts, Config), + {ServerCert, ServerKey, ServerCaCerts} = der_input_opts(SeverVerifyOpts), + ClientVerifyOpts = ?config(client_verification_opts, Config), + {ClientCert, ClientKey, ClientCaCerts} = der_input_opts(ClientVerifyOpts), + ServerOpts = [{verify, verify_peer}, {fail_if_no_peer_cert, true}, + {cert, ServerCert}, {key, ServerKey}, {cacerts, ServerCaCerts}], + ClientOpts = [{verify, verify_peer}, {fail_if_no_peer_cert, true}, + {cert, ClientCert}, {key, ClientKey}, {cacerts, ClientCaCerts}], + {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config), + Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0}, + {from, self()}, + {mfa, {?MODULE, send_recv_result, []}}, + {options, [{active, false} | ServerOpts]}]), + Port = ssl_test_lib:inet_port(Server), + Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port}, + {host, Hostname}, + {from, self()}, + {mfa, {?MODULE, send_recv_result, []}}, + {options, [{active, false} | ClientOpts]}]), + + ssl_test_lib:check_result(Server, ok, Client, ok), + ssl_test_lib:close(Server), + ssl_test_lib:close(Client). + +der_input_opts(Opts) -> + Certfile = proplists:get_value(certfile, Opts), + CaCertsfile = proplists:get_value(cacertfile, Opts), + Keyfile = proplists:get_value(keyfile, Opts), + [{_, Cert, _}] = ssl_test_lib:pem_to_der(Certfile), + [{_, Key, _}] = ssl_test_lib:pem_to_der(Keyfile), + CaCerts = + lists:map(fun(Entry) -> + {_, CaCert, _} = Entry, + CaCert + end, ssl_test_lib:pem_to_der(CaCertsfile)), + {Cert, {rsa, Key}, CaCerts}. + +%%-------------------------------------------------------------------- %%% Internal functions %%-------------------------------------------------------------------- send_recv_result(Socket) -> @@ -2873,6 +3053,7 @@ send_recv_result_active_once(Socket) -> result_ok(_Socket) -> ok. + renegotiate(Socket, Data) -> test_server:format("Renegotiating ~n", []), Result = ssl:renegotiate(Socket), diff --git a/lib/ssl/test/ssl_packet_SUITE.erl b/lib/ssl/test/ssl_packet_SUITE.erl index 1b8754afe9..1e7cde1c25 100644 --- a/lib/ssl/test/ssl_packet_SUITE.erl +++ b/lib/ssl/test/ssl_packet_SUITE.erl @@ -145,14 +145,19 @@ all(suite) -> packet_baddata_passive, packet_baddata_active, packet_size_passive, packet_size_active, packet_cdr_decode, + packet_cdr_decode_list, packet_http_decode, packet_http_decode_list, packet_http_bin_decode_multi, packet_line_decode, - packet_asn1_decode, + packet_line_decode_list, + packet_asn1_decode, + packet_asn1_decode_list, packet_tpkt_decode, + packet_tpkt_decode_list, %packet_fcgi_decode, packet_sunrm_decode, + packet_sunrm_decode_list, header_decode_one_byte, header_decode_two_bytes, header_decode_two_bytes_one_sent, @@ -1429,7 +1434,7 @@ packet_size_passive(Config) when is_list(Config) -> %%-------------------------------------------------------------------- packet_cdr_decode(doc) -> - ["Test setting the packet option {packet, cdr}"]; + ["Test setting the packet option {packet, cdr}, {mode, binary}"]; packet_cdr_decode(suite) -> []; packet_cdr_decode(Config) when is_list(Config) -> @@ -1463,8 +1468,44 @@ packet_cdr_decode(Config) when is_list(Config) -> ssl_test_lib:close(Client). %%-------------------------------------------------------------------- +packet_cdr_decode_list(doc) -> + ["Test setting the packet option {packet, cdr} {mode, list}"]; +packet_cdr_decode_list(suite) -> + []; +packet_cdr_decode_list(Config) when is_list(Config) -> + ClientOpts = ?config(client_opts, Config), + ServerOpts = ?config(server_opts, Config), + {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config), + + %% A valid cdr packet + Data = [71,73,79,80,1,2,2,1,0,0,0,41,0,0,0,0,0,0,0,0,0,0,0,1,78, + 69,79,0,0,0,0,2,0,10,0,0,0,0,0,0,0,0,0,18,0,0,0,0,0,0,0,4,49], + + Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0}, + {from, self()}, + {mfa, {?MODULE, server_packet_decode, + [Data]}}, + {options, [{active, true}, list, + {packet, cdr}|ServerOpts]}]), + + Port = ssl_test_lib:inet_port(Server), + Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port}, + {host, Hostname}, + {from, self()}, + {mfa, {?MODULE, client_packet_decode, + [Data]}}, + {options, [{active, true}, {packet, cdr}, + list | ClientOpts]}]), + + ssl_test_lib:check_result(Server, ok, Client, ok), + + ssl_test_lib:close(Server), + ssl_test_lib:close(Client). + +%%-------------------------------------------------------------------- packet_http_decode(doc) -> - ["Test setting the packet option {packet, http} {mode, binary}"]; + ["Test setting the packet option {packet, http} {mode, binary} " + "(Body will be binary http strings are lists)"]; packet_http_decode(suite) -> []; @@ -1485,7 +1526,7 @@ packet_http_decode(Config) when is_list(Config) -> {from, self()}, {mfa, {?MODULE, server_http_decode, [Response]}}, - {options, [{active, true}, binary, + {options, [{active, true},binary, {packet, http} | ServerOpts]}]), Port = ssl_test_lib:inet_port(Server), @@ -1494,7 +1535,7 @@ packet_http_decode(Config) when is_list(Config) -> {from, self()}, {mfa, {?MODULE, client_http_decode, [Request]}}, - {options, [{active, true}, binary, + {options, [{active, true}, binary, {packet, http} | ClientOpts]}]), @@ -1548,7 +1589,8 @@ client_http_decode(Socket, HttpRequest) -> %%-------------------------------------------------------------------- packet_http_decode_list(doc) -> - ["Test setting the packet option {packet, http}, {mode, list}"]; + ["Test setting the packet option {packet, http}, {mode, list}" + "(Body will be litst too)"]; packet_http_decode_list(suite) -> []; packet_http_decode_list(Config) when is_list(Config) -> @@ -1697,7 +1739,7 @@ client_http_bin_decode(_, _, _) -> ok. %%-------------------------------------------------------------------- packet_line_decode(doc) -> - ["Test setting the packet option {packet, line}"]; + ["Test setting the packet option {packet, line}, {mode, binary}"]; packet_line_decode(suite) -> []; packet_line_decode(Config) when is_list(Config) -> @@ -1731,30 +1773,44 @@ packet_line_decode(Config) when is_list(Config) -> ssl_test_lib:close(Server), ssl_test_lib:close(Client). +%%-------------------------------------------------------------------- -server_line_packet_decode(Socket, Lines) -> - receive - {ssl, Socket, <<"Line ends here.\n">>} -> ok; - Other1 -> exit({?LINE, Other1}) - end, - receive - {ssl, Socket, <<"Now it is a new line.\n">>} -> ok; - Other2 -> exit({?LINE, Other2}) - end, - ok = ssl:send(Socket, Lines). +packet_line_decode_list(doc) -> + ["Test setting the packet option {packet, line}, {mode, list}"]; +packet_line_decode_list(suite) -> + []; +packet_line_decode_list(Config) when is_list(Config) -> + ClientOpts = ?config(client_opts, Config), + ServerOpts = ?config(server_opts, Config), + {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config), + + Data = lists:flatten(io_lib:format("Line ends here.~n" + "Now it is a new line.~n", [])), + + Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0}, + {from, self()}, + {mfa, {?MODULE, + server_line_packet_decode, + [Data]}}, + {options, [{active, true}, list, + {packet, line}|ServerOpts]}]), + + Port = ssl_test_lib:inet_port(Server), + Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port}, + {host, Hostname}, + {from, self()}, + {mfa, {?MODULE, + client_line_packet_decode, + [Data]}}, + {options, [{active, true}, + {packet, line}, + list | ClientOpts]}]), + + ssl_test_lib:check_result(Server, ok, Client, ok), + + ssl_test_lib:close(Server), + ssl_test_lib:close(Client). -client_line_packet_decode(Socket, Lines) -> - <<P1:10/binary, P2/binary>> = Lines, - ok = ssl:send(Socket, P1), - ok = ssl:send(Socket, P2), - receive - {ssl, Socket, <<"Line ends here.\n">>} -> ok; - Other1 -> exit({?LINE, Other1}) - end, - receive - {ssl, Socket, <<"Now it is a new line.\n">>} -> ok; - Other2 -> exit({?LINE, Other2}) - end. %%-------------------------------------------------------------------- @@ -1770,7 +1826,7 @@ packet_asn1_decode(Config) when is_list(Config) -> File = proplists:get_value(certfile, ServerOpts), %% A valid asn1 BER packet (DER is stricter BER) - {ok,[{cert, Data, _}]} = public_key:pem_to_der(File), + [{'Certificate', Data, _}] = ssl_test_lib:pem_to_der(File), Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0}, {from, self()}, @@ -1794,6 +1850,44 @@ packet_asn1_decode(Config) when is_list(Config) -> ssl_test_lib:close(Client). %%-------------------------------------------------------------------- +packet_asn1_decode_list(doc) -> + ["Test setting the packet option {packet, asn1}"]; +packet_asn1_decode_list(suite) -> + []; +packet_asn1_decode_list(Config) when is_list(Config) -> + ClientOpts = ?config(client_opts, Config), + ServerOpts = ?config(server_opts, Config), + {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config), + + File = proplists:get_value(certfile, ServerOpts), + + %% A valid asn1 BER packet (DER is stricter BER) + [{'Certificate', BinData, _}] = ssl_test_lib:pem_to_der(File), + + Data = binary_to_list(BinData), + + Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0}, + {from, self()}, + {mfa, {?MODULE, server_packet_decode, + [Data]}}, + {options, [{active, true}, list, + {packet, asn1}|ServerOpts]}]), + + Port = ssl_test_lib:inet_port(Server), + Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port}, + {host, Hostname}, + {from, self()}, + {mfa, {?MODULE, client_packet_decode, + [Data]}}, + {options, [{active, true}, {packet, asn1}, + list | ClientOpts]}]), + + ssl_test_lib:check_result(Server, ok, Client, ok), + + ssl_test_lib:close(Server), + ssl_test_lib:close(Client). + +%%-------------------------------------------------------------------- packet_tpkt_decode(doc) -> ["Test setting the packet option {packet, tpkt}"]; packet_tpkt_decode(suite) -> @@ -1826,6 +1920,38 @@ packet_tpkt_decode(Config) when is_list(Config) -> ssl_test_lib:close(Server), ssl_test_lib:close(Client). +%%-------------------------------------------------------------------- +packet_tpkt_decode_list(doc) -> + ["Test setting the packet option {packet, tpkt}"]; +packet_tpkt_decode_list(suite) -> + []; +packet_tpkt_decode_list(Config) when is_list(Config) -> + ClientOpts = ?config(client_opts, Config), + ServerOpts = ?config(server_opts, Config), + {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config), + + Data = binary_to_list(list_to_binary(add_tpkt_header("TPKT data"))), + + Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0}, + {from, self()}, + {mfa, {?MODULE, server_packet_decode, + [Data]}}, + {options, [{active, true}, list, + {packet, tpkt}|ServerOpts]}]), + + Port = ssl_test_lib:inet_port(Server), + Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port}, + {host, Hostname}, + {from, self()}, + {mfa, {?MODULE, client_packet_decode, + [Data]}}, + {options, [{active, true}, {packet, tpkt}, + list | ClientOpts]}]), + + ssl_test_lib:check_result(Server, ok, Client, ok), + + ssl_test_lib:close(Server), + ssl_test_lib:close(Client). %%-------------------------------------------------------------------- @@ -1895,6 +2021,39 @@ packet_sunrm_decode(Config) when is_list(Config) -> ssl_test_lib:close(Server), ssl_test_lib:close(Client). + +%%-------------------------------------------------------------------- +packet_sunrm_decode_list(doc) -> + ["Test setting the packet option {packet, sunrm}"]; +packet_sunrm_decode_list(suite) -> + []; +packet_sunrm_decode_list(Config) when is_list(Config) -> + ClientOpts = ?config(client_opts, Config), + ServerOpts = ?config(server_opts, Config), + {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config), + + Data = binary_to_list(list_to_binary([<<11:32>>, "Hello world"])), + + Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0}, + {from, self()}, + {mfa, {?MODULE, server_packet_decode, + [Data]}}, + {options, [{active, true}, list, + {packet, sunrm}|ServerOpts]}]), + + Port = ssl_test_lib:inet_port(Server), + Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port}, + {host, Hostname}, + {from, self()}, + {mfa, {?MODULE, client_packet_decode, + [Data]}}, + {options, [{active, true}, {packet, sunrm}, + list | ClientOpts]}]), + + ssl_test_lib:check_result(Server, ok, Client, ok), + + ssl_test_lib:close(Server), + ssl_test_lib:close(Client). %%-------------------------------------------------------------------- header_decode_one_byte(doc) -> @@ -2037,21 +2196,29 @@ header_decode_two_bytes_one_sent(Config) when is_list(Config) -> %%-------------------------------------------------------------------- %% Internal functions -send_raw(_,_, 0) -> +send_raw(Socket,_, 0) -> + ssl:send(Socket, <<>>), no_result_msg; send_raw(Socket, Data, N) -> ssl:send(Socket, Data), send_raw(Socket, Data, N-1). -passive_raw(_, _, 0) -> +passive_raw(Socket, _, 0) -> + {error, timeout} = ssl:recv(Socket, 0, 500), ok; passive_raw(Socket, Data, N) -> Length = length(Data), {ok, Data} = ssl:recv(Socket, Length), passive_raw(Socket, Data, N-1). -passive_recv_packet(_, _, 0) -> - ok; +passive_recv_packet(Socket, _, 0) -> + case ssl:recv(Socket, 0) of + {ok, []} -> + {error, timeout} = ssl:recv(Socket, 0, 500), + ok; + Other -> + {other, Other, ssl:session_info(Socket), 0} + end; passive_recv_packet(Socket, Data, N) -> case ssl:recv(Socket, 0) of {ok, Data} -> @@ -2060,7 +2227,8 @@ passive_recv_packet(Socket, Data, N) -> {other, Other, ssl:session_info(Socket), N} end. -send(_,_, 0) -> +send(Socket,_, 0) -> + ssl:send(Socket, <<>>), no_result_msg; send(Socket, Data, N) -> case ssl:send(Socket, [Data]) of @@ -2074,6 +2242,7 @@ send_incomplete(Socket, Data, N) -> send_incomplete(Socket, Data, N, <<>>). send_incomplete(Socket, _Data, 0, Prev) -> ssl:send(Socket, Prev), + ssl:send(Socket, [?uint32(0)]), no_result_msg; send_incomplete(Socket, Data, N, Prev) -> Length = size(Data), @@ -2102,8 +2271,13 @@ active_once_raw(Socket, Data, N, Acc) -> end end. -active_once_packet(_,_, 0) -> - ok; +active_once_packet(Socket,_, 0) -> + receive + {ssl, Socket, []} -> + ok; + {ssl, Socket, Other} -> + {other, Other, ssl:session_info(Socket), 0} + end; active_once_packet(Socket, Data, N) -> receive {ssl, Socket, Data} -> @@ -2115,7 +2289,7 @@ active_once_packet(Socket, Data, N) -> active_raw(Socket, Data, N) -> active_raw(Socket, Data, N, []). -active_raw(_, _, 0, _) -> +active_raw(_Socket, _, 0, _) -> ok; active_raw(Socket, Data, N, Acc) -> receive @@ -2130,8 +2304,13 @@ active_raw(Socket, Data, N, Acc) -> end end. -active_packet(_, _, 0) -> - ok; +active_packet(Socket, _, 0) -> + receive + {ssl, Socket, []} -> + ok; + Other -> + {other, Other, ssl:session_info(Socket), 0} + end; active_packet(Socket, Data, N) -> receive {ssl, Socket, Data} -> @@ -2155,8 +2334,14 @@ server_packet_decode(Socket, Packet) -> end, ok = ssl:send(Socket, Packet). -client_packet_decode(Socket, Packet) -> +client_packet_decode(Socket, Packet) when is_binary(Packet)-> <<P1:10/binary, P2/binary>> = Packet, + client_packet_decode(Socket, P1, P2, Packet); +client_packet_decode(Socket, [Head | Tail] = Packet) -> + client_packet_decode(Socket, [Head], Tail, Packet). + +client_packet_decode(Socket, P1, P2, Packet) -> + test_server:format("Packet: ~p ~n", [Packet]), ok = ssl:send(Socket, P1), ok = ssl:send(Socket, P2), receive @@ -2176,7 +2361,7 @@ server_header_decode(Socket, Packet, Result) -> end, ok = ssl:send(Socket, Packet), receive - {ssl, Socket, Result} -> ok; + {ssl, Socket, Result} -> ok; Other2 -> exit({?LINE, Other2}) end, ok = ssl:send(Socket, Packet). @@ -2192,6 +2377,44 @@ client_header_decode(Socket, Packet, Result) -> {ssl, Socket, Result} -> ok; Other2 -> exit({?LINE, Other2}) end. + +server_line_packet_decode(Socket, Packet) when is_binary(Packet) -> + [L1, L2] = string:tokens(binary_to_list(Packet), "\n"), + server_line_packet_decode(Socket, list_to_binary(L1 ++ "\n"), list_to_binary(L2 ++ "\n"), Packet); +server_line_packet_decode(Socket, Packet) -> + [L1, L2] = string:tokens(Packet, "\n"), + server_line_packet_decode(Socket, L1 ++ "\n", L2 ++ "\n", Packet). + +server_line_packet_decode(Socket, L1, L2, Packet) -> + receive + {ssl, Socket, L1} -> ok; + Other1 -> exit({?LINE, Other1}) + end, + receive + {ssl, Socket, L2} -> ok; + Other2 -> exit({?LINE, Other2}) + end, + ok = ssl:send(Socket, Packet). + +client_line_packet_decode(Socket, Packet) when is_binary(Packet)-> + <<P1:10/binary, P2/binary>> = Packet, + [L1, L2] = string:tokens(binary_to_list(Packet), "\n"), + client_line_packet_decode(Socket, P1, P2, list_to_binary(L1 ++ "\n"), list_to_binary(L2 ++ "\n")); +client_line_packet_decode(Socket, [Head | Tail] = Packet) -> + [L1, L2] = string:tokens(Packet, "\n"), + client_line_packet_decode(Socket, [Head], Tail, L1 ++ "\n", L2 ++ "\n"). + +client_line_packet_decode(Socket, P1, P2, L1, L2) -> + ok = ssl:send(Socket, P1), + ok = ssl:send(Socket, P2), + receive + {ssl, Socket, L1} -> ok; + Other1 -> exit({?LINE, Other1}) + end, + receive + {ssl, Socket, L2} -> ok; + Other2 -> exit({?LINE, Other2}) + end. add_tpkt_header(Data) when is_binary(Data) -> L = size(Data) + 4, diff --git a/lib/ssl/test/ssl_test_lib.erl b/lib/ssl/test/ssl_test_lib.erl index dd0818827a..ce164f7e4c 100644 --- a/lib/ssl/test/ssl_test_lib.erl +++ b/lib/ssl/test/ssl_test_lib.erl @@ -268,6 +268,8 @@ cert_options(Config) -> "client", "cacerts.pem"]), ClientCertFile = filename:join([?config(priv_dir, Config), "client", "cert.pem"]), + ClientCertFileDigitalSignatureOnly = filename:join([?config(priv_dir, Config), + "client", "digital_signature_only_cert.pem"]), ServerCaCertFile = filename:join([?config(priv_dir, Config), "server", "cacerts.pem"]), ServerCertFile = filename:join([?config(priv_dir, Config), @@ -292,6 +294,10 @@ cert_options(Config) -> {certfile, ClientCertFile}, {keyfile, ClientKeyFile}, {ssl_imp, new}]}, + {client_verification_opts_digital_signature_only, [{cacertfile, ClientCaCertFile}, + {certfile, ClientCertFileDigitalSignatureOnly}, + {keyfile, ClientKeyFile}, + {ssl_imp, new}]}, {server_opts, [{ssl_imp, new},{reuseaddr, true}, {certfile, ServerCertFile}, {keyfile, ServerKeyFile}]}, {server_verification_opts, [{ssl_imp, new},{reuseaddr, true}, @@ -326,7 +332,7 @@ make_dsa_cert(Config) -> {cacertfile, ServerCaCertFile}, {certfile, ServerCertFile}, {keyfile, ServerKeyFile}]}, {server_dsa_verify_opts, [{ssl_imp, new},{reuseaddr, true}, - {cacertfile, ServerCaCertFile}, + {cacertfile, ClientCaCertFile}, {certfile, ServerCertFile}, {keyfile, ServerKeyFile}, {verify, verify_peer}]}, {client_dsa_opts, [{ssl_imp, new},{reuseaddr, true}, @@ -346,9 +352,9 @@ make_dsa_cert_files(RoleStr, Config) -> KeyFile = filename:join([?config(priv_dir, Config), RoleStr, "dsa_key.pem"]), - public_key:der_to_pem(CaCertFile, [{cert, CaCert, not_encrypted}]), - public_key:der_to_pem(CertFile, [{cert, Cert, not_encrypted}]), - public_key:der_to_pem(KeyFile, [CertKey]), + der_to_pem(CaCertFile, [{'Certificate', CaCert, not_encrypted}]), + der_to_pem(CertFile, [{'Certificate', Cert, not_encrypted}]), + der_to_pem(KeyFile, [CertKey]), {CaCertFile, CertFile, KeyFile}. start_upgrade_server(Args) -> @@ -571,6 +577,14 @@ rsa_suites() -> end, ssl:cipher_suites()). +rsa_non_signed_suites() -> + lists:filter(fun({rsa, _, _}) -> + true; + (_) -> + false + end, + ssl:cipher_suites()). + dsa_suites() -> lists:filter(fun({dhe_dss, _, _}) -> true; @@ -601,3 +615,28 @@ openssl_dsa_suites() -> true end end, Ciphers). + +pem_to_der(File) -> + {ok, PemBin} = file:read_file(File), + public_key:pem_decode(PemBin). + +der_to_pem(File, Entries) -> + PemBin = public_key:pem_encode(Entries), + file:write_file(File, PemBin). + +cipher_result(Socket, Result) -> + Result = ssl:connection_info(Socket), + test_server:format("Successfull connect: ~p~n", [Result]), + %% Importante to send two packets here + %% to properly test "cipher state" handling + ssl:send(Socket, "Hello\n"), + receive + {ssl, Socket, "Hello\n"} -> + ssl:send(Socket, " world\n"), + receive + {ssl, Socket, " world\n"} -> + ok + end; + Other -> + {unexpected, Other} + end. diff --git a/lib/ssl/test/ssl_to_openssl_SUITE.erl b/lib/ssl/test/ssl_to_openssl_SUITE.erl index 75cfce0052..7f512f2ab9 100644 --- a/lib/ssl/test/ssl_to_openssl_SUITE.erl +++ b/lib/ssl/test/ssl_to_openssl_SUITE.erl @@ -1136,17 +1136,31 @@ cipher(CipherSuite, Version, Config, ClientOpts, ServerOpts) -> wait_for_openssl_server(), + ConnectionInfo = {ok, {Version, CipherSuite}}, + Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port}, {host, Hostname}, {from, self()}, - {mfa, {?MODULE, connection_info_result, []}}, + {mfa, {ssl_test_lib, cipher_result, [ConnectionInfo]}}, {options, [{ciphers,[CipherSuite]} | ClientOpts]}]), - - ClientMsg = {ok, {Version, CipherSuite}}, - - Result = ssl_test_lib:wait_for_result(Client, ClientMsg), + + port_command(OpenSslPort, "Hello\n"), + + receive + {Port, {data, _}} when is_port(Port) -> + ok + after 500 -> + test_server:format("Time out on openssl port, check that" + " the messages Hello and world are received" + " during close of port" , []), + ok + end, + + port_command(OpenSslPort, " world\n"), + + Result = ssl_test_lib:wait_for_result(Client, ok), close_port(OpenSslPort), %% Clean close down! diff --git a/lib/ssl/vsn.mk b/lib/ssl/vsn.mk index 254ee8b986..709a089892 100644 --- a/lib/ssl/vsn.mk +++ b/lib/ssl/vsn.mk @@ -1,63 +1 @@ -# -# %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% -# - SSL_VSN = 4.0.1 - -TICKETS = OTP-8721 - -#TICKETS_4.0 = OTP-8587\ -# OTP-8695 - -#TICKETS_3.11.1 = OTP-8679 \ -# OTP-7047 \ -# OTP-7049 \ -# OTP-8568 \ -# OTP-8588 - -#TICKETS_3.11 = OTP-8517 \ -# OTP-7046 \ -# OTP-8557 \ -# OTP-8560 \ -# OTP-8545 \ -# OTP-8554 - -#TICKETS_3.10.9 = OTP-8510 - -#TICKETS_3.10.8 = OTP-8372 OTP-8441 OTP-8459 -#TICKETS_3.10.7 = OTP-8260 OTP-8218 OTP-8250 - -#TICKETS_3.10.6 = OTP-8275 - -#TICKETS_3.10.5 = OTP-8224 OTP-8244 - -#TICKETS_3.10.4 = OTP-8137 - -#TICKETS_3.10.3 = OTP-8011 -#TICKETS_3.10.2 = OTP-7963 - -# TICKETS_3.10.1 = OTP-7878 \ -# OTP-7656 \ -# OTP-7870 \ -# OTP-7871 - -# TICKETS_3.10 = OTP-7258 \ -# OTP-6894 \ -# OTP-7037 \ -# OTP-7039 \ -# OTP-7150 diff --git a/lib/stdlib/doc/src/dets.xml b/lib/stdlib/doc/src/dets.xml index 8d1398d3b7..ad100d2cf5 100644 --- a/lib/stdlib/doc/src/dets.xml +++ b/lib/stdlib/doc/src/dets.xml @@ -109,7 +109,7 @@ bool() = true | false file() = string() int() = integer() >= 0 keypos() = integer() >= 1 -name() = atom() | ref() +name() = atom() | reference() no_slots() = integer() >= 0 | default object() = tuple() object_cont() = tuple() @@ -759,7 +759,7 @@ ok <fsummary>Open an existing Dets table.</fsummary> <type> <v>FileName = file()</v> - <v>Reference = ref()</v> + <v>Reference = reference()</v> </type> <desc> <p>Opens an existing table. If the table has not been properly diff --git a/lib/stdlib/doc/src/ets.xml b/lib/stdlib/doc/src/ets.xml index 5df60a92e5..dd4a289c61 100644 --- a/lib/stdlib/doc/src/ets.xml +++ b/lib/stdlib/doc/src/ets.xml @@ -1385,6 +1385,28 @@ is_integer(X), is_integer(Y), X + Y < 4711]]></code> </desc> </func> <func> + <name>select_count(Tab, MatchSpec) -> NumMatched</name> + <fsummary>Match the objects in an ETS table against a match_spec and returns the number of objects for which the match_spec returned 'true'</fsummary> + <type> + <v>Tab = tid() | atom()</v> + <v>Object = tuple()</v> + <v>MatchSpec = match_spec()</v> + <v>NumMatched = integer()</v> + </type> + <desc> + <p>Matches the objects in the table <c>Tab</c> using a + <seealso marker="#match_spec">match_spec</seealso>. If the + match_spec returns <c>true</c> for an object, that object + considered a match and is counted. For any other result from + the match_spec the object is not considered a match and is + therefore not counted.</p> + <p>The function could be described as a <c>match_delete/2</c> + that does not actually delete any elements, but only counts + them.</p> + <p>The function returns the number of objects matched.</p> + </desc> + </func> + <func> <name>select_delete(Tab, MatchSpec) -> NumDeleted</name> <fsummary>Match the objects in an ETS table against a match_spec and deletes objects where the match_spec returns 'true'</fsummary> <type> @@ -1411,25 +1433,82 @@ is_integer(X), is_integer(Y), X + Y < 4711]]></code> </desc> </func> <func> - <name>select_count(Tab, MatchSpec) -> NumMatched</name> - <fsummary>Match the objects in an ETS table against a match_spec and returns the number of objects for which the match_spec returned 'true'</fsummary> + <name>select_reverse(Tab, MatchSpec) -> [Match]</name> + <fsummary>Match the objects in an ETS table against a match_spec.</fsummary> <type> <v>Tab = tid() | atom()</v> - <v>Object = tuple()</v> + <v>Match = term()</v> <v>MatchSpec = match_spec()</v> - <v>NumMatched = integer()</v> </type> <desc> - <p>Matches the objects in the table <c>Tab</c> using a - <seealso marker="#match_spec">match_spec</seealso>. If the - match_spec returns <c>true</c> for an object, that object - considered a match and is counted. For any other result from - the match_spec the object is not considered a match and is - therefore not counted.</p> - <p>The function could be described as a <c>match_delete/2</c> - that does not actually delete any elements, but only counts - them.</p> - <p>The function returns the number of objects matched.</p> + + <p>Works like <c>select/2</c>, but returns the list in reverse + order for the <c>ordered_set</c> table type. For all other table + types, the return value is identical to that of <c>select/2</c>.</p> + + </desc> + </func> + <func> + <name>select_reverse(Tab, MatchSpec, Limit) -> {[Match],Continuation} | '$end_of_table'</name> + <fsummary>Match the objects in an ETS table against a match_spec and returns part of the answers.</fsummary> + <type> + <v>Tab = tid() | atom()</v> + <v>Match = term()</v> + <v>MatchSpec = match_spec()</v> + <v>Continuation = term()</v> + </type> + <desc> + + <p>Works like <c>select/3</c>, but for the <c>ordered_set</c> + table type, traversing is done starting at the last object in + Erlang term order and moves towards the first. For all other + table types, the return value is identical to that of + <c>select/3</c>.</p> + + <p>Note that this is <em>not</em> equivalent to + reversing the result list of a <c>select/3</c> call, as the result list + is not only reversed, but also contains the last <c>Limit</c> + matching objects in the table, not the first.</p> + + </desc> + </func> + <func> + <name>select_reverse(Continuation) -> {[Match],Continuation} | '$end_of_table'</name> + <fsummary>Continue matching objects in an ETS table.</fsummary> + <type> + <v>Match = term()</v> + <v>Continuation = term()</v> + </type> + <desc> + + <p>Continues a match started with + <c>ets:select_reverse/3</c>. If the table is an + <c>ordered_set</c>, the traversal of the table will continue + towards objects with keys earlier in the Erlang term order. The + returned list will also contain objects with keys in reverse + order.</p> + + <p>For all other table types, the behaviour is exatly that of <c>select/1</c>.</p> + <p>Example:</p> + <code> +1> T = ets:new(x,[ordered_set]). +2> [ ets:insert(T,{N}) || N <- lists:seq(1,10) ]. +... +3> {R0,C0} = ets:select_reverse(T,[{'_',[],['$_']}],4). +... +4> R0. +[{10},{9},{8},{7}] +5> {R1,C1} = ets:select_reverse(C0). +... +6> R1. +[{6},{5},{4},{3}] +7> {R2,C2} = ets:select_reverse(C1). +... +8> R2. +[{2},{1}] +9> '$end_of_table' = ets:select_reverse(C2). +... + </code> </desc> </func> <func> diff --git a/lib/stdlib/doc/src/io_protocol.xml b/lib/stdlib/doc/src/io_protocol.xml index b52e862a5c..a97d996d98 100644 --- a/lib/stdlib/doc/src/io_protocol.xml +++ b/lib/stdlib/doc/src/io_protocol.xml @@ -79,7 +79,7 @@ sends the reply to.</item> io_reply. The io-module in the Erlang standard library simply uses the pid() of the io_server as the ReplyAs datum, but a more complicated client could have several outstanding io-requests to the same server and -would then use i.e. a ref() or something else to differentiate among +would then use i.e. a reference() or something else to differentiate among the incoming io_reply's. The ReplyAs element should be considered opaque by the io_server. Note that the pid() of the server is not explicitly present in the io_reply. The reply can be sent from any diff --git a/lib/stdlib/src/ms_transform.erl b/lib/stdlib/src/ms_transform.erl index 78b1de6e16..a249dea525 100644 --- a/lib/stdlib/src/ms_transform.erl +++ b/lib/stdlib/src/ms_transform.erl @@ -43,6 +43,7 @@ -define(ERR_GENREMOTECALL,22). -define(ERR_GENBINCONSTRUCT,23). -define(ERR_GENDISALLOWEDOP,24). +-define(WARN_SHADOW_VAR,50). -define(ERR_GUARDMATCH,?ERR_GENMATCH+?ERROR_BASE_GUARD). -define(ERR_BODYMATCH,?ERR_GENMATCH+?ERROR_BASE_BODY). -define(ERR_GUARDLOCALCALL,?ERR_GENLOCALCALL+?ERROR_BASE_GUARD). @@ -63,8 +64,13 @@ -define(ERR_BODYDISALLOWEDOP,?ERR_GENDISALLOWEDOP+?ERROR_BASE_BODY). %% -%% Called by compiler or ets/dbg:fun2ms when errors occur +%% Called by compiler or ets/dbg:fun2ms when errors/warnings occur %% +format_error({?WARN_SHADOW_VAR,Name}) -> + lists:flatten( + io_lib:format("variable ~p shadowed in ms_transform fun head", + [Name])); + format_error(?ERR_NOFUN) -> "Parameter of ets/dbg:fun2ms/1 is not a literal fun"; format_error(?ERR_ETS_HEAD) -> @@ -182,7 +188,7 @@ format_error(Else) -> %% transform_from_shell(Dialect, Clauses, BoundEnvironment) -> SaveFilename = setup_filename(), - case catch ms_clause_list(1,Clauses,Dialect) of + case catch ms_clause_list(1,Clauses,Dialect,gb_sets:new()) of {'EXIT',Reason} -> cleanup_filename(SaveFilename), exit(Reason); @@ -207,6 +213,7 @@ transform_from_shell(Dialect, Clauses, BoundEnvironment) -> %% parse_transform(Forms, _Options) -> SaveFilename = setup_filename(), + %io:format("Forms: ~p~n",[Forms]), case catch forms(Forms) of {'EXIT',Reason} -> cleanup_filename(SaveFilename), @@ -215,12 +222,31 @@ parse_transform(Forms, _Options) -> {error, [{cleanup_filename(SaveFilename), [{Line, ?MODULE, R}]}], []}; Else -> - cleanup_filename(SaveFilename), + %io:format("Transformed into: ~p~n",[Else]), + case get_warnings() of + [] -> + cleanup_filename(SaveFilename), + Else; + WL -> + FName = cleanup_filename(SaveFilename) , + WList = [ {FName, [{L, ?MODULE, R}]} || {L,R} <- WL ], + {warning, Else, WList} + end + end. + +get_warnings() -> + case get(warnings) of + undefined -> + []; + Else -> Else end. +add_warning(Line,R) -> + put(warnings,[{Line,R}| get_warnings()]). + setup_filename() -> - {erase(filename),erase(records)}. + {erase(filename),erase(records),erase(warnings)}. put_filename(Name) -> put(filename,Name). @@ -235,7 +261,7 @@ get_records() -> Else -> Else end. -cleanup_filename({Old,OldRec}) -> +cleanup_filename({Old,OldRec,OldWarnings}) -> Ret = case erase(filename) of undefined -> "TOP_LEVEL"; @@ -248,6 +274,12 @@ cleanup_filename({Old,OldRec}) -> Rec -> put(records,Rec) end, + case OldWarnings of + undefined -> + erase(warnings); + Warn -> + put(warnings,Warn) + end, case Old of undefined -> Ret; @@ -285,42 +317,77 @@ form({function,Line,Name0,Arity0,Clauses0}) -> form(AnyOther) -> AnyOther. function(Name, Arity, Clauses0) -> - Clauses1 = clauses(Clauses0), + {Clauses1,_} = clauses(Clauses0,gb_sets:new()), {Name,Arity,Clauses1}. -clauses([C0|Cs]) -> - C1 = clause(C0), - [C1|clauses(Cs)]; -clauses([]) -> []. -clause({clause,Line,H0,G0,B0}) -> - B1 = copy(B0), - {clause,Line,H0,G0,B1}. +clauses([C0|Cs],Bound) -> + {C1,Bound1} = clause(C0,Bound), + {C2,Bound2} = clauses(Cs,Bound1), + {[C1|C2],Bound2}; +clauses([],Bound) -> {[],Bound}. +clause({clause,Line,H0,G0,B0},Bound) -> + {H1,Bound1} = copy(H0,Bound), + {B1,Bound2} = copy(B0,Bound1), + {{clause,Line,H1,G0,B1},Bound2}. copy({call,Line,{remote,_Line2,{atom,_Line3,ets},{atom,_Line4,fun2ms}}, - As0}) -> - transform_call(ets,Line,As0); + As0},Bound) -> + {transform_call(ets,Line,As0,Bound),Bound}; copy({call,Line,{remote,_Line2,{record_field,_Line3, {atom,_Line4,''},{atom,_Line5,ets}}, - {atom,_Line6,fun2ms}}, As0}) -> + {atom,_Line6,fun2ms}}, As0},Bound) -> %% Packages... - transform_call(ets,Line,As0); + {transform_call(ets,Line,As0,Bound),Bound}; copy({call,Line,{remote,_Line2,{atom,_Line3,dbg},{atom,_Line4,fun2ms}}, - As0}) -> - transform_call(dbg,Line,As0); -copy(T) when is_tuple(T) -> - list_to_tuple(copy_list(tuple_to_list(T))); -copy(L) when is_list(L) -> - copy_list(L); -copy(AnyOther) -> - AnyOther. + As0},Bound) -> + {transform_call(dbg,Line,As0,Bound),Bound}; +copy({match,Line,A,B},Bound) -> + {B1,Bound1} = copy(B,Bound), + {A1,Bound2} = copy(A,Bound), + {{match,Line,A1,B1},gb_sets:union(Bound1,Bound2)}; +copy({var,_Line,'_'} = VarDef,Bound) -> + {VarDef,Bound}; +copy({var,_Line,Name} = VarDef,Bound) -> + Bound1 = gb_sets:add(Name,Bound), + {VarDef,Bound1}; +copy({'fun',Line,{clauses,Clauses}},Bound) -> % Dont export bindings from funs + {NewClauses,_IgnoredBindings} = copy_list(Clauses,Bound), + {{'fun',Line,{clauses,NewClauses}},Bound}; +copy({'case',Line,Of,ClausesList},Bound) -> % Dont export bindings from funs + {NewOf,NewBind0} = copy(Of,Bound), + {NewClausesList,NewBindings} = copy_case_clauses(ClausesList,NewBind0,[]), + {{'case',Line,NewOf,NewClausesList},NewBindings}; +copy(T,Bound) when is_tuple(T) -> + {L,Bound1} = copy_list(tuple_to_list(T),Bound), + {list_to_tuple(L),Bound1}; +copy(L,Bound) when is_list(L) -> + copy_list(L,Bound); +copy(AnyOther,Bound) -> + {AnyOther,Bound}. -copy_list([H|T]) -> - [copy(H)|copy_list(T)]; -copy_list([]) -> - []. +copy_case_clauses([],Bound,AddSets) -> + ReallyAdded = gb_sets:intersection(AddSets), + {[],gb_sets:union(Bound,ReallyAdded)}; +copy_case_clauses([{clause,Line,Match,Guard,Clauses}|T],Bound,AddSets) -> + {NewMatch,MatchBinds} = copy(Match,Bound), + {NewGuard,GuardBinds} = copy(Guard,MatchBinds), %% Really no new binds + {NewClauses,AllBinds} = copy(Clauses,GuardBinds), + %% To limit the setsizes, I subtract what I had before the case clause + %% and add it in the end + AddedBinds = gb_sets:subtract(AllBinds,Bound), + {NewTail,ExportedBindings} = + copy_case_clauses(T,Bound,[AddedBinds | AddSets]), + {[{clause,Line,NewMatch,NewGuard,NewClauses}|NewTail],ExportedBindings}. -transform_call(Type,_Line,[{'fun',Line2,{clauses, ClauseList}}]) -> - ms_clause_list(Line2, ClauseList,Type); -transform_call(_Type,Line,_NoAbstractFun) -> +copy_list([H|T],Bound) -> + {C1,Bound1} = copy(H,Bound), + {C2,Bound2} = copy_list(T,Bound1), + {[C1|C2],Bound2}; +copy_list([],Bound) -> + {[],Bound}. + +transform_call(Type,_Line,[{'fun',Line2,{clauses, ClauseList}}],Bound) -> + ms_clause_list(Line2, ClauseList,Type,Bound); +transform_call(_Type,Line,_NoAbstractFun,_) -> throw({error,Line,?ERR_NOFUN}). % Fixup semicolons in guards @@ -329,18 +396,19 @@ ms_clause_expand({clause, Line, Parameters, Guard = [_,_|_], Body}) -> ms_clause_expand(_Other) -> false. -ms_clause_list(Line,[H|T],Type) -> +ms_clause_list(Line,[H|T],Type,Bound) -> case ms_clause_expand(H) of NewHead when is_list(NewHead) -> - ms_clause_list(Line,NewHead ++ T, Type); + ms_clause_list(Line,NewHead ++ T, Type, Bound); false -> - {cons, Line, ms_clause(H,Type), ms_clause_list(Line, T,Type)} + {cons, Line, ms_clause(H, Type, Bound), + ms_clause_list(Line, T, Type, Bound)} end; -ms_clause_list(Line,[],_) -> +ms_clause_list(Line,[],_,_) -> {nil,Line}. -ms_clause({clause, Line, Parameters, Guards, Body},Type) -> +ms_clause({clause, Line, Parameters, Guards, Body},Type,Bound) -> check_type(Line,Parameters,Type), - {MSHead,Bindings} = transform_head(Parameters), + {MSHead,Bindings} = transform_head(Parameters,Bound), MSGuards = transform_guards(Line, Guards, Bindings), MSBody = transform_body(Line,Body,Bindings), {tuple, Line, [MSHead,MSGuards,MSBody]}. @@ -627,29 +695,31 @@ tg(Other,B) -> Element = io_lib:format("unknown element ~w", [Other]), throw({error,unknown,{?ERR_GENELEMENT+B#tgd.eb,Element}}). -transform_head([V]) -> +transform_head([V],OuterBound) -> Bind = cre_bind(), - {NewV,NewBind} = toplevel_head_match(V,Bind), - th(NewV,NewBind). + {NewV,NewBind} = toplevel_head_match(V,Bind,OuterBound), + th(NewV,NewBind,OuterBound). -toplevel_head_match({match,_,{var,_,VName},Expr},B) -> +toplevel_head_match({match,Line,{var,_,VName},Expr},B,OB) -> + warn_var_clash(Line,VName,OB), {Expr,new_bind({VName,'$_'},B)}; -toplevel_head_match({match,_,Expr,{var,_,VName}},B) -> +toplevel_head_match({match,Line,Expr,{var,_,VName}},B,OB) -> + warn_var_clash(Line,VName,OB), {Expr,new_bind({VName,'$_'},B)}; -toplevel_head_match(Other,B) -> +toplevel_head_match(Other,B,_OB) -> {Other,B}. -th({record,Line,RName,RFields},B) -> +th({record,Line,RName,RFields},B,OB) -> % youch... RDefs = get_records(), {KeyList0,NewB} = lists:foldl(fun({record_field,_,{atom,_,Key},Value}, {L,B0}) -> - {NV,B1} = th(Value,B0), + {NV,B1} = th(Value,B0,OB), {[{Key,NV}|L],B1}; ({record_field,_,{var,_,'_'},Value}, {L,B0}) -> - {NV,B1} = th(Value,B0), + {NV,B1} = th(Value,B0,OB), {[{{default},NV}|L],B1}; (_,_) -> throw({error,Line,{?ERR_HEADBADREC, @@ -692,9 +762,9 @@ th({record,Line,RName,RFields},B) -> _ -> throw({error,Line,{?ERR_HEADBADREC,RName}}) end; -th({match,Line,_,_},_) -> +th({match,Line,_,_},_,_) -> throw({error,Line,?ERR_HEADMATCH}); -th({atom,Line,A},B) -> +th({atom,Line,A},B,_OB) -> case atom_to_list(A) of [$$|NL] -> case (catch list_to_integer(NL)) of @@ -706,10 +776,11 @@ th({atom,Line,A},B) -> _ -> {{atom,Line,A},B} end; -th({bin_element,_Line0,{var, Line, A},_,_},_) -> +th({bin_element,_Line0,{var, Line, A},_,_},_,_) -> throw({error,Line,{?ERR_HEADBINMATCH,A}}); -th({var,Line,Name},B) -> +th({var,Line,Name},B,OB) -> + warn_var_clash(Line,Name,OB), case lkup_bind(Name,B) of undefined -> NewB = new_bind(Name,B), @@ -717,16 +788,24 @@ th({var,Line,Name},B) -> Trans -> {{atom,Line,Trans},B} end; -th([H|T],B) -> - {NH,NB} = th(H,B), - {NT,NNB} = th(T,NB), +th([H|T],B,OB) -> + {NH,NB} = th(H,B,OB), + {NT,NNB} = th(T,NB,OB), {[NH|NT],NNB}; -th(T,B) when is_tuple(T) -> - {L,NB} = th(tuple_to_list(T),B), +th(T,B,OB) when is_tuple(T) -> + {L,NB} = th(tuple_to_list(T),B,OB), {list_to_tuple(L),NB}; -th(Nonstruct,B) -> +th(Nonstruct,B,_OB) -> {Nonstruct,B}. +warn_var_clash(Line,Name,OuterBound) -> + case gb_sets:is_member(Name,OuterBound) of + true -> + add_warning(Line,{?WARN_SHADOW_VAR,Name}); + _ -> + ok + end. + %% Could be more efficient... check_multi_field(_, _, [], _) -> ok; diff --git a/lib/stdlib/src/otp_internal.erl b/lib/stdlib/src/otp_internal.erl index 1514414e48..5c52dfcbf0 100644 --- a/lib/stdlib/src/otp_internal.erl +++ b/lib/stdlib/src/otp_internal.erl @@ -361,6 +361,12 @@ obsolete_1(erlang, concat_binary, 1) -> obsolete_1(ssl, peercert, 2) -> {deprecated,"deprecated (will be removed in R15A); use ssl:peercert/1 and public_key:pkix_decode_cert/2 instead"}; +%% Added in R14B. +obsolete_1(public_key, pem_to_der, 1) -> + {deprecated,"deprecated (will be removed in R15A); use file:read_file/1 and public_key:pem_decode/1"}; +obsolete_1(public_key, decode_private_key, A) when A =:= 1; A =:= 2 -> + {deprecated,{public_key,pem_entry_decode,1},"R15A"}; + obsolete_1(_, _, _) -> no. diff --git a/lib/stdlib/test/ets_SUITE.erl b/lib/stdlib/test/ets_SUITE.erl index 5d7e558601..7f39dbe21f 100644 --- a/lib/stdlib/test/ets_SUITE.erl +++ b/lib/stdlib/test/ets_SUITE.erl @@ -94,6 +94,8 @@ do_heavy_concurrent/1 ]). +-export([t_select_reverse/1]). + -include("test_server.hrl"). init_per_testcase(Case, Config) -> @@ -128,7 +130,7 @@ all(suite) -> match_heavy, fold, member, t_delete_object, t_init_table, t_whitebox, t_delete_all_objects, t_insert_list, t_test_ms, - t_select_delete, t_ets_dets, memory, + t_select_delete, t_ets_dets, memory, t_select_reverse, t_bucket_disappears, select_fail,t_insert_new, t_repair_continuation, otp_5340, otp_6338, otp_6842_select_1000, otp_7665, otp_8732, @@ -393,7 +395,7 @@ memory(Config) when is_list(Config) -> ?line erts_debug:set_internal_state(available_internal_state, true), ?line ok = chk_normal_tab_struct_size(), ?line L = [T1,T2,T3,T4] = fill_sets_int(1000), - ?line XRes1 = adjust_xmem(L, {14862,14072,14072,14078}), + ?line XRes1 = adjust_xmem(L, {13862,13072,13072,13078}), ?line Res1 = {?S(T1),?S(T2),?S(T3),?S(T4)}, ?line lists:foreach(fun(T) -> Before = ets:info(T,size), @@ -404,7 +406,7 @@ memory(Config) when is_list(Config) -> [Key, ets:info(T,type), Before, ets:info(T,size), Objs]) end, L), - ?line XRes2 = adjust_xmem(L, {14851,14062,14052,14058}), + ?line XRes2 = adjust_xmem(L, {13852,13063,13054,13060}), ?line Res2 = {?S(T1),?S(T2),?S(T3),?S(T4)}, ?line lists:foreach(fun(T) -> Before = ets:info(T,size), @@ -415,7 +417,7 @@ memory(Config) when is_list(Config) -> [Key, ets:info(T,type), Before, ets:info(T,size), Objs]) end, L), - ?line XRes3 = adjust_xmem(L, {14840,14052,14032,14038}), + ?line XRes3 = adjust_xmem(L, {13842,13054,13036,13042}), ?line Res3 = {?S(T1),?S(T2),?S(T3),?S(T4)}, ?line lists:foreach(fun(T) -> ?line ets:delete_all_objects(T) @@ -788,6 +790,67 @@ t_test_ms(Config) when is_list(Config) -> ?line true = (if is_list(String) -> true; true -> false end), ?line verify_etsmem(EtsMem). +t_select_reverse(doc) -> + ["Test the select reverse BIF's"]; +t_select_reverse(suite) -> + []; +t_select_reverse(Config) when is_list(Config) -> + ?line Table = ets:new(xxx, [ordered_set]), + ?line filltabint(Table,1000), + ?line A = lists:reverse(ets:select(Table,[{{'$1', '_'}, + [{'>', + {'rem', + '$1', 5}, + 2}], + ['$_']}])), + ?line A = ets:select_reverse(Table,[{{'$1', '_'}, + [{'>', + {'rem', + '$1', 5}, + 2}], + ['$_']}]), + ?line A = reverse_chunked(Table,[{{'$1', '_'}, + [{'>', + {'rem', + '$1', 5}, + 2}], + ['$_']}],3), + % A set/bag/duplicate_bag should get the same result regardless + % of select or select_reverse + ?line Table2 = ets:new(xxx, [set]), + ?line filltabint(Table2,1000), + ?line Table3 = ets:new(xxx, [bag]), + ?line filltabint(Table3,1000), + ?line Table4 = ets:new(xxx, [duplicate_bag]), + ?line filltabint(Table4,1000), + ?line lists:map(fun(Tab) -> + B = ets:select(Tab,[{{'$1', '_'}, + [{'>', + {'rem', + '$1', 5}, + 2}], + ['$_']}]), + B = ets:select_reverse(Tab,[{{'$1', '_'}, + [{'>', + {'rem', + '$1', 5}, + 2}], + ['$_']}]) + end,[Table2, Table3, Table4]), + ok. + + + +reverse_chunked(T,MS,N) -> + do_reverse_chunked(ets:select_reverse(T,MS,N),[]). + +do_reverse_chunked('$end_of_table',Acc) -> + lists:reverse(Acc); +do_reverse_chunked({L,C},Acc) -> + NewAcc = lists:reverse(L)++Acc, + do_reverse_chunked(ets:select_reverse(C), NewAcc). + + t_select_delete(doc) -> ["Test the ets:select_delete/2 and ets:select_count/2 BIF's"]; t_select_delete(suite) -> @@ -3942,7 +4005,7 @@ do_lookup_element(Tab, N, M) -> end. -heavy_concurrent(Config) -> +heavy_concurrent(_Config) -> repeat_for_opts(do_heavy_concurrent). do_heavy_concurrent(Opts) -> @@ -3961,7 +4024,7 @@ do_heavy_concurrent(Opts) -> ?line lists:foreach(fun (P) -> M = erlang:monitor(process, P), receive - {'DOWN', Mon, process, P, _} -> + {'DOWN', M, process, P, _} -> ok end end, diff --git a/lib/stdlib/test/ms_transform_SUITE.erl b/lib/stdlib/test/ms_transform_SUITE.erl index 79a0a9af89..2d90d5b823 100644 --- a/lib/stdlib/test/ms_transform_SUITE.erl +++ b/lib/stdlib/test/ms_transform_SUITE.erl @@ -37,6 +37,7 @@ -export([andalso_orelse/1]). -export([float_1_function/1]). -export([action_function/1]). +-export([warnings/1]). -export([init_per_testcase/2, fin_per_testcase/2]). init_per_testcase(_Func, Config) -> @@ -50,8 +51,90 @@ fin_per_testcase(_Func, Config) -> all(suite) -> [from_shell,basic_ets,basic_dbg,records,record_index,multipass, bitsyntax, record_defaults, andalso_orelse, float_1_function, action_function, + warnings, top_match, old_guards, autoimported, semicolon]. +%% This may be subject to change +-define(WARN_NUMBER_SHADOW,50). +warnings(suite) -> + []; +warnings(doc) -> + ["Check that shadowed variables in fun head generate warning"]; +warnings(Config) when is_list(Config) -> + ?line setup(Config), + Prog = <<"A=5, " + "ets:fun2ms(fun({A,B}) " + " when is_integer(A) and (A+5 > B) -> " + " A andalso B " + " end)">>, + ?line [{_,[{_,ms_transform,{?WARN_NUMBER_SHADOW,'A'}}]}] = + compile_ww(Prog), + Prog2 = <<"C=5, " + "ets:fun2ms(fun({A,B} = C) " + " when is_integer(A) and (A+5 > B) -> " + " {A andalso B,C} " + " end)">>, + ?line [{_,[{_,ms_transform,{?WARN_NUMBER_SHADOW,'C'}}]}] = + compile_ww(Prog2), + Rec3 = <<"-record(a,{a,b,c,d=foppa}).">>, + Prog3 = <<"A=3,C=5, " + "ets:fun2ms(fun(#a{a = A, b = B} = C) " + " when is_integer(A) and (A+5 > B) -> " + " {A andalso B,C} " + " end)">>, + ?line [{_,[{_,ms_transform,{?WARN_NUMBER_SHADOW,'A'}}, + {_,ms_transform,{?WARN_NUMBER_SHADOW,'C'}}]}] = + compile_ww(Rec3,Prog3), + Rec4 = <<"-record(a,{a,b,c,d=foppa}).">>, + Prog4 = <<"A=3,C=5, " + "F = fun(B) -> B*3 end," + "erlang:display(F(A))," + "ets:fun2ms(fun(#a{a = A, b = B} = C) " + " when is_integer(A) and (A+5 > B) -> " + " {A andalso B,C} " + " end)">>, + ?line [{_,[{_,ms_transform,{?WARN_NUMBER_SHADOW,'A'}}, + {_,ms_transform,{?WARN_NUMBER_SHADOW,'C'}}]}] = + compile_ww(Rec4,Prog4), + Rec5 = <<"-record(a,{a,b,c,d=foppa}).">>, + Prog5 = <<"A=3,C=5, " + "F = fun(B) -> B*3 end," + "erlang:display(F(A))," + "B = ets:fun2ms(fun(#a{a = A, b = B} = C) " + " when is_integer(A) and (A+5 > B) -> " + " {A andalso B,C} " + " end)">>, + ?line [{_,[{_,ms_transform,{?WARN_NUMBER_SHADOW,'A'}}, + {_,ms_transform,{?WARN_NUMBER_SHADOW,'C'}}]}] = + compile_ww(Rec5,Prog5), + Prog6 = <<" X=bar, " + " A = case X of" + " foo ->" + " foo;" + " Y ->" + " ets:fun2ms(fun(Y) ->" % This is a warning + " 3*Y" + " end)" + " end," + " ets:fun2ms(fun(Y) ->" % Y out of "scope" here, so no warning + " {3*Y,A}" + " end)">>, + ?line [{_,[{_,ms_transform,{?WARN_NUMBER_SHADOW,'Y'}}]}] = + compile_ww(Prog6), + Prog7 = <<" X=bar, " + " A = case X of" + " foo ->" + " Y = foo;" + " Y ->" + " bar" + " end," + " ets:fun2ms(fun(Y) ->" % Y exported from case and safe, so warn + " {3*Y,A}" + " end)">>, + ?line [{_,[{_,ms_transform,{?WARN_NUMBER_SHADOW,'Y'}}]}] = + compile_ww(Prog7), + ok. + andalso_orelse(suite) -> []; andalso_orelse(doc) -> @@ -721,6 +804,24 @@ compile_and_run(Records,Expr) -> code:load_binary(tmp,FN,Bin), tmp:tmp(). +compile_ww(Expr) -> + compile_ww(<<>>,Expr). +compile_ww(Records,Expr) -> + Prog = << + "-module(tmp).\n", + "-include_lib(\"stdlib/include/ms_transform.hrl\").\n", + "-export([tmp/0]).\n", + Records/binary,"\n", + "tmp() ->\n", + Expr/binary,".\n">>, + FN=temp_name(), + file:write_file(FN,Prog), + {ok,Forms} = epp:parse_file(FN,"",""), + {ok,tmp,_Bin,Wlist} = compile:forms(Forms,[return_warnings, + nowarn_unused_vars, + nowarn_unused_record]), + Wlist. + do_eval(String) -> {done,{ok,T,_},[]} = erl_scan:tokens( [], diff --git a/lib/stdlib/vsn.mk b/lib/stdlib/vsn.mk index 02ea6d9d68..1757d35160 100644 --- a/lib/stdlib/vsn.mk +++ b/lib/stdlib/vsn.mk @@ -1,20 +1 @@ -# -# %CopyrightBegin% -# -# Copyright Ericsson AB 1997-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% -# - STDLIB_VSN = 1.17.1 diff --git a/lib/tools/src/cover.erl b/lib/tools/src/cover.erl index 6501e05a6e..c4d1bd1d2f 100644 --- a/lib/tools/src/cover.erl +++ b/lib/tools/src/cover.erl @@ -2174,6 +2174,8 @@ escape_lt_and_gt1([$<|T],Acc) -> escape_lt_and_gt1(T,[$;,$t,$l,$&|Acc]); escape_lt_and_gt1([$>|T],Acc) -> escape_lt_and_gt1(T,[$;,$t,$g,$&|Acc]); +escape_lt_and_gt1([$&|T],Acc) -> + escape_lt_and_gt1(T,[$;,$p,$m,$a,$&|Acc]); escape_lt_and_gt1([],Acc) -> lists:reverse(Acc); escape_lt_and_gt1([H|T],Acc) -> diff --git a/lib/tools/vsn.mk b/lib/tools/vsn.mk index abe9a804f0..7a6f8c92a2 100644 --- a/lib/tools/vsn.mk +++ b/lib/tools/vsn.mk @@ -1,19 +1 @@ -# This is an -*-makefile-*- file. -# %CopyrightBegin% -# -# Copyright Ericsson AB 1997-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% - TOOLS_VSN = 2.6.6 diff --git a/lib/tv/vsn.mk b/lib/tv/vsn.mk index 93973489bc..d344c676a3 100644 --- a/lib/tv/vsn.mk +++ b/lib/tv/vsn.mk @@ -1,20 +1 @@ -# -# %CopyrightBegin% -# -# Copyright Ericsson AB 1997-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% -# - TV_VSN = 2.1.4.5 diff --git a/lib/wx/.gitignore b/lib/wx/.gitignore new file mode 100644 index 0000000000..fd76f078d7 --- /dev/null +++ b/lib/wx/.gitignore @@ -0,0 +1,2 @@ +test_log_* +wx_test_case_info diff --git a/lib/wx/api_gen/wxapi.conf b/lib/wx/api_gen/wxapi.conf index c91a9d7fff..6bafda5b9d 100644 --- a/lib/wx/api_gen/wxapi.conf +++ b/lib/wx/api_gen/wxapi.conf @@ -902,8 +902,8 @@ ['wxTreeCtrl','~wxTreeCtrl','AddRoot','AppendItem', %% Not on Windows 'AssignButtonsImageList','GetButtonsImageList','SetButtonsImageList' 'AssignImageList','AssignStateImageList','Collapse','CollapseAndReset', - 'Create','Delete','DeleteAllItems','DeleteChildren',{'EditLabel',1}, - %'EndEditLabel', + 'Create','Delete','DeleteAllItems','DeleteChildren', + {'EditLabel', [{"textCtrlClass", [nowhere]}]}, %'EndEditLabel', 'EnsureVisible','Expand','GetBoundingRect', 'GetChildrenCount','GetCount','GetEditControl', {'GetFirstChild',[{"cookie", out}]}, {'GetNextChild',[{"cookie", [both]}]}, @@ -1740,6 +1740,11 @@ %% 'GetItemRect', 'SetItemRect', 'GetToolId', 'SetToolId' %% ]}. +{class, wxSystemSettings, object, [], + [ + 'GetColour','GetFont','GetMetric','GetScreenType' + ]}. + {class, wxAuiNotebookEvent, wxNotifyEvent, [{acc, [{old_selection, "GetOldSelection()"}, {selection, "GetSelection()"}, diff --git a/lib/wx/c_src/gen/wxe_derived_dest.h b/lib/wx/c_src/gen/wxe_derived_dest.h index 57b0faa2cb..ad46a98c90 100644 --- a/lib/wx/c_src/gen/wxe_derived_dest.h +++ b/lib/wx/c_src/gen/wxe_derived_dest.h @@ -736,7 +736,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 222: delete (wxLogNull *) ptr; break; + case 223: delete (wxLogNull *) ptr; break; default: delete (wxObject *) ptr; }} diff --git a/lib/wx/c_src/gen/wxe_events.cpp b/lib/wx/c_src/gen/wxe_events.cpp index a6857442c9..692eef858c 100644 --- a/lib/wx/c_src/gen/wxe_events.cpp +++ b/lib/wx/c_src/gen/wxe_events.cpp @@ -266,41 +266,41 @@ void initEventTable() {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, 220, "command_auinotebook_page_close"}, - {wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGED, 220, "command_auinotebook_page_changed"}, - {wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGING, 220, "command_auinotebook_page_changing"}, - {wxEVT_COMMAND_AUINOTEBOOK_BUTTON, 220, "command_auinotebook_button"}, - {wxEVT_COMMAND_AUINOTEBOOK_BEGIN_DRAG, 220, "command_auinotebook_begin_drag"}, - {wxEVT_COMMAND_AUINOTEBOOK_END_DRAG, 220, "command_auinotebook_end_drag"}, - {wxEVT_COMMAND_AUINOTEBOOK_DRAG_MOTION, 220, "command_auinotebook_drag_motion"}, - {wxEVT_COMMAND_AUINOTEBOOK_ALLOW_DND, 220, "command_auinotebook_allow_dnd"}, + {wxEVT_COMMAND_AUINOTEBOOK_PAGE_CLOSE, 221, "command_auinotebook_page_close"}, + {wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGED, 221, "command_auinotebook_page_changed"}, + {wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGING, 221, "command_auinotebook_page_changing"}, + {wxEVT_COMMAND_AUINOTEBOOK_BUTTON, 221, "command_auinotebook_button"}, + {wxEVT_COMMAND_AUINOTEBOOK_BEGIN_DRAG, 221, "command_auinotebook_begin_drag"}, + {wxEVT_COMMAND_AUINOTEBOOK_END_DRAG, 221, "command_auinotebook_end_drag"}, + {wxEVT_COMMAND_AUINOTEBOOK_DRAG_MOTION, 221, "command_auinotebook_drag_motion"}, + {wxEVT_COMMAND_AUINOTEBOOK_ALLOW_DND, 221, "command_auinotebook_allow_dnd"}, #if wxCHECK_VERSION(2,8,5) - {wxEVT_COMMAND_AUINOTEBOOK_TAB_MIDDLE_DOWN, 220, "command_auinotebook_tab_middle_down"}, + {wxEVT_COMMAND_AUINOTEBOOK_TAB_MIDDLE_DOWN, 221, "command_auinotebook_tab_middle_down"}, #endif #if wxCHECK_VERSION(2,8,5) - {wxEVT_COMMAND_AUINOTEBOOK_TAB_MIDDLE_UP, 220, "command_auinotebook_tab_middle_up"}, + {wxEVT_COMMAND_AUINOTEBOOK_TAB_MIDDLE_UP, 221, "command_auinotebook_tab_middle_up"}, #endif #if wxCHECK_VERSION(2,8,5) - {wxEVT_COMMAND_AUINOTEBOOK_TAB_RIGHT_DOWN, 220, "command_auinotebook_tab_right_down"}, + {wxEVT_COMMAND_AUINOTEBOOK_TAB_RIGHT_DOWN, 221, "command_auinotebook_tab_right_down"}, #endif #if wxCHECK_VERSION(2,8,5) - {wxEVT_COMMAND_AUINOTEBOOK_TAB_RIGHT_UP, 220, "command_auinotebook_tab_right_up"}, + {wxEVT_COMMAND_AUINOTEBOOK_TAB_RIGHT_UP, 221, "command_auinotebook_tab_right_up"}, #endif #if wxCHECK_VERSION(2,8,5) - {wxEVT_COMMAND_AUINOTEBOOK_PAGE_CLOSED, 220, "command_auinotebook_page_closed"}, + {wxEVT_COMMAND_AUINOTEBOOK_PAGE_CLOSED, 221, "command_auinotebook_page_closed"}, #endif #if wxCHECK_VERSION(2,8,5) - {wxEVT_COMMAND_AUINOTEBOOK_DRAG_DONE, 220, "command_auinotebook_drag_done"}, + {wxEVT_COMMAND_AUINOTEBOOK_DRAG_DONE, 221, "command_auinotebook_drag_done"}, #endif #if wxCHECK_VERSION(2,8,5) - {wxEVT_COMMAND_AUINOTEBOOK_BG_DCLICK, 220, "command_auinotebook_bg_dclick"}, + {wxEVT_COMMAND_AUINOTEBOOK_BG_DCLICK, 221, "command_auinotebook_bg_dclick"}, #endif - {wxEVT_AUI_PANE_BUTTON, 221, "aui_pane_button"}, - {wxEVT_AUI_PANE_CLOSE, 221, "aui_pane_close"}, - {wxEVT_AUI_PANE_MAXIMIZE, 221, "aui_pane_maximize"}, - {wxEVT_AUI_PANE_RESTORE, 221, "aui_pane_restore"}, - {wxEVT_AUI_RENDER, 221, "aui_render"}, - {wxEVT_AUI_FIND_MANAGER, 221, "aui_find_manager"}, + {wxEVT_AUI_PANE_BUTTON, 222, "aui_pane_button"}, + {wxEVT_AUI_PANE_CLOSE, 222, "aui_pane_close"}, + {wxEVT_AUI_PANE_MAXIMIZE, 222, "aui_pane_maximize"}, + {wxEVT_AUI_PANE_RESTORE, 222, "aui_pane_restore"}, + {wxEVT_AUI_RENDER, 222, "aui_render"}, + {wxEVT_AUI_FIND_MANAGER, 222, "aui_find_manager"}, {-1, 0, } }; for(int i=0; event_types[i].ev_type != -1; i++) { @@ -778,7 +778,7 @@ case 219: {// wxHtmlLinkEvent rt.addTupleCount(3); break; } -case 220: {// wxAuiNotebookEvent +case 221: {// wxAuiNotebookEvent wxAuiNotebookEvent * ev = (wxAuiNotebookEvent *) event; wxAuiNotebook * GetDragSource = ev->GetDragSource(); evClass = (char*)"wxAuiNotebookEvent"; @@ -790,7 +790,7 @@ case 220: {// wxAuiNotebookEvent rt.addTupleCount(5); break; } -case 221: {// wxAuiManagerEvent +case 222: {// wxAuiManagerEvent wxAuiManagerEvent * ev = (wxAuiManagerEvent *) event; wxAuiManager * GetManager = ev->GetManager(); wxAuiPaneInfo * GetPane = ev->GetPane(); diff --git a/lib/wx/c_src/gen/wxe_funcs.cpp b/lib/wx/c_src/gen/wxe_funcs.cpp index fd496c2ccc..8c056bbb91 100644 --- a/lib/wx/c_src/gen/wxe_funcs.cpp +++ b/lib/wx/c_src/gen/wxe_funcs.cpp @@ -18501,6 +18501,15 @@ case wxTreeCtrl_DeleteChildren: { // wxTreeCtrl::DeleteChildren This->DeleteChildren(item); break; } +case wxTreeCtrl_EditLabel: { // wxTreeCtrl::EditLabel + wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4; + bp += 4; /* Align */ + wxTreeItemId item = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8; + if(!This) throw wxe_badarg(0); + wxTextCtrl * Result = (wxTextCtrl*)This->EditLabel(item); + rt.addRef(getRef((void *)Result,memenv), "wxTextCtrl"); + break; +} case wxTreeCtrl_EnsureVisible: { // wxTreeCtrl::EnsureVisible wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4; bp += 4; /* Align */ @@ -30976,6 +30985,36 @@ case wxHtmlLinkEvent_GetLinkInfo: { // wxHtmlLinkEvent::GetLinkInfo rt.add(Result); break; } +case wxSystemSettings_GetColour: { // wxSystemSettings::GetColour + wxSystemColour index = *(wxSystemColour *) bp; bp += 4;; + wxColour Result = wxSystemSettings::GetColour((wxSystemColour) index); + rt.add(Result); + break; +} +case wxSystemSettings_GetFont: { // wxSystemSettings::GetFont + wxSystemFont index = *(wxSystemFont *) bp; bp += 4;; + wxFont * Result = new wxFont(wxSystemSettings::GetFont((wxSystemFont) index)); newPtr((void *) Result,3, memenv);; + rt.addRef(getRef((void *)Result,memenv), "wxFont"); + break; +} +case wxSystemSettings_GetMetric: { // wxSystemSettings::GetMetric + wxWindow * win=NULL; + wxSystemMetric index = *(wxSystemMetric *) bp; bp += 4;; + bp += 4; /* Align */ + while( * (int*) bp) { switch (* (int*) bp) { + case 1: {bp += 4; +win = (wxWindow *) getPtr(bp,memenv); bp += 4; + } break; + }}; + int Result = wxSystemSettings::GetMetric((wxSystemMetric) index,win); + rt.addInt(Result); + break; +} +case wxSystemSettings_GetScreenType: { // wxSystemSettings::GetScreenType + int Result = wxSystemSettings::GetScreenType(); + rt.addInt(Result); + break; +} case wxAuiNotebookEvent_SetSelection: { // wxAuiNotebookEvent::SetSelection wxAuiNotebookEvent *This = (wxAuiNotebookEvent *) getPtr(bp,memenv); bp += 4; int * s = (int *) bp; bp += 4; @@ -31110,7 +31149,7 @@ case wxAuiManagerEvent_CanVeto: { // wxAuiManagerEvent::CanVeto } case wxLogNull_new: { // wxLogNull::wxLogNull wxLogNull * Result = new wxLogNull(); - newPtr((void *) Result, 222, memenv); + newPtr((void *) Result, 223, memenv); rt.addRef(getRef((void *)Result,memenv), "wxLogNull"); break; } diff --git a/lib/wx/c_src/gen/wxe_macros.h b/lib/wx/c_src/gen/wxe_macros.h index 415b7f0b29..4fb76f960b 100644 --- a/lib/wx/c_src/gen/wxe_macros.h +++ b/lib/wx/c_src/gen/wxe_macros.h @@ -1882,1444 +1882,1449 @@ #define wxTreeCtrl_Delete 2007 #define wxTreeCtrl_DeleteAllItems 2008 #define wxTreeCtrl_DeleteChildren 2009 -#define wxTreeCtrl_EnsureVisible 2010 -#define wxTreeCtrl_Expand 2011 -#define wxTreeCtrl_GetBoundingRect 2012 -#define wxTreeCtrl_GetChildrenCount 2014 -#define wxTreeCtrl_GetCount 2015 -#define wxTreeCtrl_GetEditControl 2016 -#define wxTreeCtrl_GetFirstChild 2017 -#define wxTreeCtrl_GetNextChild 2018 -#define wxTreeCtrl_GetFirstVisibleItem 2019 -#define wxTreeCtrl_GetImageList 2020 -#define wxTreeCtrl_GetIndent 2021 -#define wxTreeCtrl_GetItemBackgroundColour 2022 -#define wxTreeCtrl_GetItemData 2023 -#define wxTreeCtrl_GetItemFont 2024 -#define wxTreeCtrl_GetItemImage_1 2025 -#define wxTreeCtrl_GetItemImage_2 2026 -#define wxTreeCtrl_GetItemText 2027 -#define wxTreeCtrl_GetItemTextColour 2028 -#define wxTreeCtrl_GetLastChild 2029 -#define wxTreeCtrl_GetNextSibling 2030 -#define wxTreeCtrl_GetNextVisible 2031 -#define wxTreeCtrl_GetItemParent 2032 -#define wxTreeCtrl_GetPrevSibling 2033 -#define wxTreeCtrl_GetPrevVisible 2034 -#define wxTreeCtrl_GetRootItem 2035 -#define wxTreeCtrl_GetSelection 2036 -#define wxTreeCtrl_GetSelections 2037 -#define wxTreeCtrl_GetStateImageList 2038 -#define wxTreeCtrl_HitTest 2039 -#define wxTreeCtrl_InsertItem 2041 -#define wxTreeCtrl_IsBold 2042 -#define wxTreeCtrl_IsExpanded 2043 -#define wxTreeCtrl_IsSelected 2044 -#define wxTreeCtrl_IsVisible 2045 -#define wxTreeCtrl_ItemHasChildren 2046 -#define wxTreeCtrl_PrependItem 2047 -#define wxTreeCtrl_ScrollTo 2048 -#define wxTreeCtrl_SelectItem_1 2049 -#define wxTreeCtrl_SelectItem_2 2050 -#define wxTreeCtrl_SetIndent 2051 -#define wxTreeCtrl_SetImageList 2052 -#define wxTreeCtrl_SetItemBackgroundColour 2053 -#define wxTreeCtrl_SetItemBold 2054 -#define wxTreeCtrl_SetItemData 2055 -#define wxTreeCtrl_SetItemDropHighlight 2056 -#define wxTreeCtrl_SetItemFont 2057 -#define wxTreeCtrl_SetItemHasChildren 2058 -#define wxTreeCtrl_SetItemImage_2 2059 -#define wxTreeCtrl_SetItemImage_3 2060 -#define wxTreeCtrl_SetItemText 2061 -#define wxTreeCtrl_SetItemTextColour 2062 -#define wxTreeCtrl_SetStateImageList 2063 -#define wxTreeCtrl_SetWindowStyle 2064 -#define wxTreeCtrl_SortChildren 2065 -#define wxTreeCtrl_Toggle 2066 -#define wxTreeCtrl_ToggleItemSelection 2067 -#define wxTreeCtrl_Unselect 2068 -#define wxTreeCtrl_UnselectAll 2069 -#define wxTreeCtrl_UnselectItem 2070 -#define wxScrollBar_new_0 2071 -#define wxScrollBar_new_3 2072 -#define wxScrollBar_destruct 2073 -#define wxScrollBar_Create 2074 -#define wxScrollBar_GetRange 2075 -#define wxScrollBar_GetPageSize 2076 -#define wxScrollBar_GetThumbPosition 2077 -#define wxScrollBar_GetThumbSize 2078 -#define wxScrollBar_SetThumbPosition 2079 -#define wxScrollBar_SetScrollbar 2080 -#define wxSpinButton_new_2 2082 -#define wxSpinButton_new_0 2083 -#define wxSpinButton_Create 2084 -#define wxSpinButton_GetMax 2085 -#define wxSpinButton_GetMin 2086 -#define wxSpinButton_GetValue 2087 -#define wxSpinButton_SetRange 2088 -#define wxSpinButton_SetValue 2089 -#define wxSpinButton_destroy 2090 -#define wxSpinCtrl_new_0 2091 -#define wxSpinCtrl_new_2 2092 -#define wxSpinCtrl_Create 2094 -#define wxSpinCtrl_SetValue_1_1 2097 -#define wxSpinCtrl_SetValue_1_0 2098 -#define wxSpinCtrl_GetValue 2100 -#define wxSpinCtrl_SetRange 2102 -#define wxSpinCtrl_SetSelection 2103 -#define wxSpinCtrl_GetMin 2105 -#define wxSpinCtrl_GetMax 2107 -#define wxSpinCtrl_destroy 2108 -#define wxStaticText_new_0 2109 -#define wxStaticText_new_4 2110 -#define wxStaticText_Create 2111 -#define wxStaticText_GetLabel 2112 -#define wxStaticText_SetLabel 2113 -#define wxStaticText_Wrap 2114 -#define wxStaticText_destroy 2115 -#define wxStaticBitmap_new_0 2116 -#define wxStaticBitmap_new_4 2117 -#define wxStaticBitmap_Create 2118 -#define wxStaticBitmap_GetBitmap 2119 -#define wxStaticBitmap_SetBitmap 2120 -#define wxStaticBitmap_destroy 2121 -#define wxRadioBox_new 2122 -#define wxRadioBox_destruct 2124 -#define wxRadioBox_Create 2125 -#define wxRadioBox_Enable_2 2126 -#define wxRadioBox_Enable_1 2127 -#define wxRadioBox_GetSelection 2128 -#define wxRadioBox_GetString 2129 -#define wxRadioBox_SetSelection 2130 -#define wxRadioBox_Show_2 2131 -#define wxRadioBox_Show_1 2132 -#define wxRadioBox_GetColumnCount 2133 -#define wxRadioBox_GetItemHelpText 2134 -#define wxRadioBox_GetItemToolTip 2135 -#define wxRadioBox_GetItemFromPoint 2137 -#define wxRadioBox_GetRowCount 2138 -#define wxRadioBox_IsItemEnabled 2139 -#define wxRadioBox_IsItemShown 2140 -#define wxRadioBox_SetItemHelpText 2141 -#define wxRadioBox_SetItemToolTip 2142 -#define wxRadioButton_new_0 2143 -#define wxRadioButton_new_4 2144 -#define wxRadioButton_Create 2145 -#define wxRadioButton_GetValue 2146 -#define wxRadioButton_SetValue 2147 -#define wxRadioButton_destroy 2148 -#define wxSlider_new_6 2150 -#define wxSlider_new_0 2151 -#define wxSlider_Create 2152 -#define wxSlider_GetLineSize 2153 -#define wxSlider_GetMax 2154 -#define wxSlider_GetMin 2155 -#define wxSlider_GetPageSize 2156 -#define wxSlider_GetThumbLength 2157 -#define wxSlider_GetValue 2158 -#define wxSlider_SetLineSize 2159 -#define wxSlider_SetPageSize 2160 -#define wxSlider_SetRange 2161 -#define wxSlider_SetThumbLength 2162 -#define wxSlider_SetValue 2163 -#define wxSlider_destroy 2164 -#define wxDialog_new_4 2166 -#define wxDialog_new_0 2167 -#define wxDialog_destruct 2169 -#define wxDialog_Create 2170 -#define wxDialog_CreateButtonSizer 2171 -#define wxDialog_CreateStdDialogButtonSizer 2172 -#define wxDialog_EndModal 2173 -#define wxDialog_GetAffirmativeId 2174 -#define wxDialog_GetReturnCode 2175 -#define wxDialog_IsModal 2176 -#define wxDialog_SetAffirmativeId 2177 -#define wxDialog_SetReturnCode 2178 -#define wxDialog_Show 2179 -#define wxDialog_ShowModal 2180 -#define wxColourDialog_new_0 2181 -#define wxColourDialog_new_2 2182 -#define wxColourDialog_destruct 2183 -#define wxColourDialog_Create 2184 -#define wxColourDialog_GetColourData 2185 -#define wxColourData_new_0 2186 -#define wxColourData_new_1 2187 -#define wxColourData_destruct 2188 -#define wxColourData_GetChooseFull 2189 -#define wxColourData_GetColour 2190 -#define wxColourData_GetCustomColour 2192 -#define wxColourData_SetChooseFull 2193 -#define wxColourData_SetColour 2194 -#define wxColourData_SetCustomColour 2195 -#define wxPalette_new_0 2196 -#define wxPalette_new_4 2197 -#define wxPalette_destruct 2199 -#define wxPalette_Create 2200 -#define wxPalette_GetColoursCount 2201 -#define wxPalette_GetPixel 2202 -#define wxPalette_GetRGB 2203 -#define wxPalette_IsOk 2204 -#define wxDirDialog_new 2208 -#define wxDirDialog_destruct 2209 -#define wxDirDialog_GetPath 2210 -#define wxDirDialog_GetMessage 2211 -#define wxDirDialog_SetMessage 2212 -#define wxDirDialog_SetPath 2213 -#define wxFileDialog_new 2217 -#define wxFileDialog_destruct 2218 -#define wxFileDialog_GetDirectory 2219 -#define wxFileDialog_GetFilename 2220 -#define wxFileDialog_GetFilenames 2221 -#define wxFileDialog_GetFilterIndex 2222 -#define wxFileDialog_GetMessage 2223 -#define wxFileDialog_GetPath 2224 -#define wxFileDialog_GetPaths 2225 -#define wxFileDialog_GetWildcard 2226 -#define wxFileDialog_SetDirectory 2227 -#define wxFileDialog_SetFilename 2228 -#define wxFileDialog_SetFilterIndex 2229 -#define wxFileDialog_SetMessage 2230 -#define wxFileDialog_SetPath 2231 -#define wxFileDialog_SetWildcard 2232 -#define wxPickerBase_SetInternalMargin 2233 -#define wxPickerBase_GetInternalMargin 2234 -#define wxPickerBase_SetTextCtrlProportion 2235 -#define wxPickerBase_SetPickerCtrlProportion 2236 -#define wxPickerBase_GetTextCtrlProportion 2237 -#define wxPickerBase_GetPickerCtrlProportion 2238 -#define wxPickerBase_HasTextCtrl 2239 -#define wxPickerBase_GetTextCtrl 2240 -#define wxPickerBase_IsTextCtrlGrowable 2241 -#define wxPickerBase_SetPickerCtrlGrowable 2242 -#define wxPickerBase_SetTextCtrlGrowable 2243 -#define wxPickerBase_IsPickerCtrlGrowable 2244 -#define wxFilePickerCtrl_new_0 2245 -#define wxFilePickerCtrl_new_3 2246 -#define wxFilePickerCtrl_Create 2247 -#define wxFilePickerCtrl_GetPath 2248 -#define wxFilePickerCtrl_SetPath 2249 -#define wxFilePickerCtrl_destroy 2250 -#define wxDirPickerCtrl_new_0 2251 -#define wxDirPickerCtrl_new_3 2252 -#define wxDirPickerCtrl_Create 2253 -#define wxDirPickerCtrl_GetPath 2254 -#define wxDirPickerCtrl_SetPath 2255 -#define wxDirPickerCtrl_destroy 2256 -#define wxColourPickerCtrl_new_0 2257 -#define wxColourPickerCtrl_new_3 2258 -#define wxColourPickerCtrl_Create 2259 -#define wxColourPickerCtrl_GetColour 2260 -#define wxColourPickerCtrl_SetColour_1_1 2261 -#define wxColourPickerCtrl_SetColour_1_0 2262 -#define wxColourPickerCtrl_destroy 2263 -#define wxDatePickerCtrl_new_0 2264 -#define wxDatePickerCtrl_new_3 2265 -#define wxDatePickerCtrl_GetRange 2266 -#define wxDatePickerCtrl_GetValue 2267 -#define wxDatePickerCtrl_SetRange 2268 -#define wxDatePickerCtrl_SetValue 2269 -#define wxDatePickerCtrl_destroy 2270 -#define wxFontPickerCtrl_new_0 2271 -#define wxFontPickerCtrl_new_3 2272 -#define wxFontPickerCtrl_Create 2273 -#define wxFontPickerCtrl_GetSelectedFont 2274 -#define wxFontPickerCtrl_SetSelectedFont 2275 -#define wxFontPickerCtrl_GetMaxPointSize 2276 -#define wxFontPickerCtrl_SetMaxPointSize 2277 -#define wxFontPickerCtrl_destroy 2278 -#define wxFindReplaceDialog_new_0 2281 -#define wxFindReplaceDialog_new_4 2282 -#define wxFindReplaceDialog_destruct 2283 -#define wxFindReplaceDialog_Create 2284 -#define wxFindReplaceDialog_GetData 2285 -#define wxFindReplaceData_new_0 2286 -#define wxFindReplaceData_new_1 2287 -#define wxFindReplaceData_GetFindString 2288 -#define wxFindReplaceData_GetReplaceString 2289 -#define wxFindReplaceData_GetFlags 2290 -#define wxFindReplaceData_SetFlags 2291 -#define wxFindReplaceData_SetFindString 2292 -#define wxFindReplaceData_SetReplaceString 2293 -#define wxFindReplaceData_destroy 2294 -#define wxMultiChoiceDialog_new_0 2295 -#define wxMultiChoiceDialog_new_5 2297 -#define wxMultiChoiceDialog_GetSelections 2298 -#define wxMultiChoiceDialog_SetSelections 2299 -#define wxMultiChoiceDialog_destroy 2300 -#define wxSingleChoiceDialog_new_0 2301 -#define wxSingleChoiceDialog_new_5 2303 -#define wxSingleChoiceDialog_GetSelection 2304 -#define wxSingleChoiceDialog_GetStringSelection 2305 -#define wxSingleChoiceDialog_SetSelection 2306 -#define wxSingleChoiceDialog_destroy 2307 -#define wxTextEntryDialog_new 2308 -#define wxTextEntryDialog_GetValue 2309 -#define wxTextEntryDialog_SetValue 2310 -#define wxTextEntryDialog_destroy 2311 -#define wxPasswordEntryDialog_new 2312 -#define wxPasswordEntryDialog_destroy 2313 -#define wxFontData_new_0 2314 -#define wxFontData_new_1 2315 -#define wxFontData_destruct 2316 -#define wxFontData_EnableEffects 2317 -#define wxFontData_GetAllowSymbols 2318 -#define wxFontData_GetColour 2319 -#define wxFontData_GetChosenFont 2320 -#define wxFontData_GetEnableEffects 2321 -#define wxFontData_GetInitialFont 2322 -#define wxFontData_GetShowHelp 2323 -#define wxFontData_SetAllowSymbols 2324 -#define wxFontData_SetChosenFont 2325 -#define wxFontData_SetColour 2326 -#define wxFontData_SetInitialFont 2327 -#define wxFontData_SetRange 2328 -#define wxFontData_SetShowHelp 2329 -#define wxFontDialog_new_0 2333 -#define wxFontDialog_new_2 2335 -#define wxFontDialog_Create 2337 -#define wxFontDialog_GetFontData 2338 -#define wxFontDialog_destroy 2340 -#define wxProgressDialog_new 2341 -#define wxProgressDialog_destruct 2342 -#define wxProgressDialog_Resume 2343 -#define wxProgressDialog_Update_2 2344 -#define wxProgressDialog_Update_0 2345 -#define wxMessageDialog_new 2346 -#define wxMessageDialog_destruct 2347 -#define wxPageSetupDialog_new 2348 -#define wxPageSetupDialog_destruct 2349 -#define wxPageSetupDialog_GetPageSetupData 2350 -#define wxPageSetupDialog_ShowModal 2351 -#define wxPageSetupDialogData_new_0 2352 -#define wxPageSetupDialogData_new_1_0 2353 -#define wxPageSetupDialogData_new_1_1 2354 -#define wxPageSetupDialogData_destruct 2355 -#define wxPageSetupDialogData_EnableHelp 2356 -#define wxPageSetupDialogData_EnableMargins 2357 -#define wxPageSetupDialogData_EnableOrientation 2358 -#define wxPageSetupDialogData_EnablePaper 2359 -#define wxPageSetupDialogData_EnablePrinter 2360 -#define wxPageSetupDialogData_GetDefaultMinMargins 2361 -#define wxPageSetupDialogData_GetEnableMargins 2362 -#define wxPageSetupDialogData_GetEnableOrientation 2363 -#define wxPageSetupDialogData_GetEnablePaper 2364 -#define wxPageSetupDialogData_GetEnablePrinter 2365 -#define wxPageSetupDialogData_GetEnableHelp 2366 -#define wxPageSetupDialogData_GetDefaultInfo 2367 -#define wxPageSetupDialogData_GetMarginTopLeft 2368 -#define wxPageSetupDialogData_GetMarginBottomRight 2369 -#define wxPageSetupDialogData_GetMinMarginTopLeft 2370 -#define wxPageSetupDialogData_GetMinMarginBottomRight 2371 -#define wxPageSetupDialogData_GetPaperId 2372 -#define wxPageSetupDialogData_GetPaperSize 2373 -#define wxPageSetupDialogData_GetPrintData 2375 -#define wxPageSetupDialogData_IsOk 2376 -#define wxPageSetupDialogData_SetDefaultInfo 2377 -#define wxPageSetupDialogData_SetDefaultMinMargins 2378 -#define wxPageSetupDialogData_SetMarginTopLeft 2379 -#define wxPageSetupDialogData_SetMarginBottomRight 2380 -#define wxPageSetupDialogData_SetMinMarginTopLeft 2381 -#define wxPageSetupDialogData_SetMinMarginBottomRight 2382 -#define wxPageSetupDialogData_SetPaperId 2383 -#define wxPageSetupDialogData_SetPaperSize_1_1 2384 -#define wxPageSetupDialogData_SetPaperSize_1_0 2385 -#define wxPageSetupDialogData_SetPrintData 2386 -#define wxPrintDialog_new_2_0 2387 -#define wxPrintDialog_new_2_1 2388 -#define wxPrintDialog_destruct 2389 -#define wxPrintDialog_GetPrintDialogData 2390 -#define wxPrintDialog_GetPrintDC 2391 -#define wxPrintDialogData_new_0 2392 -#define wxPrintDialogData_new_1_1 2393 -#define wxPrintDialogData_new_1_0 2394 -#define wxPrintDialogData_destruct 2395 -#define wxPrintDialogData_EnableHelp 2396 -#define wxPrintDialogData_EnablePageNumbers 2397 -#define wxPrintDialogData_EnablePrintToFile 2398 -#define wxPrintDialogData_EnableSelection 2399 -#define wxPrintDialogData_GetAllPages 2400 -#define wxPrintDialogData_GetCollate 2401 -#define wxPrintDialogData_GetFromPage 2402 -#define wxPrintDialogData_GetMaxPage 2403 -#define wxPrintDialogData_GetMinPage 2404 -#define wxPrintDialogData_GetNoCopies 2405 -#define wxPrintDialogData_GetPrintData 2406 -#define wxPrintDialogData_GetPrintToFile 2407 -#define wxPrintDialogData_GetSelection 2408 -#define wxPrintDialogData_GetToPage 2409 -#define wxPrintDialogData_IsOk 2410 -#define wxPrintDialogData_SetCollate 2411 -#define wxPrintDialogData_SetFromPage 2412 -#define wxPrintDialogData_SetMaxPage 2413 -#define wxPrintDialogData_SetMinPage 2414 -#define wxPrintDialogData_SetNoCopies 2415 -#define wxPrintDialogData_SetPrintData 2416 -#define wxPrintDialogData_SetPrintToFile 2417 -#define wxPrintDialogData_SetSelection 2418 -#define wxPrintDialogData_SetToPage 2419 -#define wxPrintData_new_0 2420 -#define wxPrintData_new_1 2421 -#define wxPrintData_destruct 2422 -#define wxPrintData_GetCollate 2423 -#define wxPrintData_GetBin 2424 -#define wxPrintData_GetColour 2425 -#define wxPrintData_GetDuplex 2426 -#define wxPrintData_GetNoCopies 2427 -#define wxPrintData_GetOrientation 2428 -#define wxPrintData_GetPaperId 2429 -#define wxPrintData_GetPrinterName 2430 -#define wxPrintData_GetQuality 2431 -#define wxPrintData_IsOk 2432 -#define wxPrintData_SetBin 2433 -#define wxPrintData_SetCollate 2434 -#define wxPrintData_SetColour 2435 -#define wxPrintData_SetDuplex 2436 -#define wxPrintData_SetNoCopies 2437 -#define wxPrintData_SetOrientation 2438 -#define wxPrintData_SetPaperId 2439 -#define wxPrintData_SetPrinterName 2440 -#define wxPrintData_SetQuality 2441 -#define wxPrintPreview_new_2 2444 -#define wxPrintPreview_new_3 2445 -#define wxPrintPreview_destruct 2447 -#define wxPrintPreview_GetCanvas 2448 -#define wxPrintPreview_GetCurrentPage 2449 -#define wxPrintPreview_GetFrame 2450 -#define wxPrintPreview_GetMaxPage 2451 -#define wxPrintPreview_GetMinPage 2452 -#define wxPrintPreview_GetPrintout 2453 -#define wxPrintPreview_GetPrintoutForPrinting 2454 -#define wxPrintPreview_IsOk 2455 -#define wxPrintPreview_PaintPage 2456 -#define wxPrintPreview_Print 2457 -#define wxPrintPreview_RenderPage 2458 -#define wxPrintPreview_SetCanvas 2459 -#define wxPrintPreview_SetCurrentPage 2460 -#define wxPrintPreview_SetFrame 2461 -#define wxPrintPreview_SetPrintout 2462 -#define wxPrintPreview_SetZoom 2463 -#define wxPreviewFrame_new 2464 -#define wxPreviewFrame_destruct 2465 -#define wxPreviewFrame_CreateControlBar 2466 -#define wxPreviewFrame_CreateCanvas 2467 -#define wxPreviewFrame_Initialize 2468 -#define wxPreviewFrame_OnCloseWindow 2469 -#define wxPreviewControlBar_new 2470 -#define wxPreviewControlBar_destruct 2471 -#define wxPreviewControlBar_CreateButtons 2472 -#define wxPreviewControlBar_GetPrintPreview 2473 -#define wxPreviewControlBar_GetZoomControl 2474 -#define wxPreviewControlBar_SetZoomControl 2475 -#define wxPrinter_new 2477 -#define wxPrinter_CreateAbortWindow 2478 -#define wxPrinter_GetAbort 2479 -#define wxPrinter_GetLastError 2480 -#define wxPrinter_GetPrintDialogData 2481 -#define wxPrinter_Print 2482 -#define wxPrinter_PrintDialog 2483 -#define wxPrinter_ReportError 2484 -#define wxPrinter_Setup 2485 -#define wxPrinter_destroy 2486 -#define wxXmlResource_new_1 2487 -#define wxXmlResource_new_2 2488 -#define wxXmlResource_destruct 2489 -#define wxXmlResource_AttachUnknownControl 2490 -#define wxXmlResource_ClearHandlers 2491 -#define wxXmlResource_CompareVersion 2492 -#define wxXmlResource_Get 2493 -#define wxXmlResource_GetFlags 2494 -#define wxXmlResource_GetVersion 2495 -#define wxXmlResource_GetXRCID 2496 -#define wxXmlResource_InitAllHandlers 2497 -#define wxXmlResource_Load 2498 -#define wxXmlResource_LoadBitmap 2499 -#define wxXmlResource_LoadDialog_2 2500 -#define wxXmlResource_LoadDialog_3 2501 -#define wxXmlResource_LoadFrame_2 2502 -#define wxXmlResource_LoadFrame_3 2503 -#define wxXmlResource_LoadIcon 2504 -#define wxXmlResource_LoadMenu 2505 -#define wxXmlResource_LoadMenuBar_2 2506 -#define wxXmlResource_LoadMenuBar_1 2507 -#define wxXmlResource_LoadPanel_2 2508 -#define wxXmlResource_LoadPanel_3 2509 -#define wxXmlResource_LoadToolBar 2510 -#define wxXmlResource_Set 2511 -#define wxXmlResource_SetFlags 2512 -#define wxXmlResource_Unload 2513 -#define wxXmlResource_xrcctrl 2514 -#define wxHtmlEasyPrinting_new 2515 -#define wxHtmlEasyPrinting_destruct 2516 -#define wxHtmlEasyPrinting_GetPrintData 2517 -#define wxHtmlEasyPrinting_GetPageSetupData 2518 -#define wxHtmlEasyPrinting_PreviewFile 2519 -#define wxHtmlEasyPrinting_PreviewText 2520 -#define wxHtmlEasyPrinting_PrintFile 2521 -#define wxHtmlEasyPrinting_PrintText 2522 -#define wxHtmlEasyPrinting_PageSetup 2523 -#define wxHtmlEasyPrinting_SetFonts 2524 -#define wxHtmlEasyPrinting_SetHeader 2525 -#define wxHtmlEasyPrinting_SetFooter 2526 -#define wxGLCanvas_new_2 2528 -#define wxGLCanvas_new_3_1 2529 -#define wxGLCanvas_new_3_0 2530 -#define wxGLCanvas_GetContext 2531 -#define wxGLCanvas_SetCurrent 2533 -#define wxGLCanvas_SwapBuffers 2534 -#define wxGLCanvas_destroy 2535 -#define wxAuiManager_new 2536 -#define wxAuiManager_destruct 2537 -#define wxAuiManager_AddPane_2_1 2538 -#define wxAuiManager_AddPane_3 2539 -#define wxAuiManager_AddPane_2_0 2540 -#define wxAuiManager_DetachPane 2541 -#define wxAuiManager_GetAllPanes 2542 -#define wxAuiManager_GetArtProvider 2543 -#define wxAuiManager_GetDockSizeConstraint 2544 -#define wxAuiManager_GetFlags 2545 -#define wxAuiManager_GetManagedWindow 2546 -#define wxAuiManager_GetManager 2547 -#define wxAuiManager_GetPane_1_1 2548 -#define wxAuiManager_GetPane_1_0 2549 -#define wxAuiManager_HideHint 2550 -#define wxAuiManager_InsertPane 2551 -#define wxAuiManager_LoadPaneInfo 2552 -#define wxAuiManager_LoadPerspective 2553 -#define wxAuiManager_SavePaneInfo 2554 -#define wxAuiManager_SavePerspective 2555 -#define wxAuiManager_SetArtProvider 2556 -#define wxAuiManager_SetDockSizeConstraint 2557 -#define wxAuiManager_SetFlags 2558 -#define wxAuiManager_SetManagedWindow 2559 -#define wxAuiManager_ShowHint 2560 -#define wxAuiManager_UnInit 2561 -#define wxAuiManager_Update 2562 -#define wxAuiPaneInfo_new_0 2563 -#define wxAuiPaneInfo_new_1 2564 -#define wxAuiPaneInfo_destruct 2565 -#define wxAuiPaneInfo_BestSize_1 2566 -#define wxAuiPaneInfo_BestSize_2 2567 -#define wxAuiPaneInfo_Bottom 2568 -#define wxAuiPaneInfo_BottomDockable 2569 -#define wxAuiPaneInfo_Caption 2570 -#define wxAuiPaneInfo_CaptionVisible 2571 -#define wxAuiPaneInfo_Centre 2572 -#define wxAuiPaneInfo_CentrePane 2573 -#define wxAuiPaneInfo_CloseButton 2574 -#define wxAuiPaneInfo_DefaultPane 2575 -#define wxAuiPaneInfo_DestroyOnClose 2576 -#define wxAuiPaneInfo_Direction 2577 -#define wxAuiPaneInfo_Dock 2578 -#define wxAuiPaneInfo_Dockable 2579 -#define wxAuiPaneInfo_Fixed 2580 -#define wxAuiPaneInfo_Float 2581 -#define wxAuiPaneInfo_Floatable 2582 -#define wxAuiPaneInfo_FloatingPosition_1 2583 -#define wxAuiPaneInfo_FloatingPosition_2 2584 -#define wxAuiPaneInfo_FloatingSize_1 2585 -#define wxAuiPaneInfo_FloatingSize_2 2586 -#define wxAuiPaneInfo_Gripper 2587 -#define wxAuiPaneInfo_GripperTop 2588 -#define wxAuiPaneInfo_HasBorder 2589 -#define wxAuiPaneInfo_HasCaption 2590 -#define wxAuiPaneInfo_HasCloseButton 2591 -#define wxAuiPaneInfo_HasFlag 2592 -#define wxAuiPaneInfo_HasGripper 2593 -#define wxAuiPaneInfo_HasGripperTop 2594 -#define wxAuiPaneInfo_HasMaximizeButton 2595 -#define wxAuiPaneInfo_HasMinimizeButton 2596 -#define wxAuiPaneInfo_HasPinButton 2597 -#define wxAuiPaneInfo_Hide 2598 -#define wxAuiPaneInfo_IsBottomDockable 2599 -#define wxAuiPaneInfo_IsDocked 2600 -#define wxAuiPaneInfo_IsFixed 2601 -#define wxAuiPaneInfo_IsFloatable 2602 -#define wxAuiPaneInfo_IsFloating 2603 -#define wxAuiPaneInfo_IsLeftDockable 2604 -#define wxAuiPaneInfo_IsMovable 2605 -#define wxAuiPaneInfo_IsOk 2606 -#define wxAuiPaneInfo_IsResizable 2607 -#define wxAuiPaneInfo_IsRightDockable 2608 -#define wxAuiPaneInfo_IsShown 2609 -#define wxAuiPaneInfo_IsToolbar 2610 -#define wxAuiPaneInfo_IsTopDockable 2611 -#define wxAuiPaneInfo_Layer 2612 -#define wxAuiPaneInfo_Left 2613 -#define wxAuiPaneInfo_LeftDockable 2614 -#define wxAuiPaneInfo_MaxSize_1 2615 -#define wxAuiPaneInfo_MaxSize_2 2616 -#define wxAuiPaneInfo_MaximizeButton 2617 -#define wxAuiPaneInfo_MinSize_1 2618 -#define wxAuiPaneInfo_MinSize_2 2619 -#define wxAuiPaneInfo_MinimizeButton 2620 -#define wxAuiPaneInfo_Movable 2621 -#define wxAuiPaneInfo_Name 2622 -#define wxAuiPaneInfo_PaneBorder 2623 -#define wxAuiPaneInfo_PinButton 2624 -#define wxAuiPaneInfo_Position 2625 -#define wxAuiPaneInfo_Resizable 2626 -#define wxAuiPaneInfo_Right 2627 -#define wxAuiPaneInfo_RightDockable 2628 -#define wxAuiPaneInfo_Row 2629 -#define wxAuiPaneInfo_SafeSet 2630 -#define wxAuiPaneInfo_SetFlag 2631 -#define wxAuiPaneInfo_Show 2632 -#define wxAuiPaneInfo_ToolbarPane 2633 -#define wxAuiPaneInfo_Top 2634 -#define wxAuiPaneInfo_TopDockable 2635 -#define wxAuiPaneInfo_Window 2636 -#define wxAuiNotebook_new_0 2637 -#define wxAuiNotebook_new_2 2638 -#define wxAuiNotebook_AddPage 2639 -#define wxAuiNotebook_Create 2640 -#define wxAuiNotebook_DeletePage 2641 -#define wxAuiNotebook_GetArtProvider 2642 -#define wxAuiNotebook_GetPage 2643 -#define wxAuiNotebook_GetPageBitmap 2644 -#define wxAuiNotebook_GetPageCount 2645 -#define wxAuiNotebook_GetPageIndex 2646 -#define wxAuiNotebook_GetPageText 2647 -#define wxAuiNotebook_GetSelection 2648 -#define wxAuiNotebook_InsertPage 2649 -#define wxAuiNotebook_RemovePage 2650 -#define wxAuiNotebook_SetArtProvider 2651 -#define wxAuiNotebook_SetFont 2652 -#define wxAuiNotebook_SetPageBitmap 2653 -#define wxAuiNotebook_SetPageText 2654 -#define wxAuiNotebook_SetSelection 2655 -#define wxAuiNotebook_SetTabCtrlHeight 2656 -#define wxAuiNotebook_SetUniformBitmapSize 2657 -#define wxAuiNotebook_destroy 2658 -#define wxMDIParentFrame_new_0 2659 -#define wxMDIParentFrame_new_4 2660 -#define wxMDIParentFrame_destruct 2661 -#define wxMDIParentFrame_ActivateNext 2662 -#define wxMDIParentFrame_ActivatePrevious 2663 -#define wxMDIParentFrame_ArrangeIcons 2664 -#define wxMDIParentFrame_Cascade 2665 -#define wxMDIParentFrame_Create 2666 -#define wxMDIParentFrame_GetActiveChild 2667 -#define wxMDIParentFrame_GetClientWindow 2668 -#define wxMDIParentFrame_Tile 2669 -#define wxMDIChildFrame_new_0 2670 -#define wxMDIChildFrame_new_4 2671 -#define wxMDIChildFrame_destruct 2672 -#define wxMDIChildFrame_Activate 2673 -#define wxMDIChildFrame_Create 2674 -#define wxMDIChildFrame_Maximize 2675 -#define wxMDIChildFrame_Restore 2676 -#define wxMDIClientWindow_new_0 2677 -#define wxMDIClientWindow_new_2 2678 -#define wxMDIClientWindow_destruct 2679 -#define wxMDIClientWindow_CreateClient 2680 -#define wxLayoutAlgorithm_new 2681 -#define wxLayoutAlgorithm_LayoutFrame 2682 -#define wxLayoutAlgorithm_LayoutMDIFrame 2683 -#define wxLayoutAlgorithm_LayoutWindow 2684 -#define wxLayoutAlgorithm_destroy 2685 -#define wxEvent_GetId 2686 -#define wxEvent_GetSkipped 2687 -#define wxEvent_GetTimestamp 2688 -#define wxEvent_IsCommandEvent 2689 -#define wxEvent_ResumePropagation 2690 -#define wxEvent_ShouldPropagate 2691 -#define wxEvent_Skip 2692 -#define wxEvent_StopPropagation 2693 -#define wxCommandEvent_getClientData 2694 -#define wxCommandEvent_GetExtraLong 2695 -#define wxCommandEvent_GetInt 2696 -#define wxCommandEvent_GetSelection 2697 -#define wxCommandEvent_GetString 2698 -#define wxCommandEvent_IsChecked 2699 -#define wxCommandEvent_IsSelection 2700 -#define wxCommandEvent_SetInt 2701 -#define wxCommandEvent_SetString 2702 -#define wxScrollEvent_GetOrientation 2703 -#define wxScrollEvent_GetPosition 2704 -#define wxScrollWinEvent_GetOrientation 2705 -#define wxScrollWinEvent_GetPosition 2706 -#define wxMouseEvent_AltDown 2707 -#define wxMouseEvent_Button 2708 -#define wxMouseEvent_ButtonDClick 2709 -#define wxMouseEvent_ButtonDown 2710 -#define wxMouseEvent_ButtonUp 2711 -#define wxMouseEvent_CmdDown 2712 -#define wxMouseEvent_ControlDown 2713 -#define wxMouseEvent_Dragging 2714 -#define wxMouseEvent_Entering 2715 -#define wxMouseEvent_GetButton 2716 -#define wxMouseEvent_GetPosition 2719 -#define wxMouseEvent_GetLogicalPosition 2720 -#define wxMouseEvent_GetLinesPerAction 2721 -#define wxMouseEvent_GetWheelRotation 2722 -#define wxMouseEvent_GetWheelDelta 2723 -#define wxMouseEvent_GetX 2724 -#define wxMouseEvent_GetY 2725 -#define wxMouseEvent_IsButton 2726 -#define wxMouseEvent_IsPageScroll 2727 -#define wxMouseEvent_Leaving 2728 -#define wxMouseEvent_LeftDClick 2729 -#define wxMouseEvent_LeftDown 2730 -#define wxMouseEvent_LeftIsDown 2731 -#define wxMouseEvent_LeftUp 2732 -#define wxMouseEvent_MetaDown 2733 -#define wxMouseEvent_MiddleDClick 2734 -#define wxMouseEvent_MiddleDown 2735 -#define wxMouseEvent_MiddleIsDown 2736 -#define wxMouseEvent_MiddleUp 2737 -#define wxMouseEvent_Moving 2738 -#define wxMouseEvent_RightDClick 2739 -#define wxMouseEvent_RightDown 2740 -#define wxMouseEvent_RightIsDown 2741 -#define wxMouseEvent_RightUp 2742 -#define wxMouseEvent_ShiftDown 2743 -#define wxSetCursorEvent_GetCursor 2744 -#define wxSetCursorEvent_GetX 2745 -#define wxSetCursorEvent_GetY 2746 -#define wxSetCursorEvent_HasCursor 2747 -#define wxSetCursorEvent_SetCursor 2748 -#define wxKeyEvent_AltDown 2749 -#define wxKeyEvent_CmdDown 2750 -#define wxKeyEvent_ControlDown 2751 -#define wxKeyEvent_GetKeyCode 2752 -#define wxKeyEvent_GetModifiers 2753 -#define wxKeyEvent_GetPosition 2756 -#define wxKeyEvent_GetRawKeyCode 2757 -#define wxKeyEvent_GetRawKeyFlags 2758 -#define wxKeyEvent_GetUnicodeKey 2759 -#define wxKeyEvent_GetX 2760 -#define wxKeyEvent_GetY 2761 -#define wxKeyEvent_HasModifiers 2762 -#define wxKeyEvent_MetaDown 2763 -#define wxKeyEvent_ShiftDown 2764 -#define wxSizeEvent_GetSize 2765 -#define wxMoveEvent_GetPosition 2766 -#define wxEraseEvent_GetDC 2767 -#define wxFocusEvent_GetWindow 2768 -#define wxChildFocusEvent_GetWindow 2769 -#define wxMenuEvent_GetMenu 2770 -#define wxMenuEvent_GetMenuId 2771 -#define wxMenuEvent_IsPopup 2772 -#define wxCloseEvent_CanVeto 2773 -#define wxCloseEvent_GetLoggingOff 2774 -#define wxCloseEvent_SetCanVeto 2775 -#define wxCloseEvent_SetLoggingOff 2776 -#define wxCloseEvent_Veto 2777 -#define wxShowEvent_SetShow 2778 -#define wxShowEvent_GetShow 2779 -#define wxIconizeEvent_Iconized 2780 -#define wxJoystickEvent_ButtonDown 2781 -#define wxJoystickEvent_ButtonIsDown 2782 -#define wxJoystickEvent_ButtonUp 2783 -#define wxJoystickEvent_GetButtonChange 2784 -#define wxJoystickEvent_GetButtonState 2785 -#define wxJoystickEvent_GetJoystick 2786 -#define wxJoystickEvent_GetPosition 2787 -#define wxJoystickEvent_GetZPosition 2788 -#define wxJoystickEvent_IsButton 2789 -#define wxJoystickEvent_IsMove 2790 -#define wxJoystickEvent_IsZMove 2791 -#define wxUpdateUIEvent_CanUpdate 2792 -#define wxUpdateUIEvent_Check 2793 -#define wxUpdateUIEvent_Enable 2794 -#define wxUpdateUIEvent_Show 2795 -#define wxUpdateUIEvent_GetChecked 2796 -#define wxUpdateUIEvent_GetEnabled 2797 -#define wxUpdateUIEvent_GetShown 2798 -#define wxUpdateUIEvent_GetSetChecked 2799 -#define wxUpdateUIEvent_GetSetEnabled 2800 -#define wxUpdateUIEvent_GetSetShown 2801 -#define wxUpdateUIEvent_GetSetText 2802 -#define wxUpdateUIEvent_GetText 2803 -#define wxUpdateUIEvent_GetMode 2804 -#define wxUpdateUIEvent_GetUpdateInterval 2805 -#define wxUpdateUIEvent_ResetUpdateTime 2806 -#define wxUpdateUIEvent_SetMode 2807 -#define wxUpdateUIEvent_SetText 2808 -#define wxUpdateUIEvent_SetUpdateInterval 2809 -#define wxMouseCaptureChangedEvent_GetCapturedWindow 2810 -#define wxPaletteChangedEvent_SetChangedWindow 2811 -#define wxPaletteChangedEvent_GetChangedWindow 2812 -#define wxQueryNewPaletteEvent_SetPaletteRealized 2813 -#define wxQueryNewPaletteEvent_GetPaletteRealized 2814 -#define wxNavigationKeyEvent_GetDirection 2815 -#define wxNavigationKeyEvent_SetDirection 2816 -#define wxNavigationKeyEvent_IsWindowChange 2817 -#define wxNavigationKeyEvent_SetWindowChange 2818 -#define wxNavigationKeyEvent_IsFromTab 2819 -#define wxNavigationKeyEvent_SetFromTab 2820 -#define wxNavigationKeyEvent_GetCurrentFocus 2821 -#define wxNavigationKeyEvent_SetCurrentFocus 2822 -#define wxHelpEvent_GetOrigin 2823 -#define wxHelpEvent_GetPosition 2824 -#define wxHelpEvent_SetOrigin 2825 -#define wxHelpEvent_SetPosition 2826 -#define wxContextMenuEvent_GetPosition 2827 -#define wxContextMenuEvent_SetPosition 2828 -#define wxIdleEvent_CanSend 2829 -#define wxIdleEvent_GetMode 2830 -#define wxIdleEvent_RequestMore 2831 -#define wxIdleEvent_MoreRequested 2832 -#define wxIdleEvent_SetMode 2833 -#define wxGridEvent_AltDown 2834 -#define wxGridEvent_ControlDown 2835 -#define wxGridEvent_GetCol 2836 -#define wxGridEvent_GetPosition 2837 -#define wxGridEvent_GetRow 2838 -#define wxGridEvent_MetaDown 2839 -#define wxGridEvent_Selecting 2840 -#define wxGridEvent_ShiftDown 2841 -#define wxNotifyEvent_Allow 2842 -#define wxNotifyEvent_IsAllowed 2843 -#define wxNotifyEvent_Veto 2844 -#define wxSashEvent_GetEdge 2845 -#define wxSashEvent_GetDragRect 2846 -#define wxSashEvent_GetDragStatus 2847 -#define wxListEvent_GetCacheFrom 2848 -#define wxListEvent_GetCacheTo 2849 -#define wxListEvent_GetKeyCode 2850 -#define wxListEvent_GetIndex 2851 -#define wxListEvent_GetColumn 2852 -#define wxListEvent_GetPoint 2853 -#define wxListEvent_GetLabel 2854 -#define wxListEvent_GetText 2855 -#define wxListEvent_GetImage 2856 -#define wxListEvent_GetData 2857 -#define wxListEvent_GetMask 2858 -#define wxListEvent_GetItem 2859 -#define wxListEvent_IsEditCancelled 2860 -#define wxDateEvent_GetDate 2861 -#define wxCalendarEvent_GetWeekDay 2862 -#define wxFileDirPickerEvent_GetPath 2863 -#define wxColourPickerEvent_GetColour 2864 -#define wxFontPickerEvent_GetFont 2865 -#define wxStyledTextEvent_GetPosition 2866 -#define wxStyledTextEvent_GetKey 2867 -#define wxStyledTextEvent_GetModifiers 2868 -#define wxStyledTextEvent_GetModificationType 2869 -#define wxStyledTextEvent_GetText 2870 -#define wxStyledTextEvent_GetLength 2871 -#define wxStyledTextEvent_GetLinesAdded 2872 -#define wxStyledTextEvent_GetLine 2873 -#define wxStyledTextEvent_GetFoldLevelNow 2874 -#define wxStyledTextEvent_GetFoldLevelPrev 2875 -#define wxStyledTextEvent_GetMargin 2876 -#define wxStyledTextEvent_GetMessage 2877 -#define wxStyledTextEvent_GetWParam 2878 -#define wxStyledTextEvent_GetLParam 2879 -#define wxStyledTextEvent_GetListType 2880 -#define wxStyledTextEvent_GetX 2881 -#define wxStyledTextEvent_GetY 2882 -#define wxStyledTextEvent_GetDragText 2883 -#define wxStyledTextEvent_GetDragAllowMove 2884 -#define wxStyledTextEvent_GetDragResult 2885 -#define wxStyledTextEvent_GetShift 2886 -#define wxStyledTextEvent_GetControl 2887 -#define wxStyledTextEvent_GetAlt 2888 -#define utils_wxGetKeyState 2889 -#define utils_wxGetMousePosition 2890 -#define utils_wxGetMouseState 2891 -#define utils_wxSetDetectableAutoRepeat 2892 -#define utils_wxBell 2893 -#define utils_wxFindMenuItemId 2894 -#define utils_wxGenericFindWindowAtPoint 2895 -#define utils_wxFindWindowAtPoint 2896 -#define utils_wxBeginBusyCursor 2897 -#define utils_wxEndBusyCursor 2898 -#define utils_wxIsBusy 2899 -#define utils_wxShutdown 2900 -#define utils_wxShell 2901 -#define utils_wxLaunchDefaultBrowser 2902 -#define utils_wxGetEmailAddress 2903 -#define utils_wxGetUserId 2904 -#define utils_wxGetHomeDir 2905 -#define utils_wxNewId 2906 -#define utils_wxRegisterId 2907 -#define utils_wxGetCurrentId 2908 -#define utils_wxGetOsDescription 2909 -#define utils_wxIsPlatformLittleEndian 2910 -#define utils_wxIsPlatform64Bit 2911 -#define wxPrintout_new 2912 -#define wxPrintout_destruct 2913 -#define wxPrintout_GetDC 2914 -#define wxPrintout_GetPageSizeMM 2915 -#define wxPrintout_GetPageSizePixels 2916 -#define wxPrintout_GetPaperRectPixels 2917 -#define wxPrintout_GetPPIPrinter 2918 -#define wxPrintout_GetPPIScreen 2919 -#define wxPrintout_GetTitle 2920 -#define wxPrintout_IsPreview 2921 -#define wxPrintout_FitThisSizeToPaper 2922 -#define wxPrintout_FitThisSizeToPage 2923 -#define wxPrintout_FitThisSizeToPageMargins 2924 -#define wxPrintout_MapScreenSizeToPaper 2925 -#define wxPrintout_MapScreenSizeToPage 2926 -#define wxPrintout_MapScreenSizeToPageMargins 2927 -#define wxPrintout_MapScreenSizeToDevice 2928 -#define wxPrintout_GetLogicalPaperRect 2929 -#define wxPrintout_GetLogicalPageRect 2930 -#define wxPrintout_GetLogicalPageMarginsRect 2931 -#define wxPrintout_SetLogicalOrigin 2932 -#define wxPrintout_OffsetLogicalOrigin 2933 -#define wxStyledTextCtrl_new_2 2934 -#define wxStyledTextCtrl_new_0 2935 -#define wxStyledTextCtrl_destruct 2936 -#define wxStyledTextCtrl_Create 2937 -#define wxStyledTextCtrl_AddText 2938 -#define wxStyledTextCtrl_AddStyledText 2939 -#define wxStyledTextCtrl_InsertText 2940 -#define wxStyledTextCtrl_ClearAll 2941 -#define wxStyledTextCtrl_ClearDocumentStyle 2942 -#define wxStyledTextCtrl_GetLength 2943 -#define wxStyledTextCtrl_GetCharAt 2944 -#define wxStyledTextCtrl_GetCurrentPos 2945 -#define wxStyledTextCtrl_GetAnchor 2946 -#define wxStyledTextCtrl_GetStyleAt 2947 -#define wxStyledTextCtrl_Redo 2948 -#define wxStyledTextCtrl_SetUndoCollection 2949 -#define wxStyledTextCtrl_SelectAll 2950 -#define wxStyledTextCtrl_SetSavePoint 2951 -#define wxStyledTextCtrl_GetStyledText 2952 -#define wxStyledTextCtrl_CanRedo 2953 -#define wxStyledTextCtrl_MarkerLineFromHandle 2954 -#define wxStyledTextCtrl_MarkerDeleteHandle 2955 -#define wxStyledTextCtrl_GetUndoCollection 2956 -#define wxStyledTextCtrl_GetViewWhiteSpace 2957 -#define wxStyledTextCtrl_SetViewWhiteSpace 2958 -#define wxStyledTextCtrl_PositionFromPoint 2959 -#define wxStyledTextCtrl_PositionFromPointClose 2960 -#define wxStyledTextCtrl_GotoLine 2961 -#define wxStyledTextCtrl_GotoPos 2962 -#define wxStyledTextCtrl_SetAnchor 2963 -#define wxStyledTextCtrl_GetCurLine 2964 -#define wxStyledTextCtrl_GetEndStyled 2965 -#define wxStyledTextCtrl_ConvertEOLs 2966 -#define wxStyledTextCtrl_GetEOLMode 2967 -#define wxStyledTextCtrl_SetEOLMode 2968 -#define wxStyledTextCtrl_StartStyling 2969 -#define wxStyledTextCtrl_SetStyling 2970 -#define wxStyledTextCtrl_GetBufferedDraw 2971 -#define wxStyledTextCtrl_SetBufferedDraw 2972 -#define wxStyledTextCtrl_SetTabWidth 2973 -#define wxStyledTextCtrl_GetTabWidth 2974 -#define wxStyledTextCtrl_SetCodePage 2975 -#define wxStyledTextCtrl_MarkerDefine 2976 -#define wxStyledTextCtrl_MarkerSetForeground 2977 -#define wxStyledTextCtrl_MarkerSetBackground 2978 -#define wxStyledTextCtrl_MarkerAdd 2979 -#define wxStyledTextCtrl_MarkerDelete 2980 -#define wxStyledTextCtrl_MarkerDeleteAll 2981 -#define wxStyledTextCtrl_MarkerGet 2982 -#define wxStyledTextCtrl_MarkerNext 2983 -#define wxStyledTextCtrl_MarkerPrevious 2984 -#define wxStyledTextCtrl_MarkerDefineBitmap 2985 -#define wxStyledTextCtrl_MarkerAddSet 2986 -#define wxStyledTextCtrl_MarkerSetAlpha 2987 -#define wxStyledTextCtrl_SetMarginType 2988 -#define wxStyledTextCtrl_GetMarginType 2989 -#define wxStyledTextCtrl_SetMarginWidth 2990 -#define wxStyledTextCtrl_GetMarginWidth 2991 -#define wxStyledTextCtrl_SetMarginMask 2992 -#define wxStyledTextCtrl_GetMarginMask 2993 -#define wxStyledTextCtrl_SetMarginSensitive 2994 -#define wxStyledTextCtrl_GetMarginSensitive 2995 -#define wxStyledTextCtrl_StyleClearAll 2996 -#define wxStyledTextCtrl_StyleSetForeground 2997 -#define wxStyledTextCtrl_StyleSetBackground 2998 -#define wxStyledTextCtrl_StyleSetBold 2999 -#define wxStyledTextCtrl_StyleSetItalic 3000 -#define wxStyledTextCtrl_StyleSetSize 3001 -#define wxStyledTextCtrl_StyleSetFaceName 3002 -#define wxStyledTextCtrl_StyleSetEOLFilled 3003 -#define wxStyledTextCtrl_StyleResetDefault 3004 -#define wxStyledTextCtrl_StyleSetUnderline 3005 -#define wxStyledTextCtrl_StyleSetCase 3006 -#define wxStyledTextCtrl_StyleSetHotSpot 3007 -#define wxStyledTextCtrl_SetSelForeground 3008 -#define wxStyledTextCtrl_SetSelBackground 3009 -#define wxStyledTextCtrl_GetSelAlpha 3010 -#define wxStyledTextCtrl_SetSelAlpha 3011 -#define wxStyledTextCtrl_SetCaretForeground 3012 -#define wxStyledTextCtrl_CmdKeyAssign 3013 -#define wxStyledTextCtrl_CmdKeyClear 3014 -#define wxStyledTextCtrl_CmdKeyClearAll 3015 -#define wxStyledTextCtrl_SetStyleBytes 3016 -#define wxStyledTextCtrl_StyleSetVisible 3017 -#define wxStyledTextCtrl_GetCaretPeriod 3018 -#define wxStyledTextCtrl_SetCaretPeriod 3019 -#define wxStyledTextCtrl_SetWordChars 3020 -#define wxStyledTextCtrl_BeginUndoAction 3021 -#define wxStyledTextCtrl_EndUndoAction 3022 -#define wxStyledTextCtrl_IndicatorSetStyle 3023 -#define wxStyledTextCtrl_IndicatorGetStyle 3024 -#define wxStyledTextCtrl_IndicatorSetForeground 3025 -#define wxStyledTextCtrl_IndicatorGetForeground 3026 -#define wxStyledTextCtrl_SetWhitespaceForeground 3027 -#define wxStyledTextCtrl_SetWhitespaceBackground 3028 -#define wxStyledTextCtrl_GetStyleBits 3029 -#define wxStyledTextCtrl_SetLineState 3030 -#define wxStyledTextCtrl_GetLineState 3031 -#define wxStyledTextCtrl_GetMaxLineState 3032 -#define wxStyledTextCtrl_GetCaretLineVisible 3033 -#define wxStyledTextCtrl_SetCaretLineVisible 3034 -#define wxStyledTextCtrl_GetCaretLineBackground 3035 -#define wxStyledTextCtrl_SetCaretLineBackground 3036 -#define wxStyledTextCtrl_AutoCompShow 3037 -#define wxStyledTextCtrl_AutoCompCancel 3038 -#define wxStyledTextCtrl_AutoCompActive 3039 -#define wxStyledTextCtrl_AutoCompPosStart 3040 -#define wxStyledTextCtrl_AutoCompComplete 3041 -#define wxStyledTextCtrl_AutoCompStops 3042 -#define wxStyledTextCtrl_AutoCompSetSeparator 3043 -#define wxStyledTextCtrl_AutoCompGetSeparator 3044 -#define wxStyledTextCtrl_AutoCompSelect 3045 -#define wxStyledTextCtrl_AutoCompSetCancelAtStart 3046 -#define wxStyledTextCtrl_AutoCompGetCancelAtStart 3047 -#define wxStyledTextCtrl_AutoCompSetFillUps 3048 -#define wxStyledTextCtrl_AutoCompSetChooseSingle 3049 -#define wxStyledTextCtrl_AutoCompGetChooseSingle 3050 -#define wxStyledTextCtrl_AutoCompSetIgnoreCase 3051 -#define wxStyledTextCtrl_AutoCompGetIgnoreCase 3052 -#define wxStyledTextCtrl_UserListShow 3053 -#define wxStyledTextCtrl_AutoCompSetAutoHide 3054 -#define wxStyledTextCtrl_AutoCompGetAutoHide 3055 -#define wxStyledTextCtrl_AutoCompSetDropRestOfWord 3056 -#define wxStyledTextCtrl_AutoCompGetDropRestOfWord 3057 -#define wxStyledTextCtrl_RegisterImage 3058 -#define wxStyledTextCtrl_ClearRegisteredImages 3059 -#define wxStyledTextCtrl_AutoCompGetTypeSeparator 3060 -#define wxStyledTextCtrl_AutoCompSetTypeSeparator 3061 -#define wxStyledTextCtrl_AutoCompSetMaxWidth 3062 -#define wxStyledTextCtrl_AutoCompGetMaxWidth 3063 -#define wxStyledTextCtrl_AutoCompSetMaxHeight 3064 -#define wxStyledTextCtrl_AutoCompGetMaxHeight 3065 -#define wxStyledTextCtrl_SetIndent 3066 -#define wxStyledTextCtrl_GetIndent 3067 -#define wxStyledTextCtrl_SetUseTabs 3068 -#define wxStyledTextCtrl_GetUseTabs 3069 -#define wxStyledTextCtrl_SetLineIndentation 3070 -#define wxStyledTextCtrl_GetLineIndentation 3071 -#define wxStyledTextCtrl_GetLineIndentPosition 3072 -#define wxStyledTextCtrl_GetColumn 3073 -#define wxStyledTextCtrl_SetUseHorizontalScrollBar 3074 -#define wxStyledTextCtrl_GetUseHorizontalScrollBar 3075 -#define wxStyledTextCtrl_SetIndentationGuides 3076 -#define wxStyledTextCtrl_GetIndentationGuides 3077 -#define wxStyledTextCtrl_SetHighlightGuide 3078 -#define wxStyledTextCtrl_GetHighlightGuide 3079 -#define wxStyledTextCtrl_GetLineEndPosition 3080 -#define wxStyledTextCtrl_GetCodePage 3081 -#define wxStyledTextCtrl_GetCaretForeground 3082 -#define wxStyledTextCtrl_GetReadOnly 3083 -#define wxStyledTextCtrl_SetCurrentPos 3084 -#define wxStyledTextCtrl_SetSelectionStart 3085 -#define wxStyledTextCtrl_GetSelectionStart 3086 -#define wxStyledTextCtrl_SetSelectionEnd 3087 -#define wxStyledTextCtrl_GetSelectionEnd 3088 -#define wxStyledTextCtrl_SetPrintMagnification 3089 -#define wxStyledTextCtrl_GetPrintMagnification 3090 -#define wxStyledTextCtrl_SetPrintColourMode 3091 -#define wxStyledTextCtrl_GetPrintColourMode 3092 -#define wxStyledTextCtrl_FindText 3093 -#define wxStyledTextCtrl_FormatRange 3094 -#define wxStyledTextCtrl_GetFirstVisibleLine 3095 -#define wxStyledTextCtrl_GetLine 3096 -#define wxStyledTextCtrl_GetLineCount 3097 -#define wxStyledTextCtrl_SetMarginLeft 3098 -#define wxStyledTextCtrl_GetMarginLeft 3099 -#define wxStyledTextCtrl_SetMarginRight 3100 -#define wxStyledTextCtrl_GetMarginRight 3101 -#define wxStyledTextCtrl_GetModify 3102 -#define wxStyledTextCtrl_SetSelection 3103 -#define wxStyledTextCtrl_GetSelectedText 3104 -#define wxStyledTextCtrl_GetTextRange 3105 -#define wxStyledTextCtrl_HideSelection 3106 -#define wxStyledTextCtrl_LineFromPosition 3107 -#define wxStyledTextCtrl_PositionFromLine 3108 -#define wxStyledTextCtrl_LineScroll 3109 -#define wxStyledTextCtrl_EnsureCaretVisible 3110 -#define wxStyledTextCtrl_ReplaceSelection 3111 -#define wxStyledTextCtrl_SetReadOnly 3112 -#define wxStyledTextCtrl_CanPaste 3113 -#define wxStyledTextCtrl_CanUndo 3114 -#define wxStyledTextCtrl_EmptyUndoBuffer 3115 -#define wxStyledTextCtrl_Undo 3116 -#define wxStyledTextCtrl_Cut 3117 -#define wxStyledTextCtrl_Copy 3118 -#define wxStyledTextCtrl_Paste 3119 -#define wxStyledTextCtrl_Clear 3120 -#define wxStyledTextCtrl_SetText 3121 -#define wxStyledTextCtrl_GetText 3122 -#define wxStyledTextCtrl_GetTextLength 3123 -#define wxStyledTextCtrl_GetOvertype 3124 -#define wxStyledTextCtrl_SetCaretWidth 3125 -#define wxStyledTextCtrl_GetCaretWidth 3126 -#define wxStyledTextCtrl_SetTargetStart 3127 -#define wxStyledTextCtrl_GetTargetStart 3128 -#define wxStyledTextCtrl_SetTargetEnd 3129 -#define wxStyledTextCtrl_GetTargetEnd 3130 -#define wxStyledTextCtrl_ReplaceTarget 3131 -#define wxStyledTextCtrl_SearchInTarget 3132 -#define wxStyledTextCtrl_SetSearchFlags 3133 -#define wxStyledTextCtrl_GetSearchFlags 3134 -#define wxStyledTextCtrl_CallTipShow 3135 -#define wxStyledTextCtrl_CallTipCancel 3136 -#define wxStyledTextCtrl_CallTipActive 3137 -#define wxStyledTextCtrl_CallTipPosAtStart 3138 -#define wxStyledTextCtrl_CallTipSetHighlight 3139 -#define wxStyledTextCtrl_CallTipSetBackground 3140 -#define wxStyledTextCtrl_CallTipSetForeground 3141 -#define wxStyledTextCtrl_CallTipSetForegroundHighlight 3142 -#define wxStyledTextCtrl_CallTipUseStyle 3143 -#define wxStyledTextCtrl_VisibleFromDocLine 3144 -#define wxStyledTextCtrl_DocLineFromVisible 3145 -#define wxStyledTextCtrl_WrapCount 3146 -#define wxStyledTextCtrl_SetFoldLevel 3147 -#define wxStyledTextCtrl_GetFoldLevel 3148 -#define wxStyledTextCtrl_GetLastChild 3149 -#define wxStyledTextCtrl_GetFoldParent 3150 -#define wxStyledTextCtrl_ShowLines 3151 -#define wxStyledTextCtrl_HideLines 3152 -#define wxStyledTextCtrl_GetLineVisible 3153 -#define wxStyledTextCtrl_SetFoldExpanded 3154 -#define wxStyledTextCtrl_GetFoldExpanded 3155 -#define wxStyledTextCtrl_ToggleFold 3156 -#define wxStyledTextCtrl_EnsureVisible 3157 -#define wxStyledTextCtrl_SetFoldFlags 3158 -#define wxStyledTextCtrl_EnsureVisibleEnforcePolicy 3159 -#define wxStyledTextCtrl_SetTabIndents 3160 -#define wxStyledTextCtrl_GetTabIndents 3161 -#define wxStyledTextCtrl_SetBackSpaceUnIndents 3162 -#define wxStyledTextCtrl_GetBackSpaceUnIndents 3163 -#define wxStyledTextCtrl_SetMouseDwellTime 3164 -#define wxStyledTextCtrl_GetMouseDwellTime 3165 -#define wxStyledTextCtrl_WordStartPosition 3166 -#define wxStyledTextCtrl_WordEndPosition 3167 -#define wxStyledTextCtrl_SetWrapMode 3168 -#define wxStyledTextCtrl_GetWrapMode 3169 -#define wxStyledTextCtrl_SetWrapVisualFlags 3170 -#define wxStyledTextCtrl_GetWrapVisualFlags 3171 -#define wxStyledTextCtrl_SetWrapVisualFlagsLocation 3172 -#define wxStyledTextCtrl_GetWrapVisualFlagsLocation 3173 -#define wxStyledTextCtrl_SetWrapStartIndent 3174 -#define wxStyledTextCtrl_GetWrapStartIndent 3175 -#define wxStyledTextCtrl_SetLayoutCache 3176 -#define wxStyledTextCtrl_GetLayoutCache 3177 -#define wxStyledTextCtrl_SetScrollWidth 3178 -#define wxStyledTextCtrl_GetScrollWidth 3179 -#define wxStyledTextCtrl_TextWidth 3180 -#define wxStyledTextCtrl_GetEndAtLastLine 3181 -#define wxStyledTextCtrl_TextHeight 3182 -#define wxStyledTextCtrl_SetUseVerticalScrollBar 3183 -#define wxStyledTextCtrl_GetUseVerticalScrollBar 3184 -#define wxStyledTextCtrl_AppendText 3185 -#define wxStyledTextCtrl_GetTwoPhaseDraw 3186 -#define wxStyledTextCtrl_SetTwoPhaseDraw 3187 -#define wxStyledTextCtrl_TargetFromSelection 3188 -#define wxStyledTextCtrl_LinesJoin 3189 -#define wxStyledTextCtrl_LinesSplit 3190 -#define wxStyledTextCtrl_SetFoldMarginColour 3191 -#define wxStyledTextCtrl_SetFoldMarginHiColour 3192 -#define wxStyledTextCtrl_LineDown 3193 -#define wxStyledTextCtrl_LineDownExtend 3194 -#define wxStyledTextCtrl_LineUp 3195 -#define wxStyledTextCtrl_LineUpExtend 3196 -#define wxStyledTextCtrl_CharLeft 3197 -#define wxStyledTextCtrl_CharLeftExtend 3198 -#define wxStyledTextCtrl_CharRight 3199 -#define wxStyledTextCtrl_CharRightExtend 3200 -#define wxStyledTextCtrl_WordLeft 3201 -#define wxStyledTextCtrl_WordLeftExtend 3202 -#define wxStyledTextCtrl_WordRight 3203 -#define wxStyledTextCtrl_WordRightExtend 3204 -#define wxStyledTextCtrl_Home 3205 -#define wxStyledTextCtrl_HomeExtend 3206 -#define wxStyledTextCtrl_LineEnd 3207 -#define wxStyledTextCtrl_LineEndExtend 3208 -#define wxStyledTextCtrl_DocumentStart 3209 -#define wxStyledTextCtrl_DocumentStartExtend 3210 -#define wxStyledTextCtrl_DocumentEnd 3211 -#define wxStyledTextCtrl_DocumentEndExtend 3212 -#define wxStyledTextCtrl_PageUp 3213 -#define wxStyledTextCtrl_PageUpExtend 3214 -#define wxStyledTextCtrl_PageDown 3215 -#define wxStyledTextCtrl_PageDownExtend 3216 -#define wxStyledTextCtrl_EditToggleOvertype 3217 -#define wxStyledTextCtrl_Cancel 3218 -#define wxStyledTextCtrl_DeleteBack 3219 -#define wxStyledTextCtrl_Tab 3220 -#define wxStyledTextCtrl_BackTab 3221 -#define wxStyledTextCtrl_NewLine 3222 -#define wxStyledTextCtrl_FormFeed 3223 -#define wxStyledTextCtrl_VCHome 3224 -#define wxStyledTextCtrl_VCHomeExtend 3225 -#define wxStyledTextCtrl_ZoomIn 3226 -#define wxStyledTextCtrl_ZoomOut 3227 -#define wxStyledTextCtrl_DelWordLeft 3228 -#define wxStyledTextCtrl_DelWordRight 3229 -#define wxStyledTextCtrl_LineCut 3230 -#define wxStyledTextCtrl_LineDelete 3231 -#define wxStyledTextCtrl_LineTranspose 3232 -#define wxStyledTextCtrl_LineDuplicate 3233 -#define wxStyledTextCtrl_LowerCase 3234 -#define wxStyledTextCtrl_UpperCase 3235 -#define wxStyledTextCtrl_LineScrollDown 3236 -#define wxStyledTextCtrl_LineScrollUp 3237 -#define wxStyledTextCtrl_DeleteBackNotLine 3238 -#define wxStyledTextCtrl_HomeDisplay 3239 -#define wxStyledTextCtrl_HomeDisplayExtend 3240 -#define wxStyledTextCtrl_LineEndDisplay 3241 -#define wxStyledTextCtrl_LineEndDisplayExtend 3242 -#define wxStyledTextCtrl_HomeWrapExtend 3243 -#define wxStyledTextCtrl_LineEndWrap 3244 -#define wxStyledTextCtrl_LineEndWrapExtend 3245 -#define wxStyledTextCtrl_VCHomeWrap 3246 -#define wxStyledTextCtrl_VCHomeWrapExtend 3247 -#define wxStyledTextCtrl_LineCopy 3248 -#define wxStyledTextCtrl_MoveCaretInsideView 3249 -#define wxStyledTextCtrl_LineLength 3250 -#define wxStyledTextCtrl_BraceHighlight 3251 -#define wxStyledTextCtrl_BraceBadLight 3252 -#define wxStyledTextCtrl_BraceMatch 3253 -#define wxStyledTextCtrl_GetViewEOL 3254 -#define wxStyledTextCtrl_SetViewEOL 3255 -#define wxStyledTextCtrl_SetModEventMask 3256 -#define wxStyledTextCtrl_GetEdgeColumn 3257 -#define wxStyledTextCtrl_SetEdgeColumn 3258 -#define wxStyledTextCtrl_GetEdgeMode 3259 -#define wxStyledTextCtrl_GetEdgeColour 3260 -#define wxStyledTextCtrl_SetEdgeColour 3261 -#define wxStyledTextCtrl_SearchAnchor 3262 -#define wxStyledTextCtrl_SearchNext 3263 -#define wxStyledTextCtrl_SearchPrev 3264 -#define wxStyledTextCtrl_LinesOnScreen 3265 -#define wxStyledTextCtrl_UsePopUp 3266 -#define wxStyledTextCtrl_SelectionIsRectangle 3267 -#define wxStyledTextCtrl_SetZoom 3268 -#define wxStyledTextCtrl_GetZoom 3269 -#define wxStyledTextCtrl_GetModEventMask 3270 -#define wxStyledTextCtrl_SetSTCFocus 3271 -#define wxStyledTextCtrl_GetSTCFocus 3272 -#define wxStyledTextCtrl_SetStatus 3273 -#define wxStyledTextCtrl_GetStatus 3274 -#define wxStyledTextCtrl_SetMouseDownCaptures 3275 -#define wxStyledTextCtrl_GetMouseDownCaptures 3276 -#define wxStyledTextCtrl_SetSTCCursor 3277 -#define wxStyledTextCtrl_GetSTCCursor 3278 -#define wxStyledTextCtrl_SetControlCharSymbol 3279 -#define wxStyledTextCtrl_GetControlCharSymbol 3280 -#define wxStyledTextCtrl_WordPartLeft 3281 -#define wxStyledTextCtrl_WordPartLeftExtend 3282 -#define wxStyledTextCtrl_WordPartRight 3283 -#define wxStyledTextCtrl_WordPartRightExtend 3284 -#define wxStyledTextCtrl_SetVisiblePolicy 3285 -#define wxStyledTextCtrl_DelLineLeft 3286 -#define wxStyledTextCtrl_DelLineRight 3287 -#define wxStyledTextCtrl_GetXOffset 3288 -#define wxStyledTextCtrl_ChooseCaretX 3289 -#define wxStyledTextCtrl_SetXCaretPolicy 3290 -#define wxStyledTextCtrl_SetYCaretPolicy 3291 -#define wxStyledTextCtrl_GetPrintWrapMode 3292 -#define wxStyledTextCtrl_SetHotspotActiveForeground 3293 -#define wxStyledTextCtrl_SetHotspotActiveBackground 3294 -#define wxStyledTextCtrl_SetHotspotActiveUnderline 3295 -#define wxStyledTextCtrl_SetHotspotSingleLine 3296 -#define wxStyledTextCtrl_ParaDownExtend 3297 -#define wxStyledTextCtrl_ParaUp 3298 -#define wxStyledTextCtrl_ParaUpExtend 3299 -#define wxStyledTextCtrl_PositionBefore 3300 -#define wxStyledTextCtrl_PositionAfter 3301 -#define wxStyledTextCtrl_CopyRange 3302 -#define wxStyledTextCtrl_CopyText 3303 -#define wxStyledTextCtrl_SetSelectionMode 3304 -#define wxStyledTextCtrl_GetSelectionMode 3305 -#define wxStyledTextCtrl_LineDownRectExtend 3306 -#define wxStyledTextCtrl_LineUpRectExtend 3307 -#define wxStyledTextCtrl_CharLeftRectExtend 3308 -#define wxStyledTextCtrl_CharRightRectExtend 3309 -#define wxStyledTextCtrl_HomeRectExtend 3310 -#define wxStyledTextCtrl_VCHomeRectExtend 3311 -#define wxStyledTextCtrl_LineEndRectExtend 3312 -#define wxStyledTextCtrl_PageUpRectExtend 3313 -#define wxStyledTextCtrl_PageDownRectExtend 3314 -#define wxStyledTextCtrl_StutteredPageUp 3315 -#define wxStyledTextCtrl_StutteredPageUpExtend 3316 -#define wxStyledTextCtrl_StutteredPageDown 3317 -#define wxStyledTextCtrl_StutteredPageDownExtend 3318 -#define wxStyledTextCtrl_WordLeftEnd 3319 -#define wxStyledTextCtrl_WordLeftEndExtend 3320 -#define wxStyledTextCtrl_WordRightEnd 3321 -#define wxStyledTextCtrl_WordRightEndExtend 3322 -#define wxStyledTextCtrl_SetWhitespaceChars 3323 -#define wxStyledTextCtrl_SetCharsDefault 3324 -#define wxStyledTextCtrl_AutoCompGetCurrent 3325 -#define wxStyledTextCtrl_Allocate 3326 -#define wxStyledTextCtrl_FindColumn 3327 -#define wxStyledTextCtrl_GetCaretSticky 3328 -#define wxStyledTextCtrl_SetCaretSticky 3329 -#define wxStyledTextCtrl_ToggleCaretSticky 3330 -#define wxStyledTextCtrl_SetPasteConvertEndings 3331 -#define wxStyledTextCtrl_GetPasteConvertEndings 3332 -#define wxStyledTextCtrl_SelectionDuplicate 3333 -#define wxStyledTextCtrl_SetCaretLineBackAlpha 3334 -#define wxStyledTextCtrl_GetCaretLineBackAlpha 3335 -#define wxStyledTextCtrl_StartRecord 3336 -#define wxStyledTextCtrl_StopRecord 3337 -#define wxStyledTextCtrl_SetLexer 3338 -#define wxStyledTextCtrl_GetLexer 3339 -#define wxStyledTextCtrl_Colourise 3340 -#define wxStyledTextCtrl_SetProperty 3341 -#define wxStyledTextCtrl_SetKeyWords 3342 -#define wxStyledTextCtrl_SetLexerLanguage 3343 -#define wxStyledTextCtrl_GetProperty 3344 -#define wxStyledTextCtrl_GetStyleBitsNeeded 3345 -#define wxStyledTextCtrl_GetCurrentLine 3346 -#define wxStyledTextCtrl_StyleSetSpec 3347 -#define wxStyledTextCtrl_StyleSetFont 3348 -#define wxStyledTextCtrl_StyleSetFontAttr 3349 -#define wxStyledTextCtrl_StyleSetCharacterSet 3350 -#define wxStyledTextCtrl_StyleSetFontEncoding 3351 -#define wxStyledTextCtrl_CmdKeyExecute 3352 -#define wxStyledTextCtrl_SetMargins 3353 -#define wxStyledTextCtrl_GetSelection 3354 -#define wxStyledTextCtrl_PointFromPosition 3355 -#define wxStyledTextCtrl_ScrollToLine 3356 -#define wxStyledTextCtrl_ScrollToColumn 3357 -#define wxStyledTextCtrl_SendMsg 3358 -#define wxStyledTextCtrl_SetVScrollBar 3359 -#define wxStyledTextCtrl_SetHScrollBar 3360 -#define wxStyledTextCtrl_GetLastKeydownProcessed 3361 -#define wxStyledTextCtrl_SetLastKeydownProcessed 3362 -#define wxStyledTextCtrl_SaveFile 3363 -#define wxStyledTextCtrl_LoadFile 3364 -#define wxStyledTextCtrl_DoDragOver 3365 -#define wxStyledTextCtrl_DoDropText 3366 -#define wxStyledTextCtrl_GetUseAntiAliasing 3367 -#define wxStyledTextCtrl_AddTextRaw 3368 -#define wxStyledTextCtrl_InsertTextRaw 3369 -#define wxStyledTextCtrl_GetCurLineRaw 3370 -#define wxStyledTextCtrl_GetLineRaw 3371 -#define wxStyledTextCtrl_GetSelectedTextRaw 3372 -#define wxStyledTextCtrl_GetTextRangeRaw 3373 -#define wxStyledTextCtrl_SetTextRaw 3374 -#define wxStyledTextCtrl_GetTextRaw 3375 -#define wxStyledTextCtrl_AppendTextRaw 3376 -#define wxArtProvider_GetBitmap 3377 -#define wxArtProvider_GetIcon 3378 -#define wxTreeEvent_GetKeyCode 3379 -#define wxTreeEvent_GetItem 3380 -#define wxTreeEvent_GetKeyEvent 3381 -#define wxTreeEvent_GetLabel 3382 -#define wxTreeEvent_GetOldItem 3383 -#define wxTreeEvent_GetPoint 3384 -#define wxTreeEvent_IsEditCancelled 3385 -#define wxTreeEvent_SetToolTip 3386 -#define wxNotebookEvent_GetOldSelection 3387 -#define wxNotebookEvent_GetSelection 3388 -#define wxNotebookEvent_SetOldSelection 3389 -#define wxNotebookEvent_SetSelection 3390 -#define wxFileDataObject_new 3391 -#define wxFileDataObject_AddFile 3392 -#define wxFileDataObject_GetFilenames 3393 -#define wxFileDataObject_destroy 3394 -#define wxTextDataObject_new 3395 -#define wxTextDataObject_GetTextLength 3396 -#define wxTextDataObject_GetText 3397 -#define wxTextDataObject_SetText 3398 -#define wxTextDataObject_destroy 3399 -#define wxBitmapDataObject_new_1_1 3400 -#define wxBitmapDataObject_new_1_0 3401 -#define wxBitmapDataObject_GetBitmap 3402 -#define wxBitmapDataObject_SetBitmap 3403 -#define wxBitmapDataObject_destroy 3404 -#define wxClipboard_new 3406 -#define wxClipboard_destruct 3407 -#define wxClipboard_AddData 3408 -#define wxClipboard_Clear 3409 -#define wxClipboard_Close 3410 -#define wxClipboard_Flush 3411 -#define wxClipboard_GetData 3412 -#define wxClipboard_IsOpened 3413 -#define wxClipboard_Open 3414 -#define wxClipboard_SetData 3415 -#define wxClipboard_UsePrimarySelection 3417 -#define wxClipboard_IsSupported 3418 -#define wxClipboard_Get 3419 -#define wxSpinEvent_GetPosition 3420 -#define wxSpinEvent_SetPosition 3421 -#define wxSplitterWindow_new_0 3422 -#define wxSplitterWindow_new_2 3423 -#define wxSplitterWindow_destruct 3424 -#define wxSplitterWindow_Create 3425 -#define wxSplitterWindow_GetMinimumPaneSize 3426 -#define wxSplitterWindow_GetSashGravity 3427 -#define wxSplitterWindow_GetSashPosition 3428 -#define wxSplitterWindow_GetSplitMode 3429 -#define wxSplitterWindow_GetWindow1 3430 -#define wxSplitterWindow_GetWindow2 3431 -#define wxSplitterWindow_Initialize 3432 -#define wxSplitterWindow_IsSplit 3433 -#define wxSplitterWindow_ReplaceWindow 3434 -#define wxSplitterWindow_SetSashGravity 3435 -#define wxSplitterWindow_SetSashPosition 3436 -#define wxSplitterWindow_SetSashSize 3437 -#define wxSplitterWindow_SetMinimumPaneSize 3438 -#define wxSplitterWindow_SetSplitMode 3439 -#define wxSplitterWindow_SplitHorizontally 3440 -#define wxSplitterWindow_SplitVertically 3441 -#define wxSplitterWindow_Unsplit 3442 -#define wxSplitterWindow_UpdateSize 3443 -#define wxSplitterEvent_GetSashPosition 3444 -#define wxSplitterEvent_GetX 3445 -#define wxSplitterEvent_GetY 3446 -#define wxSplitterEvent_GetWindowBeingRemoved 3447 -#define wxSplitterEvent_SetSashPosition 3448 -#define wxHtmlWindow_new_0 3449 -#define wxHtmlWindow_new_2 3450 -#define wxHtmlWindow_AppendToPage 3451 -#define wxHtmlWindow_GetOpenedAnchor 3452 -#define wxHtmlWindow_GetOpenedPage 3453 -#define wxHtmlWindow_GetOpenedPageTitle 3454 -#define wxHtmlWindow_GetRelatedFrame 3455 -#define wxHtmlWindow_HistoryBack 3456 -#define wxHtmlWindow_HistoryCanBack 3457 -#define wxHtmlWindow_HistoryCanForward 3458 -#define wxHtmlWindow_HistoryClear 3459 -#define wxHtmlWindow_HistoryForward 3460 -#define wxHtmlWindow_LoadFile 3461 -#define wxHtmlWindow_LoadPage 3462 -#define wxHtmlWindow_SelectAll 3463 -#define wxHtmlWindow_SelectionToText 3464 -#define wxHtmlWindow_SelectLine 3465 -#define wxHtmlWindow_SelectWord 3466 -#define wxHtmlWindow_SetBorders 3467 -#define wxHtmlWindow_SetFonts 3468 -#define wxHtmlWindow_SetPage 3469 -#define wxHtmlWindow_SetRelatedFrame 3470 -#define wxHtmlWindow_SetRelatedStatusBar 3471 -#define wxHtmlWindow_ToText 3472 -#define wxHtmlWindow_destroy 3473 -#define wxHtmlLinkEvent_GetLinkInfo 3474 -#define wxAuiNotebookEvent_SetSelection 3475 -#define wxAuiNotebookEvent_GetSelection 3476 -#define wxAuiNotebookEvent_SetOldSelection 3477 -#define wxAuiNotebookEvent_GetOldSelection 3478 -#define wxAuiNotebookEvent_SetDragSource 3479 -#define wxAuiNotebookEvent_GetDragSource 3480 -#define wxAuiManagerEvent_SetManager 3481 -#define wxAuiManagerEvent_GetManager 3482 -#define wxAuiManagerEvent_SetPane 3483 -#define wxAuiManagerEvent_GetPane 3484 -#define wxAuiManagerEvent_SetButton 3485 -#define wxAuiManagerEvent_GetButton 3486 -#define wxAuiManagerEvent_SetDC 3487 -#define wxAuiManagerEvent_GetDC 3488 -#define wxAuiManagerEvent_Veto 3489 -#define wxAuiManagerEvent_GetVeto 3490 -#define wxAuiManagerEvent_SetCanVeto 3491 -#define wxAuiManagerEvent_CanVeto 3492 -#define wxLogNull_new 3493 -#define wxLogNull_destroy 3494 +#define wxTreeCtrl_EditLabel 2010 +#define wxTreeCtrl_EnsureVisible 2011 +#define wxTreeCtrl_Expand 2012 +#define wxTreeCtrl_GetBoundingRect 2013 +#define wxTreeCtrl_GetChildrenCount 2015 +#define wxTreeCtrl_GetCount 2016 +#define wxTreeCtrl_GetEditControl 2017 +#define wxTreeCtrl_GetFirstChild 2018 +#define wxTreeCtrl_GetNextChild 2019 +#define wxTreeCtrl_GetFirstVisibleItem 2020 +#define wxTreeCtrl_GetImageList 2021 +#define wxTreeCtrl_GetIndent 2022 +#define wxTreeCtrl_GetItemBackgroundColour 2023 +#define wxTreeCtrl_GetItemData 2024 +#define wxTreeCtrl_GetItemFont 2025 +#define wxTreeCtrl_GetItemImage_1 2026 +#define wxTreeCtrl_GetItemImage_2 2027 +#define wxTreeCtrl_GetItemText 2028 +#define wxTreeCtrl_GetItemTextColour 2029 +#define wxTreeCtrl_GetLastChild 2030 +#define wxTreeCtrl_GetNextSibling 2031 +#define wxTreeCtrl_GetNextVisible 2032 +#define wxTreeCtrl_GetItemParent 2033 +#define wxTreeCtrl_GetPrevSibling 2034 +#define wxTreeCtrl_GetPrevVisible 2035 +#define wxTreeCtrl_GetRootItem 2036 +#define wxTreeCtrl_GetSelection 2037 +#define wxTreeCtrl_GetSelections 2038 +#define wxTreeCtrl_GetStateImageList 2039 +#define wxTreeCtrl_HitTest 2040 +#define wxTreeCtrl_InsertItem 2042 +#define wxTreeCtrl_IsBold 2043 +#define wxTreeCtrl_IsExpanded 2044 +#define wxTreeCtrl_IsSelected 2045 +#define wxTreeCtrl_IsVisible 2046 +#define wxTreeCtrl_ItemHasChildren 2047 +#define wxTreeCtrl_PrependItem 2048 +#define wxTreeCtrl_ScrollTo 2049 +#define wxTreeCtrl_SelectItem_1 2050 +#define wxTreeCtrl_SelectItem_2 2051 +#define wxTreeCtrl_SetIndent 2052 +#define wxTreeCtrl_SetImageList 2053 +#define wxTreeCtrl_SetItemBackgroundColour 2054 +#define wxTreeCtrl_SetItemBold 2055 +#define wxTreeCtrl_SetItemData 2056 +#define wxTreeCtrl_SetItemDropHighlight 2057 +#define wxTreeCtrl_SetItemFont 2058 +#define wxTreeCtrl_SetItemHasChildren 2059 +#define wxTreeCtrl_SetItemImage_2 2060 +#define wxTreeCtrl_SetItemImage_3 2061 +#define wxTreeCtrl_SetItemText 2062 +#define wxTreeCtrl_SetItemTextColour 2063 +#define wxTreeCtrl_SetStateImageList 2064 +#define wxTreeCtrl_SetWindowStyle 2065 +#define wxTreeCtrl_SortChildren 2066 +#define wxTreeCtrl_Toggle 2067 +#define wxTreeCtrl_ToggleItemSelection 2068 +#define wxTreeCtrl_Unselect 2069 +#define wxTreeCtrl_UnselectAll 2070 +#define wxTreeCtrl_UnselectItem 2071 +#define wxScrollBar_new_0 2072 +#define wxScrollBar_new_3 2073 +#define wxScrollBar_destruct 2074 +#define wxScrollBar_Create 2075 +#define wxScrollBar_GetRange 2076 +#define wxScrollBar_GetPageSize 2077 +#define wxScrollBar_GetThumbPosition 2078 +#define wxScrollBar_GetThumbSize 2079 +#define wxScrollBar_SetThumbPosition 2080 +#define wxScrollBar_SetScrollbar 2081 +#define wxSpinButton_new_2 2083 +#define wxSpinButton_new_0 2084 +#define wxSpinButton_Create 2085 +#define wxSpinButton_GetMax 2086 +#define wxSpinButton_GetMin 2087 +#define wxSpinButton_GetValue 2088 +#define wxSpinButton_SetRange 2089 +#define wxSpinButton_SetValue 2090 +#define wxSpinButton_destroy 2091 +#define wxSpinCtrl_new_0 2092 +#define wxSpinCtrl_new_2 2093 +#define wxSpinCtrl_Create 2095 +#define wxSpinCtrl_SetValue_1_1 2098 +#define wxSpinCtrl_SetValue_1_0 2099 +#define wxSpinCtrl_GetValue 2101 +#define wxSpinCtrl_SetRange 2103 +#define wxSpinCtrl_SetSelection 2104 +#define wxSpinCtrl_GetMin 2106 +#define wxSpinCtrl_GetMax 2108 +#define wxSpinCtrl_destroy 2109 +#define wxStaticText_new_0 2110 +#define wxStaticText_new_4 2111 +#define wxStaticText_Create 2112 +#define wxStaticText_GetLabel 2113 +#define wxStaticText_SetLabel 2114 +#define wxStaticText_Wrap 2115 +#define wxStaticText_destroy 2116 +#define wxStaticBitmap_new_0 2117 +#define wxStaticBitmap_new_4 2118 +#define wxStaticBitmap_Create 2119 +#define wxStaticBitmap_GetBitmap 2120 +#define wxStaticBitmap_SetBitmap 2121 +#define wxStaticBitmap_destroy 2122 +#define wxRadioBox_new 2123 +#define wxRadioBox_destruct 2125 +#define wxRadioBox_Create 2126 +#define wxRadioBox_Enable_2 2127 +#define wxRadioBox_Enable_1 2128 +#define wxRadioBox_GetSelection 2129 +#define wxRadioBox_GetString 2130 +#define wxRadioBox_SetSelection 2131 +#define wxRadioBox_Show_2 2132 +#define wxRadioBox_Show_1 2133 +#define wxRadioBox_GetColumnCount 2134 +#define wxRadioBox_GetItemHelpText 2135 +#define wxRadioBox_GetItemToolTip 2136 +#define wxRadioBox_GetItemFromPoint 2138 +#define wxRadioBox_GetRowCount 2139 +#define wxRadioBox_IsItemEnabled 2140 +#define wxRadioBox_IsItemShown 2141 +#define wxRadioBox_SetItemHelpText 2142 +#define wxRadioBox_SetItemToolTip 2143 +#define wxRadioButton_new_0 2144 +#define wxRadioButton_new_4 2145 +#define wxRadioButton_Create 2146 +#define wxRadioButton_GetValue 2147 +#define wxRadioButton_SetValue 2148 +#define wxRadioButton_destroy 2149 +#define wxSlider_new_6 2151 +#define wxSlider_new_0 2152 +#define wxSlider_Create 2153 +#define wxSlider_GetLineSize 2154 +#define wxSlider_GetMax 2155 +#define wxSlider_GetMin 2156 +#define wxSlider_GetPageSize 2157 +#define wxSlider_GetThumbLength 2158 +#define wxSlider_GetValue 2159 +#define wxSlider_SetLineSize 2160 +#define wxSlider_SetPageSize 2161 +#define wxSlider_SetRange 2162 +#define wxSlider_SetThumbLength 2163 +#define wxSlider_SetValue 2164 +#define wxSlider_destroy 2165 +#define wxDialog_new_4 2167 +#define wxDialog_new_0 2168 +#define wxDialog_destruct 2170 +#define wxDialog_Create 2171 +#define wxDialog_CreateButtonSizer 2172 +#define wxDialog_CreateStdDialogButtonSizer 2173 +#define wxDialog_EndModal 2174 +#define wxDialog_GetAffirmativeId 2175 +#define wxDialog_GetReturnCode 2176 +#define wxDialog_IsModal 2177 +#define wxDialog_SetAffirmativeId 2178 +#define wxDialog_SetReturnCode 2179 +#define wxDialog_Show 2180 +#define wxDialog_ShowModal 2181 +#define wxColourDialog_new_0 2182 +#define wxColourDialog_new_2 2183 +#define wxColourDialog_destruct 2184 +#define wxColourDialog_Create 2185 +#define wxColourDialog_GetColourData 2186 +#define wxColourData_new_0 2187 +#define wxColourData_new_1 2188 +#define wxColourData_destruct 2189 +#define wxColourData_GetChooseFull 2190 +#define wxColourData_GetColour 2191 +#define wxColourData_GetCustomColour 2193 +#define wxColourData_SetChooseFull 2194 +#define wxColourData_SetColour 2195 +#define wxColourData_SetCustomColour 2196 +#define wxPalette_new_0 2197 +#define wxPalette_new_4 2198 +#define wxPalette_destruct 2200 +#define wxPalette_Create 2201 +#define wxPalette_GetColoursCount 2202 +#define wxPalette_GetPixel 2203 +#define wxPalette_GetRGB 2204 +#define wxPalette_IsOk 2205 +#define wxDirDialog_new 2209 +#define wxDirDialog_destruct 2210 +#define wxDirDialog_GetPath 2211 +#define wxDirDialog_GetMessage 2212 +#define wxDirDialog_SetMessage 2213 +#define wxDirDialog_SetPath 2214 +#define wxFileDialog_new 2218 +#define wxFileDialog_destruct 2219 +#define wxFileDialog_GetDirectory 2220 +#define wxFileDialog_GetFilename 2221 +#define wxFileDialog_GetFilenames 2222 +#define wxFileDialog_GetFilterIndex 2223 +#define wxFileDialog_GetMessage 2224 +#define wxFileDialog_GetPath 2225 +#define wxFileDialog_GetPaths 2226 +#define wxFileDialog_GetWildcard 2227 +#define wxFileDialog_SetDirectory 2228 +#define wxFileDialog_SetFilename 2229 +#define wxFileDialog_SetFilterIndex 2230 +#define wxFileDialog_SetMessage 2231 +#define wxFileDialog_SetPath 2232 +#define wxFileDialog_SetWildcard 2233 +#define wxPickerBase_SetInternalMargin 2234 +#define wxPickerBase_GetInternalMargin 2235 +#define wxPickerBase_SetTextCtrlProportion 2236 +#define wxPickerBase_SetPickerCtrlProportion 2237 +#define wxPickerBase_GetTextCtrlProportion 2238 +#define wxPickerBase_GetPickerCtrlProportion 2239 +#define wxPickerBase_HasTextCtrl 2240 +#define wxPickerBase_GetTextCtrl 2241 +#define wxPickerBase_IsTextCtrlGrowable 2242 +#define wxPickerBase_SetPickerCtrlGrowable 2243 +#define wxPickerBase_SetTextCtrlGrowable 2244 +#define wxPickerBase_IsPickerCtrlGrowable 2245 +#define wxFilePickerCtrl_new_0 2246 +#define wxFilePickerCtrl_new_3 2247 +#define wxFilePickerCtrl_Create 2248 +#define wxFilePickerCtrl_GetPath 2249 +#define wxFilePickerCtrl_SetPath 2250 +#define wxFilePickerCtrl_destroy 2251 +#define wxDirPickerCtrl_new_0 2252 +#define wxDirPickerCtrl_new_3 2253 +#define wxDirPickerCtrl_Create 2254 +#define wxDirPickerCtrl_GetPath 2255 +#define wxDirPickerCtrl_SetPath 2256 +#define wxDirPickerCtrl_destroy 2257 +#define wxColourPickerCtrl_new_0 2258 +#define wxColourPickerCtrl_new_3 2259 +#define wxColourPickerCtrl_Create 2260 +#define wxColourPickerCtrl_GetColour 2261 +#define wxColourPickerCtrl_SetColour_1_1 2262 +#define wxColourPickerCtrl_SetColour_1_0 2263 +#define wxColourPickerCtrl_destroy 2264 +#define wxDatePickerCtrl_new_0 2265 +#define wxDatePickerCtrl_new_3 2266 +#define wxDatePickerCtrl_GetRange 2267 +#define wxDatePickerCtrl_GetValue 2268 +#define wxDatePickerCtrl_SetRange 2269 +#define wxDatePickerCtrl_SetValue 2270 +#define wxDatePickerCtrl_destroy 2271 +#define wxFontPickerCtrl_new_0 2272 +#define wxFontPickerCtrl_new_3 2273 +#define wxFontPickerCtrl_Create 2274 +#define wxFontPickerCtrl_GetSelectedFont 2275 +#define wxFontPickerCtrl_SetSelectedFont 2276 +#define wxFontPickerCtrl_GetMaxPointSize 2277 +#define wxFontPickerCtrl_SetMaxPointSize 2278 +#define wxFontPickerCtrl_destroy 2279 +#define wxFindReplaceDialog_new_0 2282 +#define wxFindReplaceDialog_new_4 2283 +#define wxFindReplaceDialog_destruct 2284 +#define wxFindReplaceDialog_Create 2285 +#define wxFindReplaceDialog_GetData 2286 +#define wxFindReplaceData_new_0 2287 +#define wxFindReplaceData_new_1 2288 +#define wxFindReplaceData_GetFindString 2289 +#define wxFindReplaceData_GetReplaceString 2290 +#define wxFindReplaceData_GetFlags 2291 +#define wxFindReplaceData_SetFlags 2292 +#define wxFindReplaceData_SetFindString 2293 +#define wxFindReplaceData_SetReplaceString 2294 +#define wxFindReplaceData_destroy 2295 +#define wxMultiChoiceDialog_new_0 2296 +#define wxMultiChoiceDialog_new_5 2298 +#define wxMultiChoiceDialog_GetSelections 2299 +#define wxMultiChoiceDialog_SetSelections 2300 +#define wxMultiChoiceDialog_destroy 2301 +#define wxSingleChoiceDialog_new_0 2302 +#define wxSingleChoiceDialog_new_5 2304 +#define wxSingleChoiceDialog_GetSelection 2305 +#define wxSingleChoiceDialog_GetStringSelection 2306 +#define wxSingleChoiceDialog_SetSelection 2307 +#define wxSingleChoiceDialog_destroy 2308 +#define wxTextEntryDialog_new 2309 +#define wxTextEntryDialog_GetValue 2310 +#define wxTextEntryDialog_SetValue 2311 +#define wxTextEntryDialog_destroy 2312 +#define wxPasswordEntryDialog_new 2313 +#define wxPasswordEntryDialog_destroy 2314 +#define wxFontData_new_0 2315 +#define wxFontData_new_1 2316 +#define wxFontData_destruct 2317 +#define wxFontData_EnableEffects 2318 +#define wxFontData_GetAllowSymbols 2319 +#define wxFontData_GetColour 2320 +#define wxFontData_GetChosenFont 2321 +#define wxFontData_GetEnableEffects 2322 +#define wxFontData_GetInitialFont 2323 +#define wxFontData_GetShowHelp 2324 +#define wxFontData_SetAllowSymbols 2325 +#define wxFontData_SetChosenFont 2326 +#define wxFontData_SetColour 2327 +#define wxFontData_SetInitialFont 2328 +#define wxFontData_SetRange 2329 +#define wxFontData_SetShowHelp 2330 +#define wxFontDialog_new_0 2334 +#define wxFontDialog_new_2 2336 +#define wxFontDialog_Create 2338 +#define wxFontDialog_GetFontData 2339 +#define wxFontDialog_destroy 2341 +#define wxProgressDialog_new 2342 +#define wxProgressDialog_destruct 2343 +#define wxProgressDialog_Resume 2344 +#define wxProgressDialog_Update_2 2345 +#define wxProgressDialog_Update_0 2346 +#define wxMessageDialog_new 2347 +#define wxMessageDialog_destruct 2348 +#define wxPageSetupDialog_new 2349 +#define wxPageSetupDialog_destruct 2350 +#define wxPageSetupDialog_GetPageSetupData 2351 +#define wxPageSetupDialog_ShowModal 2352 +#define wxPageSetupDialogData_new_0 2353 +#define wxPageSetupDialogData_new_1_0 2354 +#define wxPageSetupDialogData_new_1_1 2355 +#define wxPageSetupDialogData_destruct 2356 +#define wxPageSetupDialogData_EnableHelp 2357 +#define wxPageSetupDialogData_EnableMargins 2358 +#define wxPageSetupDialogData_EnableOrientation 2359 +#define wxPageSetupDialogData_EnablePaper 2360 +#define wxPageSetupDialogData_EnablePrinter 2361 +#define wxPageSetupDialogData_GetDefaultMinMargins 2362 +#define wxPageSetupDialogData_GetEnableMargins 2363 +#define wxPageSetupDialogData_GetEnableOrientation 2364 +#define wxPageSetupDialogData_GetEnablePaper 2365 +#define wxPageSetupDialogData_GetEnablePrinter 2366 +#define wxPageSetupDialogData_GetEnableHelp 2367 +#define wxPageSetupDialogData_GetDefaultInfo 2368 +#define wxPageSetupDialogData_GetMarginTopLeft 2369 +#define wxPageSetupDialogData_GetMarginBottomRight 2370 +#define wxPageSetupDialogData_GetMinMarginTopLeft 2371 +#define wxPageSetupDialogData_GetMinMarginBottomRight 2372 +#define wxPageSetupDialogData_GetPaperId 2373 +#define wxPageSetupDialogData_GetPaperSize 2374 +#define wxPageSetupDialogData_GetPrintData 2376 +#define wxPageSetupDialogData_IsOk 2377 +#define wxPageSetupDialogData_SetDefaultInfo 2378 +#define wxPageSetupDialogData_SetDefaultMinMargins 2379 +#define wxPageSetupDialogData_SetMarginTopLeft 2380 +#define wxPageSetupDialogData_SetMarginBottomRight 2381 +#define wxPageSetupDialogData_SetMinMarginTopLeft 2382 +#define wxPageSetupDialogData_SetMinMarginBottomRight 2383 +#define wxPageSetupDialogData_SetPaperId 2384 +#define wxPageSetupDialogData_SetPaperSize_1_1 2385 +#define wxPageSetupDialogData_SetPaperSize_1_0 2386 +#define wxPageSetupDialogData_SetPrintData 2387 +#define wxPrintDialog_new_2_0 2388 +#define wxPrintDialog_new_2_1 2389 +#define wxPrintDialog_destruct 2390 +#define wxPrintDialog_GetPrintDialogData 2391 +#define wxPrintDialog_GetPrintDC 2392 +#define wxPrintDialogData_new_0 2393 +#define wxPrintDialogData_new_1_1 2394 +#define wxPrintDialogData_new_1_0 2395 +#define wxPrintDialogData_destruct 2396 +#define wxPrintDialogData_EnableHelp 2397 +#define wxPrintDialogData_EnablePageNumbers 2398 +#define wxPrintDialogData_EnablePrintToFile 2399 +#define wxPrintDialogData_EnableSelection 2400 +#define wxPrintDialogData_GetAllPages 2401 +#define wxPrintDialogData_GetCollate 2402 +#define wxPrintDialogData_GetFromPage 2403 +#define wxPrintDialogData_GetMaxPage 2404 +#define wxPrintDialogData_GetMinPage 2405 +#define wxPrintDialogData_GetNoCopies 2406 +#define wxPrintDialogData_GetPrintData 2407 +#define wxPrintDialogData_GetPrintToFile 2408 +#define wxPrintDialogData_GetSelection 2409 +#define wxPrintDialogData_GetToPage 2410 +#define wxPrintDialogData_IsOk 2411 +#define wxPrintDialogData_SetCollate 2412 +#define wxPrintDialogData_SetFromPage 2413 +#define wxPrintDialogData_SetMaxPage 2414 +#define wxPrintDialogData_SetMinPage 2415 +#define wxPrintDialogData_SetNoCopies 2416 +#define wxPrintDialogData_SetPrintData 2417 +#define wxPrintDialogData_SetPrintToFile 2418 +#define wxPrintDialogData_SetSelection 2419 +#define wxPrintDialogData_SetToPage 2420 +#define wxPrintData_new_0 2421 +#define wxPrintData_new_1 2422 +#define wxPrintData_destruct 2423 +#define wxPrintData_GetCollate 2424 +#define wxPrintData_GetBin 2425 +#define wxPrintData_GetColour 2426 +#define wxPrintData_GetDuplex 2427 +#define wxPrintData_GetNoCopies 2428 +#define wxPrintData_GetOrientation 2429 +#define wxPrintData_GetPaperId 2430 +#define wxPrintData_GetPrinterName 2431 +#define wxPrintData_GetQuality 2432 +#define wxPrintData_IsOk 2433 +#define wxPrintData_SetBin 2434 +#define wxPrintData_SetCollate 2435 +#define wxPrintData_SetColour 2436 +#define wxPrintData_SetDuplex 2437 +#define wxPrintData_SetNoCopies 2438 +#define wxPrintData_SetOrientation 2439 +#define wxPrintData_SetPaperId 2440 +#define wxPrintData_SetPrinterName 2441 +#define wxPrintData_SetQuality 2442 +#define wxPrintPreview_new_2 2445 +#define wxPrintPreview_new_3 2446 +#define wxPrintPreview_destruct 2448 +#define wxPrintPreview_GetCanvas 2449 +#define wxPrintPreview_GetCurrentPage 2450 +#define wxPrintPreview_GetFrame 2451 +#define wxPrintPreview_GetMaxPage 2452 +#define wxPrintPreview_GetMinPage 2453 +#define wxPrintPreview_GetPrintout 2454 +#define wxPrintPreview_GetPrintoutForPrinting 2455 +#define wxPrintPreview_IsOk 2456 +#define wxPrintPreview_PaintPage 2457 +#define wxPrintPreview_Print 2458 +#define wxPrintPreview_RenderPage 2459 +#define wxPrintPreview_SetCanvas 2460 +#define wxPrintPreview_SetCurrentPage 2461 +#define wxPrintPreview_SetFrame 2462 +#define wxPrintPreview_SetPrintout 2463 +#define wxPrintPreview_SetZoom 2464 +#define wxPreviewFrame_new 2465 +#define wxPreviewFrame_destruct 2466 +#define wxPreviewFrame_CreateControlBar 2467 +#define wxPreviewFrame_CreateCanvas 2468 +#define wxPreviewFrame_Initialize 2469 +#define wxPreviewFrame_OnCloseWindow 2470 +#define wxPreviewControlBar_new 2471 +#define wxPreviewControlBar_destruct 2472 +#define wxPreviewControlBar_CreateButtons 2473 +#define wxPreviewControlBar_GetPrintPreview 2474 +#define wxPreviewControlBar_GetZoomControl 2475 +#define wxPreviewControlBar_SetZoomControl 2476 +#define wxPrinter_new 2478 +#define wxPrinter_CreateAbortWindow 2479 +#define wxPrinter_GetAbort 2480 +#define wxPrinter_GetLastError 2481 +#define wxPrinter_GetPrintDialogData 2482 +#define wxPrinter_Print 2483 +#define wxPrinter_PrintDialog 2484 +#define wxPrinter_ReportError 2485 +#define wxPrinter_Setup 2486 +#define wxPrinter_destroy 2487 +#define wxXmlResource_new_1 2488 +#define wxXmlResource_new_2 2489 +#define wxXmlResource_destruct 2490 +#define wxXmlResource_AttachUnknownControl 2491 +#define wxXmlResource_ClearHandlers 2492 +#define wxXmlResource_CompareVersion 2493 +#define wxXmlResource_Get 2494 +#define wxXmlResource_GetFlags 2495 +#define wxXmlResource_GetVersion 2496 +#define wxXmlResource_GetXRCID 2497 +#define wxXmlResource_InitAllHandlers 2498 +#define wxXmlResource_Load 2499 +#define wxXmlResource_LoadBitmap 2500 +#define wxXmlResource_LoadDialog_2 2501 +#define wxXmlResource_LoadDialog_3 2502 +#define wxXmlResource_LoadFrame_2 2503 +#define wxXmlResource_LoadFrame_3 2504 +#define wxXmlResource_LoadIcon 2505 +#define wxXmlResource_LoadMenu 2506 +#define wxXmlResource_LoadMenuBar_2 2507 +#define wxXmlResource_LoadMenuBar_1 2508 +#define wxXmlResource_LoadPanel_2 2509 +#define wxXmlResource_LoadPanel_3 2510 +#define wxXmlResource_LoadToolBar 2511 +#define wxXmlResource_Set 2512 +#define wxXmlResource_SetFlags 2513 +#define wxXmlResource_Unload 2514 +#define wxXmlResource_xrcctrl 2515 +#define wxHtmlEasyPrinting_new 2516 +#define wxHtmlEasyPrinting_destruct 2517 +#define wxHtmlEasyPrinting_GetPrintData 2518 +#define wxHtmlEasyPrinting_GetPageSetupData 2519 +#define wxHtmlEasyPrinting_PreviewFile 2520 +#define wxHtmlEasyPrinting_PreviewText 2521 +#define wxHtmlEasyPrinting_PrintFile 2522 +#define wxHtmlEasyPrinting_PrintText 2523 +#define wxHtmlEasyPrinting_PageSetup 2524 +#define wxHtmlEasyPrinting_SetFonts 2525 +#define wxHtmlEasyPrinting_SetHeader 2526 +#define wxHtmlEasyPrinting_SetFooter 2527 +#define wxGLCanvas_new_2 2529 +#define wxGLCanvas_new_3_1 2530 +#define wxGLCanvas_new_3_0 2531 +#define wxGLCanvas_GetContext 2532 +#define wxGLCanvas_SetCurrent 2534 +#define wxGLCanvas_SwapBuffers 2535 +#define wxGLCanvas_destroy 2536 +#define wxAuiManager_new 2537 +#define wxAuiManager_destruct 2538 +#define wxAuiManager_AddPane_2_1 2539 +#define wxAuiManager_AddPane_3 2540 +#define wxAuiManager_AddPane_2_0 2541 +#define wxAuiManager_DetachPane 2542 +#define wxAuiManager_GetAllPanes 2543 +#define wxAuiManager_GetArtProvider 2544 +#define wxAuiManager_GetDockSizeConstraint 2545 +#define wxAuiManager_GetFlags 2546 +#define wxAuiManager_GetManagedWindow 2547 +#define wxAuiManager_GetManager 2548 +#define wxAuiManager_GetPane_1_1 2549 +#define wxAuiManager_GetPane_1_0 2550 +#define wxAuiManager_HideHint 2551 +#define wxAuiManager_InsertPane 2552 +#define wxAuiManager_LoadPaneInfo 2553 +#define wxAuiManager_LoadPerspective 2554 +#define wxAuiManager_SavePaneInfo 2555 +#define wxAuiManager_SavePerspective 2556 +#define wxAuiManager_SetArtProvider 2557 +#define wxAuiManager_SetDockSizeConstraint 2558 +#define wxAuiManager_SetFlags 2559 +#define wxAuiManager_SetManagedWindow 2560 +#define wxAuiManager_ShowHint 2561 +#define wxAuiManager_UnInit 2562 +#define wxAuiManager_Update 2563 +#define wxAuiPaneInfo_new_0 2564 +#define wxAuiPaneInfo_new_1 2565 +#define wxAuiPaneInfo_destruct 2566 +#define wxAuiPaneInfo_BestSize_1 2567 +#define wxAuiPaneInfo_BestSize_2 2568 +#define wxAuiPaneInfo_Bottom 2569 +#define wxAuiPaneInfo_BottomDockable 2570 +#define wxAuiPaneInfo_Caption 2571 +#define wxAuiPaneInfo_CaptionVisible 2572 +#define wxAuiPaneInfo_Centre 2573 +#define wxAuiPaneInfo_CentrePane 2574 +#define wxAuiPaneInfo_CloseButton 2575 +#define wxAuiPaneInfo_DefaultPane 2576 +#define wxAuiPaneInfo_DestroyOnClose 2577 +#define wxAuiPaneInfo_Direction 2578 +#define wxAuiPaneInfo_Dock 2579 +#define wxAuiPaneInfo_Dockable 2580 +#define wxAuiPaneInfo_Fixed 2581 +#define wxAuiPaneInfo_Float 2582 +#define wxAuiPaneInfo_Floatable 2583 +#define wxAuiPaneInfo_FloatingPosition_1 2584 +#define wxAuiPaneInfo_FloatingPosition_2 2585 +#define wxAuiPaneInfo_FloatingSize_1 2586 +#define wxAuiPaneInfo_FloatingSize_2 2587 +#define wxAuiPaneInfo_Gripper 2588 +#define wxAuiPaneInfo_GripperTop 2589 +#define wxAuiPaneInfo_HasBorder 2590 +#define wxAuiPaneInfo_HasCaption 2591 +#define wxAuiPaneInfo_HasCloseButton 2592 +#define wxAuiPaneInfo_HasFlag 2593 +#define wxAuiPaneInfo_HasGripper 2594 +#define wxAuiPaneInfo_HasGripperTop 2595 +#define wxAuiPaneInfo_HasMaximizeButton 2596 +#define wxAuiPaneInfo_HasMinimizeButton 2597 +#define wxAuiPaneInfo_HasPinButton 2598 +#define wxAuiPaneInfo_Hide 2599 +#define wxAuiPaneInfo_IsBottomDockable 2600 +#define wxAuiPaneInfo_IsDocked 2601 +#define wxAuiPaneInfo_IsFixed 2602 +#define wxAuiPaneInfo_IsFloatable 2603 +#define wxAuiPaneInfo_IsFloating 2604 +#define wxAuiPaneInfo_IsLeftDockable 2605 +#define wxAuiPaneInfo_IsMovable 2606 +#define wxAuiPaneInfo_IsOk 2607 +#define wxAuiPaneInfo_IsResizable 2608 +#define wxAuiPaneInfo_IsRightDockable 2609 +#define wxAuiPaneInfo_IsShown 2610 +#define wxAuiPaneInfo_IsToolbar 2611 +#define wxAuiPaneInfo_IsTopDockable 2612 +#define wxAuiPaneInfo_Layer 2613 +#define wxAuiPaneInfo_Left 2614 +#define wxAuiPaneInfo_LeftDockable 2615 +#define wxAuiPaneInfo_MaxSize_1 2616 +#define wxAuiPaneInfo_MaxSize_2 2617 +#define wxAuiPaneInfo_MaximizeButton 2618 +#define wxAuiPaneInfo_MinSize_1 2619 +#define wxAuiPaneInfo_MinSize_2 2620 +#define wxAuiPaneInfo_MinimizeButton 2621 +#define wxAuiPaneInfo_Movable 2622 +#define wxAuiPaneInfo_Name 2623 +#define wxAuiPaneInfo_PaneBorder 2624 +#define wxAuiPaneInfo_PinButton 2625 +#define wxAuiPaneInfo_Position 2626 +#define wxAuiPaneInfo_Resizable 2627 +#define wxAuiPaneInfo_Right 2628 +#define wxAuiPaneInfo_RightDockable 2629 +#define wxAuiPaneInfo_Row 2630 +#define wxAuiPaneInfo_SafeSet 2631 +#define wxAuiPaneInfo_SetFlag 2632 +#define wxAuiPaneInfo_Show 2633 +#define wxAuiPaneInfo_ToolbarPane 2634 +#define wxAuiPaneInfo_Top 2635 +#define wxAuiPaneInfo_TopDockable 2636 +#define wxAuiPaneInfo_Window 2637 +#define wxAuiNotebook_new_0 2638 +#define wxAuiNotebook_new_2 2639 +#define wxAuiNotebook_AddPage 2640 +#define wxAuiNotebook_Create 2641 +#define wxAuiNotebook_DeletePage 2642 +#define wxAuiNotebook_GetArtProvider 2643 +#define wxAuiNotebook_GetPage 2644 +#define wxAuiNotebook_GetPageBitmap 2645 +#define wxAuiNotebook_GetPageCount 2646 +#define wxAuiNotebook_GetPageIndex 2647 +#define wxAuiNotebook_GetPageText 2648 +#define wxAuiNotebook_GetSelection 2649 +#define wxAuiNotebook_InsertPage 2650 +#define wxAuiNotebook_RemovePage 2651 +#define wxAuiNotebook_SetArtProvider 2652 +#define wxAuiNotebook_SetFont 2653 +#define wxAuiNotebook_SetPageBitmap 2654 +#define wxAuiNotebook_SetPageText 2655 +#define wxAuiNotebook_SetSelection 2656 +#define wxAuiNotebook_SetTabCtrlHeight 2657 +#define wxAuiNotebook_SetUniformBitmapSize 2658 +#define wxAuiNotebook_destroy 2659 +#define wxMDIParentFrame_new_0 2660 +#define wxMDIParentFrame_new_4 2661 +#define wxMDIParentFrame_destruct 2662 +#define wxMDIParentFrame_ActivateNext 2663 +#define wxMDIParentFrame_ActivatePrevious 2664 +#define wxMDIParentFrame_ArrangeIcons 2665 +#define wxMDIParentFrame_Cascade 2666 +#define wxMDIParentFrame_Create 2667 +#define wxMDIParentFrame_GetActiveChild 2668 +#define wxMDIParentFrame_GetClientWindow 2669 +#define wxMDIParentFrame_Tile 2670 +#define wxMDIChildFrame_new_0 2671 +#define wxMDIChildFrame_new_4 2672 +#define wxMDIChildFrame_destruct 2673 +#define wxMDIChildFrame_Activate 2674 +#define wxMDIChildFrame_Create 2675 +#define wxMDIChildFrame_Maximize 2676 +#define wxMDIChildFrame_Restore 2677 +#define wxMDIClientWindow_new_0 2678 +#define wxMDIClientWindow_new_2 2679 +#define wxMDIClientWindow_destruct 2680 +#define wxMDIClientWindow_CreateClient 2681 +#define wxLayoutAlgorithm_new 2682 +#define wxLayoutAlgorithm_LayoutFrame 2683 +#define wxLayoutAlgorithm_LayoutMDIFrame 2684 +#define wxLayoutAlgorithm_LayoutWindow 2685 +#define wxLayoutAlgorithm_destroy 2686 +#define wxEvent_GetId 2687 +#define wxEvent_GetSkipped 2688 +#define wxEvent_GetTimestamp 2689 +#define wxEvent_IsCommandEvent 2690 +#define wxEvent_ResumePropagation 2691 +#define wxEvent_ShouldPropagate 2692 +#define wxEvent_Skip 2693 +#define wxEvent_StopPropagation 2694 +#define wxCommandEvent_getClientData 2695 +#define wxCommandEvent_GetExtraLong 2696 +#define wxCommandEvent_GetInt 2697 +#define wxCommandEvent_GetSelection 2698 +#define wxCommandEvent_GetString 2699 +#define wxCommandEvent_IsChecked 2700 +#define wxCommandEvent_IsSelection 2701 +#define wxCommandEvent_SetInt 2702 +#define wxCommandEvent_SetString 2703 +#define wxScrollEvent_GetOrientation 2704 +#define wxScrollEvent_GetPosition 2705 +#define wxScrollWinEvent_GetOrientation 2706 +#define wxScrollWinEvent_GetPosition 2707 +#define wxMouseEvent_AltDown 2708 +#define wxMouseEvent_Button 2709 +#define wxMouseEvent_ButtonDClick 2710 +#define wxMouseEvent_ButtonDown 2711 +#define wxMouseEvent_ButtonUp 2712 +#define wxMouseEvent_CmdDown 2713 +#define wxMouseEvent_ControlDown 2714 +#define wxMouseEvent_Dragging 2715 +#define wxMouseEvent_Entering 2716 +#define wxMouseEvent_GetButton 2717 +#define wxMouseEvent_GetPosition 2720 +#define wxMouseEvent_GetLogicalPosition 2721 +#define wxMouseEvent_GetLinesPerAction 2722 +#define wxMouseEvent_GetWheelRotation 2723 +#define wxMouseEvent_GetWheelDelta 2724 +#define wxMouseEvent_GetX 2725 +#define wxMouseEvent_GetY 2726 +#define wxMouseEvent_IsButton 2727 +#define wxMouseEvent_IsPageScroll 2728 +#define wxMouseEvent_Leaving 2729 +#define wxMouseEvent_LeftDClick 2730 +#define wxMouseEvent_LeftDown 2731 +#define wxMouseEvent_LeftIsDown 2732 +#define wxMouseEvent_LeftUp 2733 +#define wxMouseEvent_MetaDown 2734 +#define wxMouseEvent_MiddleDClick 2735 +#define wxMouseEvent_MiddleDown 2736 +#define wxMouseEvent_MiddleIsDown 2737 +#define wxMouseEvent_MiddleUp 2738 +#define wxMouseEvent_Moving 2739 +#define wxMouseEvent_RightDClick 2740 +#define wxMouseEvent_RightDown 2741 +#define wxMouseEvent_RightIsDown 2742 +#define wxMouseEvent_RightUp 2743 +#define wxMouseEvent_ShiftDown 2744 +#define wxSetCursorEvent_GetCursor 2745 +#define wxSetCursorEvent_GetX 2746 +#define wxSetCursorEvent_GetY 2747 +#define wxSetCursorEvent_HasCursor 2748 +#define wxSetCursorEvent_SetCursor 2749 +#define wxKeyEvent_AltDown 2750 +#define wxKeyEvent_CmdDown 2751 +#define wxKeyEvent_ControlDown 2752 +#define wxKeyEvent_GetKeyCode 2753 +#define wxKeyEvent_GetModifiers 2754 +#define wxKeyEvent_GetPosition 2757 +#define wxKeyEvent_GetRawKeyCode 2758 +#define wxKeyEvent_GetRawKeyFlags 2759 +#define wxKeyEvent_GetUnicodeKey 2760 +#define wxKeyEvent_GetX 2761 +#define wxKeyEvent_GetY 2762 +#define wxKeyEvent_HasModifiers 2763 +#define wxKeyEvent_MetaDown 2764 +#define wxKeyEvent_ShiftDown 2765 +#define wxSizeEvent_GetSize 2766 +#define wxMoveEvent_GetPosition 2767 +#define wxEraseEvent_GetDC 2768 +#define wxFocusEvent_GetWindow 2769 +#define wxChildFocusEvent_GetWindow 2770 +#define wxMenuEvent_GetMenu 2771 +#define wxMenuEvent_GetMenuId 2772 +#define wxMenuEvent_IsPopup 2773 +#define wxCloseEvent_CanVeto 2774 +#define wxCloseEvent_GetLoggingOff 2775 +#define wxCloseEvent_SetCanVeto 2776 +#define wxCloseEvent_SetLoggingOff 2777 +#define wxCloseEvent_Veto 2778 +#define wxShowEvent_SetShow 2779 +#define wxShowEvent_GetShow 2780 +#define wxIconizeEvent_Iconized 2781 +#define wxJoystickEvent_ButtonDown 2782 +#define wxJoystickEvent_ButtonIsDown 2783 +#define wxJoystickEvent_ButtonUp 2784 +#define wxJoystickEvent_GetButtonChange 2785 +#define wxJoystickEvent_GetButtonState 2786 +#define wxJoystickEvent_GetJoystick 2787 +#define wxJoystickEvent_GetPosition 2788 +#define wxJoystickEvent_GetZPosition 2789 +#define wxJoystickEvent_IsButton 2790 +#define wxJoystickEvent_IsMove 2791 +#define wxJoystickEvent_IsZMove 2792 +#define wxUpdateUIEvent_CanUpdate 2793 +#define wxUpdateUIEvent_Check 2794 +#define wxUpdateUIEvent_Enable 2795 +#define wxUpdateUIEvent_Show 2796 +#define wxUpdateUIEvent_GetChecked 2797 +#define wxUpdateUIEvent_GetEnabled 2798 +#define wxUpdateUIEvent_GetShown 2799 +#define wxUpdateUIEvent_GetSetChecked 2800 +#define wxUpdateUIEvent_GetSetEnabled 2801 +#define wxUpdateUIEvent_GetSetShown 2802 +#define wxUpdateUIEvent_GetSetText 2803 +#define wxUpdateUIEvent_GetText 2804 +#define wxUpdateUIEvent_GetMode 2805 +#define wxUpdateUIEvent_GetUpdateInterval 2806 +#define wxUpdateUIEvent_ResetUpdateTime 2807 +#define wxUpdateUIEvent_SetMode 2808 +#define wxUpdateUIEvent_SetText 2809 +#define wxUpdateUIEvent_SetUpdateInterval 2810 +#define wxMouseCaptureChangedEvent_GetCapturedWindow 2811 +#define wxPaletteChangedEvent_SetChangedWindow 2812 +#define wxPaletteChangedEvent_GetChangedWindow 2813 +#define wxQueryNewPaletteEvent_SetPaletteRealized 2814 +#define wxQueryNewPaletteEvent_GetPaletteRealized 2815 +#define wxNavigationKeyEvent_GetDirection 2816 +#define wxNavigationKeyEvent_SetDirection 2817 +#define wxNavigationKeyEvent_IsWindowChange 2818 +#define wxNavigationKeyEvent_SetWindowChange 2819 +#define wxNavigationKeyEvent_IsFromTab 2820 +#define wxNavigationKeyEvent_SetFromTab 2821 +#define wxNavigationKeyEvent_GetCurrentFocus 2822 +#define wxNavigationKeyEvent_SetCurrentFocus 2823 +#define wxHelpEvent_GetOrigin 2824 +#define wxHelpEvent_GetPosition 2825 +#define wxHelpEvent_SetOrigin 2826 +#define wxHelpEvent_SetPosition 2827 +#define wxContextMenuEvent_GetPosition 2828 +#define wxContextMenuEvent_SetPosition 2829 +#define wxIdleEvent_CanSend 2830 +#define wxIdleEvent_GetMode 2831 +#define wxIdleEvent_RequestMore 2832 +#define wxIdleEvent_MoreRequested 2833 +#define wxIdleEvent_SetMode 2834 +#define wxGridEvent_AltDown 2835 +#define wxGridEvent_ControlDown 2836 +#define wxGridEvent_GetCol 2837 +#define wxGridEvent_GetPosition 2838 +#define wxGridEvent_GetRow 2839 +#define wxGridEvent_MetaDown 2840 +#define wxGridEvent_Selecting 2841 +#define wxGridEvent_ShiftDown 2842 +#define wxNotifyEvent_Allow 2843 +#define wxNotifyEvent_IsAllowed 2844 +#define wxNotifyEvent_Veto 2845 +#define wxSashEvent_GetEdge 2846 +#define wxSashEvent_GetDragRect 2847 +#define wxSashEvent_GetDragStatus 2848 +#define wxListEvent_GetCacheFrom 2849 +#define wxListEvent_GetCacheTo 2850 +#define wxListEvent_GetKeyCode 2851 +#define wxListEvent_GetIndex 2852 +#define wxListEvent_GetColumn 2853 +#define wxListEvent_GetPoint 2854 +#define wxListEvent_GetLabel 2855 +#define wxListEvent_GetText 2856 +#define wxListEvent_GetImage 2857 +#define wxListEvent_GetData 2858 +#define wxListEvent_GetMask 2859 +#define wxListEvent_GetItem 2860 +#define wxListEvent_IsEditCancelled 2861 +#define wxDateEvent_GetDate 2862 +#define wxCalendarEvent_GetWeekDay 2863 +#define wxFileDirPickerEvent_GetPath 2864 +#define wxColourPickerEvent_GetColour 2865 +#define wxFontPickerEvent_GetFont 2866 +#define wxStyledTextEvent_GetPosition 2867 +#define wxStyledTextEvent_GetKey 2868 +#define wxStyledTextEvent_GetModifiers 2869 +#define wxStyledTextEvent_GetModificationType 2870 +#define wxStyledTextEvent_GetText 2871 +#define wxStyledTextEvent_GetLength 2872 +#define wxStyledTextEvent_GetLinesAdded 2873 +#define wxStyledTextEvent_GetLine 2874 +#define wxStyledTextEvent_GetFoldLevelNow 2875 +#define wxStyledTextEvent_GetFoldLevelPrev 2876 +#define wxStyledTextEvent_GetMargin 2877 +#define wxStyledTextEvent_GetMessage 2878 +#define wxStyledTextEvent_GetWParam 2879 +#define wxStyledTextEvent_GetLParam 2880 +#define wxStyledTextEvent_GetListType 2881 +#define wxStyledTextEvent_GetX 2882 +#define wxStyledTextEvent_GetY 2883 +#define wxStyledTextEvent_GetDragText 2884 +#define wxStyledTextEvent_GetDragAllowMove 2885 +#define wxStyledTextEvent_GetDragResult 2886 +#define wxStyledTextEvent_GetShift 2887 +#define wxStyledTextEvent_GetControl 2888 +#define wxStyledTextEvent_GetAlt 2889 +#define utils_wxGetKeyState 2890 +#define utils_wxGetMousePosition 2891 +#define utils_wxGetMouseState 2892 +#define utils_wxSetDetectableAutoRepeat 2893 +#define utils_wxBell 2894 +#define utils_wxFindMenuItemId 2895 +#define utils_wxGenericFindWindowAtPoint 2896 +#define utils_wxFindWindowAtPoint 2897 +#define utils_wxBeginBusyCursor 2898 +#define utils_wxEndBusyCursor 2899 +#define utils_wxIsBusy 2900 +#define utils_wxShutdown 2901 +#define utils_wxShell 2902 +#define utils_wxLaunchDefaultBrowser 2903 +#define utils_wxGetEmailAddress 2904 +#define utils_wxGetUserId 2905 +#define utils_wxGetHomeDir 2906 +#define utils_wxNewId 2907 +#define utils_wxRegisterId 2908 +#define utils_wxGetCurrentId 2909 +#define utils_wxGetOsDescription 2910 +#define utils_wxIsPlatformLittleEndian 2911 +#define utils_wxIsPlatform64Bit 2912 +#define wxPrintout_new 2913 +#define wxPrintout_destruct 2914 +#define wxPrintout_GetDC 2915 +#define wxPrintout_GetPageSizeMM 2916 +#define wxPrintout_GetPageSizePixels 2917 +#define wxPrintout_GetPaperRectPixels 2918 +#define wxPrintout_GetPPIPrinter 2919 +#define wxPrintout_GetPPIScreen 2920 +#define wxPrintout_GetTitle 2921 +#define wxPrintout_IsPreview 2922 +#define wxPrintout_FitThisSizeToPaper 2923 +#define wxPrintout_FitThisSizeToPage 2924 +#define wxPrintout_FitThisSizeToPageMargins 2925 +#define wxPrintout_MapScreenSizeToPaper 2926 +#define wxPrintout_MapScreenSizeToPage 2927 +#define wxPrintout_MapScreenSizeToPageMargins 2928 +#define wxPrintout_MapScreenSizeToDevice 2929 +#define wxPrintout_GetLogicalPaperRect 2930 +#define wxPrintout_GetLogicalPageRect 2931 +#define wxPrintout_GetLogicalPageMarginsRect 2932 +#define wxPrintout_SetLogicalOrigin 2933 +#define wxPrintout_OffsetLogicalOrigin 2934 +#define wxStyledTextCtrl_new_2 2935 +#define wxStyledTextCtrl_new_0 2936 +#define wxStyledTextCtrl_destruct 2937 +#define wxStyledTextCtrl_Create 2938 +#define wxStyledTextCtrl_AddText 2939 +#define wxStyledTextCtrl_AddStyledText 2940 +#define wxStyledTextCtrl_InsertText 2941 +#define wxStyledTextCtrl_ClearAll 2942 +#define wxStyledTextCtrl_ClearDocumentStyle 2943 +#define wxStyledTextCtrl_GetLength 2944 +#define wxStyledTextCtrl_GetCharAt 2945 +#define wxStyledTextCtrl_GetCurrentPos 2946 +#define wxStyledTextCtrl_GetAnchor 2947 +#define wxStyledTextCtrl_GetStyleAt 2948 +#define wxStyledTextCtrl_Redo 2949 +#define wxStyledTextCtrl_SetUndoCollection 2950 +#define wxStyledTextCtrl_SelectAll 2951 +#define wxStyledTextCtrl_SetSavePoint 2952 +#define wxStyledTextCtrl_GetStyledText 2953 +#define wxStyledTextCtrl_CanRedo 2954 +#define wxStyledTextCtrl_MarkerLineFromHandle 2955 +#define wxStyledTextCtrl_MarkerDeleteHandle 2956 +#define wxStyledTextCtrl_GetUndoCollection 2957 +#define wxStyledTextCtrl_GetViewWhiteSpace 2958 +#define wxStyledTextCtrl_SetViewWhiteSpace 2959 +#define wxStyledTextCtrl_PositionFromPoint 2960 +#define wxStyledTextCtrl_PositionFromPointClose 2961 +#define wxStyledTextCtrl_GotoLine 2962 +#define wxStyledTextCtrl_GotoPos 2963 +#define wxStyledTextCtrl_SetAnchor 2964 +#define wxStyledTextCtrl_GetCurLine 2965 +#define wxStyledTextCtrl_GetEndStyled 2966 +#define wxStyledTextCtrl_ConvertEOLs 2967 +#define wxStyledTextCtrl_GetEOLMode 2968 +#define wxStyledTextCtrl_SetEOLMode 2969 +#define wxStyledTextCtrl_StartStyling 2970 +#define wxStyledTextCtrl_SetStyling 2971 +#define wxStyledTextCtrl_GetBufferedDraw 2972 +#define wxStyledTextCtrl_SetBufferedDraw 2973 +#define wxStyledTextCtrl_SetTabWidth 2974 +#define wxStyledTextCtrl_GetTabWidth 2975 +#define wxStyledTextCtrl_SetCodePage 2976 +#define wxStyledTextCtrl_MarkerDefine 2977 +#define wxStyledTextCtrl_MarkerSetForeground 2978 +#define wxStyledTextCtrl_MarkerSetBackground 2979 +#define wxStyledTextCtrl_MarkerAdd 2980 +#define wxStyledTextCtrl_MarkerDelete 2981 +#define wxStyledTextCtrl_MarkerDeleteAll 2982 +#define wxStyledTextCtrl_MarkerGet 2983 +#define wxStyledTextCtrl_MarkerNext 2984 +#define wxStyledTextCtrl_MarkerPrevious 2985 +#define wxStyledTextCtrl_MarkerDefineBitmap 2986 +#define wxStyledTextCtrl_MarkerAddSet 2987 +#define wxStyledTextCtrl_MarkerSetAlpha 2988 +#define wxStyledTextCtrl_SetMarginType 2989 +#define wxStyledTextCtrl_GetMarginType 2990 +#define wxStyledTextCtrl_SetMarginWidth 2991 +#define wxStyledTextCtrl_GetMarginWidth 2992 +#define wxStyledTextCtrl_SetMarginMask 2993 +#define wxStyledTextCtrl_GetMarginMask 2994 +#define wxStyledTextCtrl_SetMarginSensitive 2995 +#define wxStyledTextCtrl_GetMarginSensitive 2996 +#define wxStyledTextCtrl_StyleClearAll 2997 +#define wxStyledTextCtrl_StyleSetForeground 2998 +#define wxStyledTextCtrl_StyleSetBackground 2999 +#define wxStyledTextCtrl_StyleSetBold 3000 +#define wxStyledTextCtrl_StyleSetItalic 3001 +#define wxStyledTextCtrl_StyleSetSize 3002 +#define wxStyledTextCtrl_StyleSetFaceName 3003 +#define wxStyledTextCtrl_StyleSetEOLFilled 3004 +#define wxStyledTextCtrl_StyleResetDefault 3005 +#define wxStyledTextCtrl_StyleSetUnderline 3006 +#define wxStyledTextCtrl_StyleSetCase 3007 +#define wxStyledTextCtrl_StyleSetHotSpot 3008 +#define wxStyledTextCtrl_SetSelForeground 3009 +#define wxStyledTextCtrl_SetSelBackground 3010 +#define wxStyledTextCtrl_GetSelAlpha 3011 +#define wxStyledTextCtrl_SetSelAlpha 3012 +#define wxStyledTextCtrl_SetCaretForeground 3013 +#define wxStyledTextCtrl_CmdKeyAssign 3014 +#define wxStyledTextCtrl_CmdKeyClear 3015 +#define wxStyledTextCtrl_CmdKeyClearAll 3016 +#define wxStyledTextCtrl_SetStyleBytes 3017 +#define wxStyledTextCtrl_StyleSetVisible 3018 +#define wxStyledTextCtrl_GetCaretPeriod 3019 +#define wxStyledTextCtrl_SetCaretPeriod 3020 +#define wxStyledTextCtrl_SetWordChars 3021 +#define wxStyledTextCtrl_BeginUndoAction 3022 +#define wxStyledTextCtrl_EndUndoAction 3023 +#define wxStyledTextCtrl_IndicatorSetStyle 3024 +#define wxStyledTextCtrl_IndicatorGetStyle 3025 +#define wxStyledTextCtrl_IndicatorSetForeground 3026 +#define wxStyledTextCtrl_IndicatorGetForeground 3027 +#define wxStyledTextCtrl_SetWhitespaceForeground 3028 +#define wxStyledTextCtrl_SetWhitespaceBackground 3029 +#define wxStyledTextCtrl_GetStyleBits 3030 +#define wxStyledTextCtrl_SetLineState 3031 +#define wxStyledTextCtrl_GetLineState 3032 +#define wxStyledTextCtrl_GetMaxLineState 3033 +#define wxStyledTextCtrl_GetCaretLineVisible 3034 +#define wxStyledTextCtrl_SetCaretLineVisible 3035 +#define wxStyledTextCtrl_GetCaretLineBackground 3036 +#define wxStyledTextCtrl_SetCaretLineBackground 3037 +#define wxStyledTextCtrl_AutoCompShow 3038 +#define wxStyledTextCtrl_AutoCompCancel 3039 +#define wxStyledTextCtrl_AutoCompActive 3040 +#define wxStyledTextCtrl_AutoCompPosStart 3041 +#define wxStyledTextCtrl_AutoCompComplete 3042 +#define wxStyledTextCtrl_AutoCompStops 3043 +#define wxStyledTextCtrl_AutoCompSetSeparator 3044 +#define wxStyledTextCtrl_AutoCompGetSeparator 3045 +#define wxStyledTextCtrl_AutoCompSelect 3046 +#define wxStyledTextCtrl_AutoCompSetCancelAtStart 3047 +#define wxStyledTextCtrl_AutoCompGetCancelAtStart 3048 +#define wxStyledTextCtrl_AutoCompSetFillUps 3049 +#define wxStyledTextCtrl_AutoCompSetChooseSingle 3050 +#define wxStyledTextCtrl_AutoCompGetChooseSingle 3051 +#define wxStyledTextCtrl_AutoCompSetIgnoreCase 3052 +#define wxStyledTextCtrl_AutoCompGetIgnoreCase 3053 +#define wxStyledTextCtrl_UserListShow 3054 +#define wxStyledTextCtrl_AutoCompSetAutoHide 3055 +#define wxStyledTextCtrl_AutoCompGetAutoHide 3056 +#define wxStyledTextCtrl_AutoCompSetDropRestOfWord 3057 +#define wxStyledTextCtrl_AutoCompGetDropRestOfWord 3058 +#define wxStyledTextCtrl_RegisterImage 3059 +#define wxStyledTextCtrl_ClearRegisteredImages 3060 +#define wxStyledTextCtrl_AutoCompGetTypeSeparator 3061 +#define wxStyledTextCtrl_AutoCompSetTypeSeparator 3062 +#define wxStyledTextCtrl_AutoCompSetMaxWidth 3063 +#define wxStyledTextCtrl_AutoCompGetMaxWidth 3064 +#define wxStyledTextCtrl_AutoCompSetMaxHeight 3065 +#define wxStyledTextCtrl_AutoCompGetMaxHeight 3066 +#define wxStyledTextCtrl_SetIndent 3067 +#define wxStyledTextCtrl_GetIndent 3068 +#define wxStyledTextCtrl_SetUseTabs 3069 +#define wxStyledTextCtrl_GetUseTabs 3070 +#define wxStyledTextCtrl_SetLineIndentation 3071 +#define wxStyledTextCtrl_GetLineIndentation 3072 +#define wxStyledTextCtrl_GetLineIndentPosition 3073 +#define wxStyledTextCtrl_GetColumn 3074 +#define wxStyledTextCtrl_SetUseHorizontalScrollBar 3075 +#define wxStyledTextCtrl_GetUseHorizontalScrollBar 3076 +#define wxStyledTextCtrl_SetIndentationGuides 3077 +#define wxStyledTextCtrl_GetIndentationGuides 3078 +#define wxStyledTextCtrl_SetHighlightGuide 3079 +#define wxStyledTextCtrl_GetHighlightGuide 3080 +#define wxStyledTextCtrl_GetLineEndPosition 3081 +#define wxStyledTextCtrl_GetCodePage 3082 +#define wxStyledTextCtrl_GetCaretForeground 3083 +#define wxStyledTextCtrl_GetReadOnly 3084 +#define wxStyledTextCtrl_SetCurrentPos 3085 +#define wxStyledTextCtrl_SetSelectionStart 3086 +#define wxStyledTextCtrl_GetSelectionStart 3087 +#define wxStyledTextCtrl_SetSelectionEnd 3088 +#define wxStyledTextCtrl_GetSelectionEnd 3089 +#define wxStyledTextCtrl_SetPrintMagnification 3090 +#define wxStyledTextCtrl_GetPrintMagnification 3091 +#define wxStyledTextCtrl_SetPrintColourMode 3092 +#define wxStyledTextCtrl_GetPrintColourMode 3093 +#define wxStyledTextCtrl_FindText 3094 +#define wxStyledTextCtrl_FormatRange 3095 +#define wxStyledTextCtrl_GetFirstVisibleLine 3096 +#define wxStyledTextCtrl_GetLine 3097 +#define wxStyledTextCtrl_GetLineCount 3098 +#define wxStyledTextCtrl_SetMarginLeft 3099 +#define wxStyledTextCtrl_GetMarginLeft 3100 +#define wxStyledTextCtrl_SetMarginRight 3101 +#define wxStyledTextCtrl_GetMarginRight 3102 +#define wxStyledTextCtrl_GetModify 3103 +#define wxStyledTextCtrl_SetSelection 3104 +#define wxStyledTextCtrl_GetSelectedText 3105 +#define wxStyledTextCtrl_GetTextRange 3106 +#define wxStyledTextCtrl_HideSelection 3107 +#define wxStyledTextCtrl_LineFromPosition 3108 +#define wxStyledTextCtrl_PositionFromLine 3109 +#define wxStyledTextCtrl_LineScroll 3110 +#define wxStyledTextCtrl_EnsureCaretVisible 3111 +#define wxStyledTextCtrl_ReplaceSelection 3112 +#define wxStyledTextCtrl_SetReadOnly 3113 +#define wxStyledTextCtrl_CanPaste 3114 +#define wxStyledTextCtrl_CanUndo 3115 +#define wxStyledTextCtrl_EmptyUndoBuffer 3116 +#define wxStyledTextCtrl_Undo 3117 +#define wxStyledTextCtrl_Cut 3118 +#define wxStyledTextCtrl_Copy 3119 +#define wxStyledTextCtrl_Paste 3120 +#define wxStyledTextCtrl_Clear 3121 +#define wxStyledTextCtrl_SetText 3122 +#define wxStyledTextCtrl_GetText 3123 +#define wxStyledTextCtrl_GetTextLength 3124 +#define wxStyledTextCtrl_GetOvertype 3125 +#define wxStyledTextCtrl_SetCaretWidth 3126 +#define wxStyledTextCtrl_GetCaretWidth 3127 +#define wxStyledTextCtrl_SetTargetStart 3128 +#define wxStyledTextCtrl_GetTargetStart 3129 +#define wxStyledTextCtrl_SetTargetEnd 3130 +#define wxStyledTextCtrl_GetTargetEnd 3131 +#define wxStyledTextCtrl_ReplaceTarget 3132 +#define wxStyledTextCtrl_SearchInTarget 3133 +#define wxStyledTextCtrl_SetSearchFlags 3134 +#define wxStyledTextCtrl_GetSearchFlags 3135 +#define wxStyledTextCtrl_CallTipShow 3136 +#define wxStyledTextCtrl_CallTipCancel 3137 +#define wxStyledTextCtrl_CallTipActive 3138 +#define wxStyledTextCtrl_CallTipPosAtStart 3139 +#define wxStyledTextCtrl_CallTipSetHighlight 3140 +#define wxStyledTextCtrl_CallTipSetBackground 3141 +#define wxStyledTextCtrl_CallTipSetForeground 3142 +#define wxStyledTextCtrl_CallTipSetForegroundHighlight 3143 +#define wxStyledTextCtrl_CallTipUseStyle 3144 +#define wxStyledTextCtrl_VisibleFromDocLine 3145 +#define wxStyledTextCtrl_DocLineFromVisible 3146 +#define wxStyledTextCtrl_WrapCount 3147 +#define wxStyledTextCtrl_SetFoldLevel 3148 +#define wxStyledTextCtrl_GetFoldLevel 3149 +#define wxStyledTextCtrl_GetLastChild 3150 +#define wxStyledTextCtrl_GetFoldParent 3151 +#define wxStyledTextCtrl_ShowLines 3152 +#define wxStyledTextCtrl_HideLines 3153 +#define wxStyledTextCtrl_GetLineVisible 3154 +#define wxStyledTextCtrl_SetFoldExpanded 3155 +#define wxStyledTextCtrl_GetFoldExpanded 3156 +#define wxStyledTextCtrl_ToggleFold 3157 +#define wxStyledTextCtrl_EnsureVisible 3158 +#define wxStyledTextCtrl_SetFoldFlags 3159 +#define wxStyledTextCtrl_EnsureVisibleEnforcePolicy 3160 +#define wxStyledTextCtrl_SetTabIndents 3161 +#define wxStyledTextCtrl_GetTabIndents 3162 +#define wxStyledTextCtrl_SetBackSpaceUnIndents 3163 +#define wxStyledTextCtrl_GetBackSpaceUnIndents 3164 +#define wxStyledTextCtrl_SetMouseDwellTime 3165 +#define wxStyledTextCtrl_GetMouseDwellTime 3166 +#define wxStyledTextCtrl_WordStartPosition 3167 +#define wxStyledTextCtrl_WordEndPosition 3168 +#define wxStyledTextCtrl_SetWrapMode 3169 +#define wxStyledTextCtrl_GetWrapMode 3170 +#define wxStyledTextCtrl_SetWrapVisualFlags 3171 +#define wxStyledTextCtrl_GetWrapVisualFlags 3172 +#define wxStyledTextCtrl_SetWrapVisualFlagsLocation 3173 +#define wxStyledTextCtrl_GetWrapVisualFlagsLocation 3174 +#define wxStyledTextCtrl_SetWrapStartIndent 3175 +#define wxStyledTextCtrl_GetWrapStartIndent 3176 +#define wxStyledTextCtrl_SetLayoutCache 3177 +#define wxStyledTextCtrl_GetLayoutCache 3178 +#define wxStyledTextCtrl_SetScrollWidth 3179 +#define wxStyledTextCtrl_GetScrollWidth 3180 +#define wxStyledTextCtrl_TextWidth 3181 +#define wxStyledTextCtrl_GetEndAtLastLine 3182 +#define wxStyledTextCtrl_TextHeight 3183 +#define wxStyledTextCtrl_SetUseVerticalScrollBar 3184 +#define wxStyledTextCtrl_GetUseVerticalScrollBar 3185 +#define wxStyledTextCtrl_AppendText 3186 +#define wxStyledTextCtrl_GetTwoPhaseDraw 3187 +#define wxStyledTextCtrl_SetTwoPhaseDraw 3188 +#define wxStyledTextCtrl_TargetFromSelection 3189 +#define wxStyledTextCtrl_LinesJoin 3190 +#define wxStyledTextCtrl_LinesSplit 3191 +#define wxStyledTextCtrl_SetFoldMarginColour 3192 +#define wxStyledTextCtrl_SetFoldMarginHiColour 3193 +#define wxStyledTextCtrl_LineDown 3194 +#define wxStyledTextCtrl_LineDownExtend 3195 +#define wxStyledTextCtrl_LineUp 3196 +#define wxStyledTextCtrl_LineUpExtend 3197 +#define wxStyledTextCtrl_CharLeft 3198 +#define wxStyledTextCtrl_CharLeftExtend 3199 +#define wxStyledTextCtrl_CharRight 3200 +#define wxStyledTextCtrl_CharRightExtend 3201 +#define wxStyledTextCtrl_WordLeft 3202 +#define wxStyledTextCtrl_WordLeftExtend 3203 +#define wxStyledTextCtrl_WordRight 3204 +#define wxStyledTextCtrl_WordRightExtend 3205 +#define wxStyledTextCtrl_Home 3206 +#define wxStyledTextCtrl_HomeExtend 3207 +#define wxStyledTextCtrl_LineEnd 3208 +#define wxStyledTextCtrl_LineEndExtend 3209 +#define wxStyledTextCtrl_DocumentStart 3210 +#define wxStyledTextCtrl_DocumentStartExtend 3211 +#define wxStyledTextCtrl_DocumentEnd 3212 +#define wxStyledTextCtrl_DocumentEndExtend 3213 +#define wxStyledTextCtrl_PageUp 3214 +#define wxStyledTextCtrl_PageUpExtend 3215 +#define wxStyledTextCtrl_PageDown 3216 +#define wxStyledTextCtrl_PageDownExtend 3217 +#define wxStyledTextCtrl_EditToggleOvertype 3218 +#define wxStyledTextCtrl_Cancel 3219 +#define wxStyledTextCtrl_DeleteBack 3220 +#define wxStyledTextCtrl_Tab 3221 +#define wxStyledTextCtrl_BackTab 3222 +#define wxStyledTextCtrl_NewLine 3223 +#define wxStyledTextCtrl_FormFeed 3224 +#define wxStyledTextCtrl_VCHome 3225 +#define wxStyledTextCtrl_VCHomeExtend 3226 +#define wxStyledTextCtrl_ZoomIn 3227 +#define wxStyledTextCtrl_ZoomOut 3228 +#define wxStyledTextCtrl_DelWordLeft 3229 +#define wxStyledTextCtrl_DelWordRight 3230 +#define wxStyledTextCtrl_LineCut 3231 +#define wxStyledTextCtrl_LineDelete 3232 +#define wxStyledTextCtrl_LineTranspose 3233 +#define wxStyledTextCtrl_LineDuplicate 3234 +#define wxStyledTextCtrl_LowerCase 3235 +#define wxStyledTextCtrl_UpperCase 3236 +#define wxStyledTextCtrl_LineScrollDown 3237 +#define wxStyledTextCtrl_LineScrollUp 3238 +#define wxStyledTextCtrl_DeleteBackNotLine 3239 +#define wxStyledTextCtrl_HomeDisplay 3240 +#define wxStyledTextCtrl_HomeDisplayExtend 3241 +#define wxStyledTextCtrl_LineEndDisplay 3242 +#define wxStyledTextCtrl_LineEndDisplayExtend 3243 +#define wxStyledTextCtrl_HomeWrapExtend 3244 +#define wxStyledTextCtrl_LineEndWrap 3245 +#define wxStyledTextCtrl_LineEndWrapExtend 3246 +#define wxStyledTextCtrl_VCHomeWrap 3247 +#define wxStyledTextCtrl_VCHomeWrapExtend 3248 +#define wxStyledTextCtrl_LineCopy 3249 +#define wxStyledTextCtrl_MoveCaretInsideView 3250 +#define wxStyledTextCtrl_LineLength 3251 +#define wxStyledTextCtrl_BraceHighlight 3252 +#define wxStyledTextCtrl_BraceBadLight 3253 +#define wxStyledTextCtrl_BraceMatch 3254 +#define wxStyledTextCtrl_GetViewEOL 3255 +#define wxStyledTextCtrl_SetViewEOL 3256 +#define wxStyledTextCtrl_SetModEventMask 3257 +#define wxStyledTextCtrl_GetEdgeColumn 3258 +#define wxStyledTextCtrl_SetEdgeColumn 3259 +#define wxStyledTextCtrl_GetEdgeMode 3260 +#define wxStyledTextCtrl_GetEdgeColour 3261 +#define wxStyledTextCtrl_SetEdgeColour 3262 +#define wxStyledTextCtrl_SearchAnchor 3263 +#define wxStyledTextCtrl_SearchNext 3264 +#define wxStyledTextCtrl_SearchPrev 3265 +#define wxStyledTextCtrl_LinesOnScreen 3266 +#define wxStyledTextCtrl_UsePopUp 3267 +#define wxStyledTextCtrl_SelectionIsRectangle 3268 +#define wxStyledTextCtrl_SetZoom 3269 +#define wxStyledTextCtrl_GetZoom 3270 +#define wxStyledTextCtrl_GetModEventMask 3271 +#define wxStyledTextCtrl_SetSTCFocus 3272 +#define wxStyledTextCtrl_GetSTCFocus 3273 +#define wxStyledTextCtrl_SetStatus 3274 +#define wxStyledTextCtrl_GetStatus 3275 +#define wxStyledTextCtrl_SetMouseDownCaptures 3276 +#define wxStyledTextCtrl_GetMouseDownCaptures 3277 +#define wxStyledTextCtrl_SetSTCCursor 3278 +#define wxStyledTextCtrl_GetSTCCursor 3279 +#define wxStyledTextCtrl_SetControlCharSymbol 3280 +#define wxStyledTextCtrl_GetControlCharSymbol 3281 +#define wxStyledTextCtrl_WordPartLeft 3282 +#define wxStyledTextCtrl_WordPartLeftExtend 3283 +#define wxStyledTextCtrl_WordPartRight 3284 +#define wxStyledTextCtrl_WordPartRightExtend 3285 +#define wxStyledTextCtrl_SetVisiblePolicy 3286 +#define wxStyledTextCtrl_DelLineLeft 3287 +#define wxStyledTextCtrl_DelLineRight 3288 +#define wxStyledTextCtrl_GetXOffset 3289 +#define wxStyledTextCtrl_ChooseCaretX 3290 +#define wxStyledTextCtrl_SetXCaretPolicy 3291 +#define wxStyledTextCtrl_SetYCaretPolicy 3292 +#define wxStyledTextCtrl_GetPrintWrapMode 3293 +#define wxStyledTextCtrl_SetHotspotActiveForeground 3294 +#define wxStyledTextCtrl_SetHotspotActiveBackground 3295 +#define wxStyledTextCtrl_SetHotspotActiveUnderline 3296 +#define wxStyledTextCtrl_SetHotspotSingleLine 3297 +#define wxStyledTextCtrl_ParaDownExtend 3298 +#define wxStyledTextCtrl_ParaUp 3299 +#define wxStyledTextCtrl_ParaUpExtend 3300 +#define wxStyledTextCtrl_PositionBefore 3301 +#define wxStyledTextCtrl_PositionAfter 3302 +#define wxStyledTextCtrl_CopyRange 3303 +#define wxStyledTextCtrl_CopyText 3304 +#define wxStyledTextCtrl_SetSelectionMode 3305 +#define wxStyledTextCtrl_GetSelectionMode 3306 +#define wxStyledTextCtrl_LineDownRectExtend 3307 +#define wxStyledTextCtrl_LineUpRectExtend 3308 +#define wxStyledTextCtrl_CharLeftRectExtend 3309 +#define wxStyledTextCtrl_CharRightRectExtend 3310 +#define wxStyledTextCtrl_HomeRectExtend 3311 +#define wxStyledTextCtrl_VCHomeRectExtend 3312 +#define wxStyledTextCtrl_LineEndRectExtend 3313 +#define wxStyledTextCtrl_PageUpRectExtend 3314 +#define wxStyledTextCtrl_PageDownRectExtend 3315 +#define wxStyledTextCtrl_StutteredPageUp 3316 +#define wxStyledTextCtrl_StutteredPageUpExtend 3317 +#define wxStyledTextCtrl_StutteredPageDown 3318 +#define wxStyledTextCtrl_StutteredPageDownExtend 3319 +#define wxStyledTextCtrl_WordLeftEnd 3320 +#define wxStyledTextCtrl_WordLeftEndExtend 3321 +#define wxStyledTextCtrl_WordRightEnd 3322 +#define wxStyledTextCtrl_WordRightEndExtend 3323 +#define wxStyledTextCtrl_SetWhitespaceChars 3324 +#define wxStyledTextCtrl_SetCharsDefault 3325 +#define wxStyledTextCtrl_AutoCompGetCurrent 3326 +#define wxStyledTextCtrl_Allocate 3327 +#define wxStyledTextCtrl_FindColumn 3328 +#define wxStyledTextCtrl_GetCaretSticky 3329 +#define wxStyledTextCtrl_SetCaretSticky 3330 +#define wxStyledTextCtrl_ToggleCaretSticky 3331 +#define wxStyledTextCtrl_SetPasteConvertEndings 3332 +#define wxStyledTextCtrl_GetPasteConvertEndings 3333 +#define wxStyledTextCtrl_SelectionDuplicate 3334 +#define wxStyledTextCtrl_SetCaretLineBackAlpha 3335 +#define wxStyledTextCtrl_GetCaretLineBackAlpha 3336 +#define wxStyledTextCtrl_StartRecord 3337 +#define wxStyledTextCtrl_StopRecord 3338 +#define wxStyledTextCtrl_SetLexer 3339 +#define wxStyledTextCtrl_GetLexer 3340 +#define wxStyledTextCtrl_Colourise 3341 +#define wxStyledTextCtrl_SetProperty 3342 +#define wxStyledTextCtrl_SetKeyWords 3343 +#define wxStyledTextCtrl_SetLexerLanguage 3344 +#define wxStyledTextCtrl_GetProperty 3345 +#define wxStyledTextCtrl_GetStyleBitsNeeded 3346 +#define wxStyledTextCtrl_GetCurrentLine 3347 +#define wxStyledTextCtrl_StyleSetSpec 3348 +#define wxStyledTextCtrl_StyleSetFont 3349 +#define wxStyledTextCtrl_StyleSetFontAttr 3350 +#define wxStyledTextCtrl_StyleSetCharacterSet 3351 +#define wxStyledTextCtrl_StyleSetFontEncoding 3352 +#define wxStyledTextCtrl_CmdKeyExecute 3353 +#define wxStyledTextCtrl_SetMargins 3354 +#define wxStyledTextCtrl_GetSelection 3355 +#define wxStyledTextCtrl_PointFromPosition 3356 +#define wxStyledTextCtrl_ScrollToLine 3357 +#define wxStyledTextCtrl_ScrollToColumn 3358 +#define wxStyledTextCtrl_SendMsg 3359 +#define wxStyledTextCtrl_SetVScrollBar 3360 +#define wxStyledTextCtrl_SetHScrollBar 3361 +#define wxStyledTextCtrl_GetLastKeydownProcessed 3362 +#define wxStyledTextCtrl_SetLastKeydownProcessed 3363 +#define wxStyledTextCtrl_SaveFile 3364 +#define wxStyledTextCtrl_LoadFile 3365 +#define wxStyledTextCtrl_DoDragOver 3366 +#define wxStyledTextCtrl_DoDropText 3367 +#define wxStyledTextCtrl_GetUseAntiAliasing 3368 +#define wxStyledTextCtrl_AddTextRaw 3369 +#define wxStyledTextCtrl_InsertTextRaw 3370 +#define wxStyledTextCtrl_GetCurLineRaw 3371 +#define wxStyledTextCtrl_GetLineRaw 3372 +#define wxStyledTextCtrl_GetSelectedTextRaw 3373 +#define wxStyledTextCtrl_GetTextRangeRaw 3374 +#define wxStyledTextCtrl_SetTextRaw 3375 +#define wxStyledTextCtrl_GetTextRaw 3376 +#define wxStyledTextCtrl_AppendTextRaw 3377 +#define wxArtProvider_GetBitmap 3378 +#define wxArtProvider_GetIcon 3379 +#define wxTreeEvent_GetKeyCode 3380 +#define wxTreeEvent_GetItem 3381 +#define wxTreeEvent_GetKeyEvent 3382 +#define wxTreeEvent_GetLabel 3383 +#define wxTreeEvent_GetOldItem 3384 +#define wxTreeEvent_GetPoint 3385 +#define wxTreeEvent_IsEditCancelled 3386 +#define wxTreeEvent_SetToolTip 3387 +#define wxNotebookEvent_GetOldSelection 3388 +#define wxNotebookEvent_GetSelection 3389 +#define wxNotebookEvent_SetOldSelection 3390 +#define wxNotebookEvent_SetSelection 3391 +#define wxFileDataObject_new 3392 +#define wxFileDataObject_AddFile 3393 +#define wxFileDataObject_GetFilenames 3394 +#define wxFileDataObject_destroy 3395 +#define wxTextDataObject_new 3396 +#define wxTextDataObject_GetTextLength 3397 +#define wxTextDataObject_GetText 3398 +#define wxTextDataObject_SetText 3399 +#define wxTextDataObject_destroy 3400 +#define wxBitmapDataObject_new_1_1 3401 +#define wxBitmapDataObject_new_1_0 3402 +#define wxBitmapDataObject_GetBitmap 3403 +#define wxBitmapDataObject_SetBitmap 3404 +#define wxBitmapDataObject_destroy 3405 +#define wxClipboard_new 3407 +#define wxClipboard_destruct 3408 +#define wxClipboard_AddData 3409 +#define wxClipboard_Clear 3410 +#define wxClipboard_Close 3411 +#define wxClipboard_Flush 3412 +#define wxClipboard_GetData 3413 +#define wxClipboard_IsOpened 3414 +#define wxClipboard_Open 3415 +#define wxClipboard_SetData 3416 +#define wxClipboard_UsePrimarySelection 3418 +#define wxClipboard_IsSupported 3419 +#define wxClipboard_Get 3420 +#define wxSpinEvent_GetPosition 3421 +#define wxSpinEvent_SetPosition 3422 +#define wxSplitterWindow_new_0 3423 +#define wxSplitterWindow_new_2 3424 +#define wxSplitterWindow_destruct 3425 +#define wxSplitterWindow_Create 3426 +#define wxSplitterWindow_GetMinimumPaneSize 3427 +#define wxSplitterWindow_GetSashGravity 3428 +#define wxSplitterWindow_GetSashPosition 3429 +#define wxSplitterWindow_GetSplitMode 3430 +#define wxSplitterWindow_GetWindow1 3431 +#define wxSplitterWindow_GetWindow2 3432 +#define wxSplitterWindow_Initialize 3433 +#define wxSplitterWindow_IsSplit 3434 +#define wxSplitterWindow_ReplaceWindow 3435 +#define wxSplitterWindow_SetSashGravity 3436 +#define wxSplitterWindow_SetSashPosition 3437 +#define wxSplitterWindow_SetSashSize 3438 +#define wxSplitterWindow_SetMinimumPaneSize 3439 +#define wxSplitterWindow_SetSplitMode 3440 +#define wxSplitterWindow_SplitHorizontally 3441 +#define wxSplitterWindow_SplitVertically 3442 +#define wxSplitterWindow_Unsplit 3443 +#define wxSplitterWindow_UpdateSize 3444 +#define wxSplitterEvent_GetSashPosition 3445 +#define wxSplitterEvent_GetX 3446 +#define wxSplitterEvent_GetY 3447 +#define wxSplitterEvent_GetWindowBeingRemoved 3448 +#define wxSplitterEvent_SetSashPosition 3449 +#define wxHtmlWindow_new_0 3450 +#define wxHtmlWindow_new_2 3451 +#define wxHtmlWindow_AppendToPage 3452 +#define wxHtmlWindow_GetOpenedAnchor 3453 +#define wxHtmlWindow_GetOpenedPage 3454 +#define wxHtmlWindow_GetOpenedPageTitle 3455 +#define wxHtmlWindow_GetRelatedFrame 3456 +#define wxHtmlWindow_HistoryBack 3457 +#define wxHtmlWindow_HistoryCanBack 3458 +#define wxHtmlWindow_HistoryCanForward 3459 +#define wxHtmlWindow_HistoryClear 3460 +#define wxHtmlWindow_HistoryForward 3461 +#define wxHtmlWindow_LoadFile 3462 +#define wxHtmlWindow_LoadPage 3463 +#define wxHtmlWindow_SelectAll 3464 +#define wxHtmlWindow_SelectionToText 3465 +#define wxHtmlWindow_SelectLine 3466 +#define wxHtmlWindow_SelectWord 3467 +#define wxHtmlWindow_SetBorders 3468 +#define wxHtmlWindow_SetFonts 3469 +#define wxHtmlWindow_SetPage 3470 +#define wxHtmlWindow_SetRelatedFrame 3471 +#define wxHtmlWindow_SetRelatedStatusBar 3472 +#define wxHtmlWindow_ToText 3473 +#define wxHtmlWindow_destroy 3474 +#define wxHtmlLinkEvent_GetLinkInfo 3475 +#define wxSystemSettings_GetColour 3476 +#define wxSystemSettings_GetFont 3477 +#define wxSystemSettings_GetMetric 3478 +#define wxSystemSettings_GetScreenType 3479 +#define wxAuiNotebookEvent_SetSelection 3480 +#define wxAuiNotebookEvent_GetSelection 3481 +#define wxAuiNotebookEvent_SetOldSelection 3482 +#define wxAuiNotebookEvent_GetOldSelection 3483 +#define wxAuiNotebookEvent_SetDragSource 3484 +#define wxAuiNotebookEvent_GetDragSource 3485 +#define wxAuiManagerEvent_SetManager 3486 +#define wxAuiManagerEvent_GetManager 3487 +#define wxAuiManagerEvent_SetPane 3488 +#define wxAuiManagerEvent_GetPane 3489 +#define wxAuiManagerEvent_SetButton 3490 +#define wxAuiManagerEvent_GetButton 3491 +#define wxAuiManagerEvent_SetDC 3492 +#define wxAuiManagerEvent_GetDC 3493 +#define wxAuiManagerEvent_Veto 3494 +#define wxAuiManagerEvent_GetVeto 3495 +#define wxAuiManagerEvent_SetCanVeto 3496 +#define wxAuiManagerEvent_CanVeto 3497 +#define wxLogNull_new 3498 +#define wxLogNull_destroy 3499 diff --git a/lib/wx/c_src/wxe_impl.cpp b/lib/wx/c_src/wxe_impl.cpp index 528a08e654..6d2926ce4e 100644 --- a/lib/wx/c_src/wxe_impl.cpp +++ b/lib/wx/c_src/wxe_impl.cpp @@ -411,7 +411,7 @@ void WxeApp::dispatch_cb(wxList * batch, wxList * temp, ErlDrvTermData process) if(event->caller == process || // Callbacks from CB process only event->op == WXE_CB_START || // Recursive event callback allow // Allow connect_cb during CB i.e. msg from wxe_server. - event->caller == memenv->owner) + (memenv && event->caller == memenv->owner)) { switch(event->op) { case WXE_BATCH_END: @@ -669,7 +669,7 @@ void WxeApp::clearPtr(void * ptr) { send_msg("debug", &msg); } - if(refd->pid != -1) { + if(((int) refd->pid) != -1) { // Send terminate pid to owner wxeReturn rt = wxeReturn(WXE_DRV_PORT,refd->memenv->owner, false); rt.addAtom("_wxe_destroy_"); diff --git a/lib/wx/src/gen/wxTreeCtrl.erl b/lib/wx/src/gen/wxTreeCtrl.erl index 4fcbb9366e..e3fe4c9612 100644 --- a/lib/wx/src/gen/wxTreeCtrl.erl +++ b/lib/wx/src/gen/wxTreeCtrl.erl @@ -35,7 +35,7 @@ -include("wxe.hrl"). -export([addRoot/2,addRoot/3,appendItem/3,appendItem/4,assignImageList/2,assignStateImageList/2, collapse/2,collapseAndReset/2,create/2,create/3,delete/2,deleteAllItems/1, - deleteChildren/2,destroy/1,ensureVisible/2,expand/2,getBoundingRect/3, + deleteChildren/2,destroy/1,editLabel/2,ensureVisible/2,expand/2,getBoundingRect/3, getBoundingRect/4,getChildrenCount/2,getChildrenCount/3,getCount/1, getEditControl/1,getFirstChild/2,getFirstVisibleItem/1,getImageList/1, getIndent/1,getItemBackgroundColour/2,getItemData/2,getItemFont/2, @@ -243,6 +243,14 @@ deleteChildren(#wx_ref{type=ThisT,ref=ThisRef},Item) wxe_util:cast(?wxTreeCtrl_DeleteChildren, <<ThisRef:32/?UI,0:32,Item:64/?UI>>). +%% @spec (This::wxTreeCtrl(), Item::integer()) -> wxTextCtrl:wxTextCtrl() +%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrleditlabel">external documentation</a>. +editLabel(#wx_ref{type=ThisT,ref=ThisRef},Item) + when is_integer(Item) -> + ?CLASS(ThisT,wxTreeCtrl), + wxe_util:call(?wxTreeCtrl_EditLabel, + <<ThisRef:32/?UI,0:32,Item:64/?UI>>). + %% @spec (This::wxTreeCtrl(), Item::integer()) -> ok %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlensurevisible">external documentation</a>. ensureVisible(#wx_ref{type=ThisT,ref=ThisRef},Item) diff --git a/lib/wx/src/gen/wxe_debug.hrl b/lib/wx/src/gen/wxe_debug.hrl index a3416b75c8..3edfa73599 100644 --- a/lib/wx/src/gen/wxe_debug.hrl +++ b/lib/wx/src/gen/wxe_debug.hrl @@ -1837,1445 +1837,1450 @@ wxdebug_table() -> {2007, {wxTreeCtrl, delete, 1}}, {2008, {wxTreeCtrl, deleteAllItems, 0}}, {2009, {wxTreeCtrl, deleteChildren, 1}}, - {2010, {wxTreeCtrl, ensureVisible, 1}}, - {2011, {wxTreeCtrl, expand, 1}}, - {2012, {wxTreeCtrl, getBoundingRect, 3}}, - {2014, {wxTreeCtrl, getChildrenCount, 2}}, - {2015, {wxTreeCtrl, getCount, 0}}, - {2016, {wxTreeCtrl, getEditControl, 0}}, - {2017, {wxTreeCtrl, getFirstChild, 2}}, - {2018, {wxTreeCtrl, getNextChild, 2}}, - {2019, {wxTreeCtrl, getFirstVisibleItem, 0}}, - {2020, {wxTreeCtrl, getImageList, 0}}, - {2021, {wxTreeCtrl, getIndent, 0}}, - {2022, {wxTreeCtrl, getItemBackgroundColour, 1}}, - {2023, {wxTreeCtrl, getItemData, 1}}, - {2024, {wxTreeCtrl, getItemFont, 1}}, - {2025, {wxTreeCtrl, getItemImage_1, 1}}, - {2026, {wxTreeCtrl, getItemImage_2, 2}}, - {2027, {wxTreeCtrl, getItemText, 1}}, - {2028, {wxTreeCtrl, getItemTextColour, 1}}, - {2029, {wxTreeCtrl, getLastChild, 1}}, - {2030, {wxTreeCtrl, getNextSibling, 1}}, - {2031, {wxTreeCtrl, getNextVisible, 1}}, - {2032, {wxTreeCtrl, getItemParent, 1}}, - {2033, {wxTreeCtrl, getPrevSibling, 1}}, - {2034, {wxTreeCtrl, getPrevVisible, 1}}, - {2035, {wxTreeCtrl, getRootItem, 0}}, - {2036, {wxTreeCtrl, getSelection, 0}}, - {2037, {wxTreeCtrl, getSelections, 1}}, - {2038, {wxTreeCtrl, getStateImageList, 0}}, - {2039, {wxTreeCtrl, hitTest, 1}}, - {2041, {wxTreeCtrl, insertItem, 4}}, - {2042, {wxTreeCtrl, isBold, 1}}, - {2043, {wxTreeCtrl, isExpanded, 1}}, - {2044, {wxTreeCtrl, isSelected, 1}}, - {2045, {wxTreeCtrl, isVisible, 1}}, - {2046, {wxTreeCtrl, itemHasChildren, 1}}, - {2047, {wxTreeCtrl, prependItem, 3}}, - {2048, {wxTreeCtrl, scrollTo, 1}}, - {2049, {wxTreeCtrl, selectItem_1, 1}}, - {2050, {wxTreeCtrl, selectItem_2, 2}}, - {2051, {wxTreeCtrl, setIndent, 1}}, - {2052, {wxTreeCtrl, setImageList, 1}}, - {2053, {wxTreeCtrl, setItemBackgroundColour, 2}}, - {2054, {wxTreeCtrl, setItemBold, 2}}, - {2055, {wxTreeCtrl, setItemData, 2}}, - {2056, {wxTreeCtrl, setItemDropHighlight, 2}}, - {2057, {wxTreeCtrl, setItemFont, 2}}, - {2058, {wxTreeCtrl, setItemHasChildren, 2}}, - {2059, {wxTreeCtrl, setItemImage_2, 2}}, - {2060, {wxTreeCtrl, setItemImage_3, 3}}, - {2061, {wxTreeCtrl, setItemText, 2}}, - {2062, {wxTreeCtrl, setItemTextColour, 2}}, - {2063, {wxTreeCtrl, setStateImageList, 1}}, - {2064, {wxTreeCtrl, setWindowStyle, 1}}, - {2065, {wxTreeCtrl, sortChildren, 1}}, - {2066, {wxTreeCtrl, toggle, 1}}, - {2067, {wxTreeCtrl, toggleItemSelection, 1}}, - {2068, {wxTreeCtrl, unselect, 0}}, - {2069, {wxTreeCtrl, unselectAll, 0}}, - {2070, {wxTreeCtrl, unselectItem, 1}}, - {2071, {wxScrollBar, new_0, 0}}, - {2072, {wxScrollBar, new_3, 3}}, - {2073, {wxScrollBar, destruct, 0}}, - {2074, {wxScrollBar, create, 3}}, - {2075, {wxScrollBar, getRange, 0}}, - {2076, {wxScrollBar, getPageSize, 0}}, - {2077, {wxScrollBar, getThumbPosition, 0}}, - {2078, {wxScrollBar, getThumbSize, 0}}, - {2079, {wxScrollBar, setThumbPosition, 1}}, - {2080, {wxScrollBar, setScrollbar, 5}}, - {2082, {wxSpinButton, new_2, 2}}, - {2083, {wxSpinButton, new_0, 0}}, - {2084, {wxSpinButton, create, 2}}, - {2085, {wxSpinButton, getMax, 0}}, - {2086, {wxSpinButton, getMin, 0}}, - {2087, {wxSpinButton, getValue, 0}}, - {2088, {wxSpinButton, setRange, 2}}, - {2089, {wxSpinButton, setValue, 1}}, - {2090, {wxSpinButton, 'Destroy', undefined}}, - {2091, {wxSpinCtrl, new_0, 0}}, - {2092, {wxSpinCtrl, new_2, 2}}, - {2094, {wxSpinCtrl, create, 2}}, - {2097, {wxSpinCtrl, setValue_1_1, 1}}, - {2098, {wxSpinCtrl, setValue_1_0, 1}}, - {2100, {wxSpinCtrl, getValue, 0}}, - {2102, {wxSpinCtrl, setRange, 2}}, - {2103, {wxSpinCtrl, setSelection, 2}}, - {2105, {wxSpinCtrl, getMin, 0}}, - {2107, {wxSpinCtrl, getMax, 0}}, - {2108, {wxSpinCtrl, 'Destroy', undefined}}, - {2109, {wxStaticText, new_0, 0}}, - {2110, {wxStaticText, new_4, 4}}, - {2111, {wxStaticText, create, 4}}, - {2112, {wxStaticText, getLabel, 0}}, - {2113, {wxStaticText, setLabel, 1}}, - {2114, {wxStaticText, wrap, 1}}, - {2115, {wxStaticText, 'Destroy', undefined}}, - {2116, {wxStaticBitmap, new_0, 0}}, - {2117, {wxStaticBitmap, new_4, 4}}, - {2118, {wxStaticBitmap, create, 4}}, - {2119, {wxStaticBitmap, getBitmap, 0}}, - {2120, {wxStaticBitmap, setBitmap, 1}}, - {2121, {wxStaticBitmap, 'Destroy', undefined}}, - {2122, {wxRadioBox, new, 7}}, - {2124, {wxRadioBox, destruct, 0}}, - {2125, {wxRadioBox, create, 7}}, - {2126, {wxRadioBox, enable_2, 2}}, - {2127, {wxRadioBox, enable_1, 1}}, - {2128, {wxRadioBox, getSelection, 0}}, - {2129, {wxRadioBox, getString, 1}}, - {2130, {wxRadioBox, setSelection, 1}}, - {2131, {wxRadioBox, show_2, 2}}, - {2132, {wxRadioBox, show_1, 1}}, - {2133, {wxRadioBox, getColumnCount, 0}}, - {2134, {wxRadioBox, getItemHelpText, 1}}, - {2135, {wxRadioBox, getItemToolTip, 1}}, - {2137, {wxRadioBox, getItemFromPoint, 1}}, - {2138, {wxRadioBox, getRowCount, 0}}, - {2139, {wxRadioBox, isItemEnabled, 1}}, - {2140, {wxRadioBox, isItemShown, 1}}, - {2141, {wxRadioBox, setItemHelpText, 2}}, - {2142, {wxRadioBox, setItemToolTip, 2}}, - {2143, {wxRadioButton, new_0, 0}}, - {2144, {wxRadioButton, new_4, 4}}, - {2145, {wxRadioButton, create, 4}}, - {2146, {wxRadioButton, getValue, 0}}, - {2147, {wxRadioButton, setValue, 1}}, - {2148, {wxRadioButton, 'Destroy', undefined}}, - {2150, {wxSlider, new_6, 6}}, - {2151, {wxSlider, new_0, 0}}, - {2152, {wxSlider, create, 6}}, - {2153, {wxSlider, getLineSize, 0}}, - {2154, {wxSlider, getMax, 0}}, - {2155, {wxSlider, getMin, 0}}, - {2156, {wxSlider, getPageSize, 0}}, - {2157, {wxSlider, getThumbLength, 0}}, - {2158, {wxSlider, getValue, 0}}, - {2159, {wxSlider, setLineSize, 1}}, - {2160, {wxSlider, setPageSize, 1}}, - {2161, {wxSlider, setRange, 2}}, - {2162, {wxSlider, setThumbLength, 1}}, - {2163, {wxSlider, setValue, 1}}, - {2164, {wxSlider, 'Destroy', undefined}}, - {2166, {wxDialog, new_4, 4}}, - {2167, {wxDialog, new_0, 0}}, - {2169, {wxDialog, destruct, 0}}, - {2170, {wxDialog, create, 4}}, - {2171, {wxDialog, createButtonSizer, 1}}, - {2172, {wxDialog, createStdDialogButtonSizer, 1}}, - {2173, {wxDialog, endModal, 1}}, - {2174, {wxDialog, getAffirmativeId, 0}}, - {2175, {wxDialog, getReturnCode, 0}}, - {2176, {wxDialog, isModal, 0}}, - {2177, {wxDialog, setAffirmativeId, 1}}, - {2178, {wxDialog, setReturnCode, 1}}, - {2179, {wxDialog, show, 1}}, - {2180, {wxDialog, showModal, 0}}, - {2181, {wxColourDialog, new_0, 0}}, - {2182, {wxColourDialog, new_2, 2}}, - {2183, {wxColourDialog, destruct, 0}}, - {2184, {wxColourDialog, create, 2}}, - {2185, {wxColourDialog, getColourData, 0}}, - {2186, {wxColourData, new_0, 0}}, - {2187, {wxColourData, new_1, 1}}, - {2188, {wxColourData, destruct, 0}}, - {2189, {wxColourData, getChooseFull, 0}}, - {2190, {wxColourData, getColour, 0}}, - {2192, {wxColourData, getCustomColour, 1}}, - {2193, {wxColourData, setChooseFull, 1}}, - {2194, {wxColourData, setColour, 1}}, - {2195, {wxColourData, setCustomColour, 2}}, - {2196, {wxPalette, new_0, 0}}, - {2197, {wxPalette, new_4, 4}}, - {2199, {wxPalette, destruct, 0}}, - {2200, {wxPalette, create, 4}}, - {2201, {wxPalette, getColoursCount, 0}}, - {2202, {wxPalette, getPixel, 3}}, - {2203, {wxPalette, getRGB, 4}}, - {2204, {wxPalette, isOk, 0}}, - {2208, {wxDirDialog, new, 2}}, - {2209, {wxDirDialog, destruct, 0}}, - {2210, {wxDirDialog, getPath, 0}}, - {2211, {wxDirDialog, getMessage, 0}}, - {2212, {wxDirDialog, setMessage, 1}}, - {2213, {wxDirDialog, setPath, 1}}, - {2217, {wxFileDialog, new, 2}}, - {2218, {wxFileDialog, destruct, 0}}, - {2219, {wxFileDialog, getDirectory, 0}}, - {2220, {wxFileDialog, getFilename, 0}}, - {2221, {wxFileDialog, getFilenames, 1}}, - {2222, {wxFileDialog, getFilterIndex, 0}}, - {2223, {wxFileDialog, getMessage, 0}}, - {2224, {wxFileDialog, getPath, 0}}, - {2225, {wxFileDialog, getPaths, 1}}, - {2226, {wxFileDialog, getWildcard, 0}}, - {2227, {wxFileDialog, setDirectory, 1}}, - {2228, {wxFileDialog, setFilename, 1}}, - {2229, {wxFileDialog, setFilterIndex, 1}}, - {2230, {wxFileDialog, setMessage, 1}}, - {2231, {wxFileDialog, setPath, 1}}, - {2232, {wxFileDialog, setWildcard, 1}}, - {2233, {wxPickerBase, setInternalMargin, 1}}, - {2234, {wxPickerBase, getInternalMargin, 0}}, - {2235, {wxPickerBase, setTextCtrlProportion, 1}}, - {2236, {wxPickerBase, setPickerCtrlProportion, 1}}, - {2237, {wxPickerBase, getTextCtrlProportion, 0}}, - {2238, {wxPickerBase, getPickerCtrlProportion, 0}}, - {2239, {wxPickerBase, hasTextCtrl, 0}}, - {2240, {wxPickerBase, getTextCtrl, 0}}, - {2241, {wxPickerBase, isTextCtrlGrowable, 0}}, - {2242, {wxPickerBase, setPickerCtrlGrowable, 1}}, - {2243, {wxPickerBase, setTextCtrlGrowable, 1}}, - {2244, {wxPickerBase, isPickerCtrlGrowable, 0}}, - {2245, {wxFilePickerCtrl, new_0, 0}}, - {2246, {wxFilePickerCtrl, new_3, 3}}, - {2247, {wxFilePickerCtrl, create, 3}}, - {2248, {wxFilePickerCtrl, getPath, 0}}, - {2249, {wxFilePickerCtrl, setPath, 1}}, - {2250, {wxFilePickerCtrl, 'Destroy', undefined}}, - {2251, {wxDirPickerCtrl, new_0, 0}}, - {2252, {wxDirPickerCtrl, new_3, 3}}, - {2253, {wxDirPickerCtrl, create, 3}}, - {2254, {wxDirPickerCtrl, getPath, 0}}, - {2255, {wxDirPickerCtrl, setPath, 1}}, - {2256, {wxDirPickerCtrl, 'Destroy', undefined}}, - {2257, {wxColourPickerCtrl, new_0, 0}}, - {2258, {wxColourPickerCtrl, new_3, 3}}, - {2259, {wxColourPickerCtrl, create, 3}}, - {2260, {wxColourPickerCtrl, getColour, 0}}, - {2261, {wxColourPickerCtrl, setColour_1_1, 1}}, - {2262, {wxColourPickerCtrl, setColour_1_0, 1}}, - {2263, {wxColourPickerCtrl, 'Destroy', undefined}}, - {2264, {wxDatePickerCtrl, new_0, 0}}, - {2265, {wxDatePickerCtrl, new_3, 3}}, - {2266, {wxDatePickerCtrl, getRange, 2}}, - {2267, {wxDatePickerCtrl, getValue, 0}}, - {2268, {wxDatePickerCtrl, setRange, 2}}, - {2269, {wxDatePickerCtrl, setValue, 1}}, - {2270, {wxDatePickerCtrl, 'Destroy', undefined}}, - {2271, {wxFontPickerCtrl, new_0, 0}}, - {2272, {wxFontPickerCtrl, new_3, 3}}, - {2273, {wxFontPickerCtrl, create, 3}}, - {2274, {wxFontPickerCtrl, getSelectedFont, 0}}, - {2275, {wxFontPickerCtrl, setSelectedFont, 1}}, - {2276, {wxFontPickerCtrl, getMaxPointSize, 0}}, - {2277, {wxFontPickerCtrl, setMaxPointSize, 1}}, - {2278, {wxFontPickerCtrl, 'Destroy', undefined}}, - {2281, {wxFindReplaceDialog, new_0, 0}}, - {2282, {wxFindReplaceDialog, new_4, 4}}, - {2283, {wxFindReplaceDialog, destruct, 0}}, - {2284, {wxFindReplaceDialog, create, 4}}, - {2285, {wxFindReplaceDialog, getData, 0}}, - {2286, {wxFindReplaceData, new_0, 0}}, - {2287, {wxFindReplaceData, new_1, 1}}, - {2288, {wxFindReplaceData, getFindString, 0}}, - {2289, {wxFindReplaceData, getReplaceString, 0}}, - {2290, {wxFindReplaceData, getFlags, 0}}, - {2291, {wxFindReplaceData, setFlags, 1}}, - {2292, {wxFindReplaceData, setFindString, 1}}, - {2293, {wxFindReplaceData, setReplaceString, 1}}, - {2294, {wxFindReplaceData, 'Destroy', undefined}}, - {2295, {wxMultiChoiceDialog, new_0, 0}}, - {2297, {wxMultiChoiceDialog, new_5, 5}}, - {2298, {wxMultiChoiceDialog, getSelections, 0}}, - {2299, {wxMultiChoiceDialog, setSelections, 1}}, - {2300, {wxMultiChoiceDialog, 'Destroy', undefined}}, - {2301, {wxSingleChoiceDialog, new_0, 0}}, - {2303, {wxSingleChoiceDialog, new_5, 5}}, - {2304, {wxSingleChoiceDialog, getSelection, 0}}, - {2305, {wxSingleChoiceDialog, getStringSelection, 0}}, - {2306, {wxSingleChoiceDialog, setSelection, 1}}, - {2307, {wxSingleChoiceDialog, 'Destroy', undefined}}, - {2308, {wxTextEntryDialog, new, 3}}, - {2309, {wxTextEntryDialog, getValue, 0}}, - {2310, {wxTextEntryDialog, setValue, 1}}, - {2311, {wxTextEntryDialog, 'Destroy', undefined}}, - {2312, {wxPasswordEntryDialog, new, 3}}, - {2313, {wxPasswordEntryDialog, 'Destroy', undefined}}, - {2314, {wxFontData, new_0, 0}}, - {2315, {wxFontData, new_1, 1}}, - {2316, {wxFontData, destruct, 0}}, - {2317, {wxFontData, enableEffects, 1}}, - {2318, {wxFontData, getAllowSymbols, 0}}, - {2319, {wxFontData, getColour, 0}}, - {2320, {wxFontData, getChosenFont, 0}}, - {2321, {wxFontData, getEnableEffects, 0}}, - {2322, {wxFontData, getInitialFont, 0}}, - {2323, {wxFontData, getShowHelp, 0}}, - {2324, {wxFontData, setAllowSymbols, 1}}, - {2325, {wxFontData, setChosenFont, 1}}, - {2326, {wxFontData, setColour, 1}}, - {2327, {wxFontData, setInitialFont, 1}}, - {2328, {wxFontData, setRange, 2}}, - {2329, {wxFontData, setShowHelp, 1}}, - {2333, {wxFontDialog, new_0, 0}}, - {2335, {wxFontDialog, new_2, 2}}, - {2337, {wxFontDialog, create, 2}}, - {2338, {wxFontDialog, getFontData, 0}}, - {2340, {wxFontDialog, 'Destroy', undefined}}, - {2341, {wxProgressDialog, new, 3}}, - {2342, {wxProgressDialog, destruct, 0}}, - {2343, {wxProgressDialog, resume, 0}}, - {2344, {wxProgressDialog, update_2, 2}}, - {2345, {wxProgressDialog, update_0, 0}}, - {2346, {wxMessageDialog, new, 3}}, - {2347, {wxMessageDialog, destruct, 0}}, - {2348, {wxPageSetupDialog, new, 2}}, - {2349, {wxPageSetupDialog, destruct, 0}}, - {2350, {wxPageSetupDialog, getPageSetupData, 0}}, - {2351, {wxPageSetupDialog, showModal, 0}}, - {2352, {wxPageSetupDialogData, new_0, 0}}, - {2353, {wxPageSetupDialogData, new_1_0, 1}}, - {2354, {wxPageSetupDialogData, new_1_1, 1}}, - {2355, {wxPageSetupDialogData, destruct, 0}}, - {2356, {wxPageSetupDialogData, enableHelp, 1}}, - {2357, {wxPageSetupDialogData, enableMargins, 1}}, - {2358, {wxPageSetupDialogData, enableOrientation, 1}}, - {2359, {wxPageSetupDialogData, enablePaper, 1}}, - {2360, {wxPageSetupDialogData, enablePrinter, 1}}, - {2361, {wxPageSetupDialogData, getDefaultMinMargins, 0}}, - {2362, {wxPageSetupDialogData, getEnableMargins, 0}}, - {2363, {wxPageSetupDialogData, getEnableOrientation, 0}}, - {2364, {wxPageSetupDialogData, getEnablePaper, 0}}, - {2365, {wxPageSetupDialogData, getEnablePrinter, 0}}, - {2366, {wxPageSetupDialogData, getEnableHelp, 0}}, - {2367, {wxPageSetupDialogData, getDefaultInfo, 0}}, - {2368, {wxPageSetupDialogData, getMarginTopLeft, 0}}, - {2369, {wxPageSetupDialogData, getMarginBottomRight, 0}}, - {2370, {wxPageSetupDialogData, getMinMarginTopLeft, 0}}, - {2371, {wxPageSetupDialogData, getMinMarginBottomRight, 0}}, - {2372, {wxPageSetupDialogData, getPaperId, 0}}, - {2373, {wxPageSetupDialogData, getPaperSize, 0}}, - {2375, {wxPageSetupDialogData, getPrintData, 0}}, - {2376, {wxPageSetupDialogData, isOk, 0}}, - {2377, {wxPageSetupDialogData, setDefaultInfo, 1}}, - {2378, {wxPageSetupDialogData, setDefaultMinMargins, 1}}, - {2379, {wxPageSetupDialogData, setMarginTopLeft, 1}}, - {2380, {wxPageSetupDialogData, setMarginBottomRight, 1}}, - {2381, {wxPageSetupDialogData, setMinMarginTopLeft, 1}}, - {2382, {wxPageSetupDialogData, setMinMarginBottomRight, 1}}, - {2383, {wxPageSetupDialogData, setPaperId, 1}}, - {2384, {wxPageSetupDialogData, setPaperSize_1_1, 1}}, - {2385, {wxPageSetupDialogData, setPaperSize_1_0, 1}}, - {2386, {wxPageSetupDialogData, setPrintData, 1}}, - {2387, {wxPrintDialog, new_2_0, 2}}, - {2388, {wxPrintDialog, new_2_1, 2}}, - {2389, {wxPrintDialog, destruct, 0}}, - {2390, {wxPrintDialog, getPrintDialogData, 0}}, - {2391, {wxPrintDialog, getPrintDC, 0}}, - {2392, {wxPrintDialogData, new_0, 0}}, - {2393, {wxPrintDialogData, new_1_1, 1}}, - {2394, {wxPrintDialogData, new_1_0, 1}}, - {2395, {wxPrintDialogData, destruct, 0}}, - {2396, {wxPrintDialogData, enableHelp, 1}}, - {2397, {wxPrintDialogData, enablePageNumbers, 1}}, - {2398, {wxPrintDialogData, enablePrintToFile, 1}}, - {2399, {wxPrintDialogData, enableSelection, 1}}, - {2400, {wxPrintDialogData, getAllPages, 0}}, - {2401, {wxPrintDialogData, getCollate, 0}}, - {2402, {wxPrintDialogData, getFromPage, 0}}, - {2403, {wxPrintDialogData, getMaxPage, 0}}, - {2404, {wxPrintDialogData, getMinPage, 0}}, - {2405, {wxPrintDialogData, getNoCopies, 0}}, - {2406, {wxPrintDialogData, getPrintData, 0}}, - {2407, {wxPrintDialogData, getPrintToFile, 0}}, - {2408, {wxPrintDialogData, getSelection, 0}}, - {2409, {wxPrintDialogData, getToPage, 0}}, - {2410, {wxPrintDialogData, isOk, 0}}, - {2411, {wxPrintDialogData, setCollate, 1}}, - {2412, {wxPrintDialogData, setFromPage, 1}}, - {2413, {wxPrintDialogData, setMaxPage, 1}}, - {2414, {wxPrintDialogData, setMinPage, 1}}, - {2415, {wxPrintDialogData, setNoCopies, 1}}, - {2416, {wxPrintDialogData, setPrintData, 1}}, - {2417, {wxPrintDialogData, setPrintToFile, 1}}, - {2418, {wxPrintDialogData, setSelection, 1}}, - {2419, {wxPrintDialogData, setToPage, 1}}, - {2420, {wxPrintData, new_0, 0}}, - {2421, {wxPrintData, new_1, 1}}, - {2422, {wxPrintData, destruct, 0}}, - {2423, {wxPrintData, getCollate, 0}}, - {2424, {wxPrintData, getBin, 0}}, - {2425, {wxPrintData, getColour, 0}}, - {2426, {wxPrintData, getDuplex, 0}}, - {2427, {wxPrintData, getNoCopies, 0}}, - {2428, {wxPrintData, getOrientation, 0}}, - {2429, {wxPrintData, getPaperId, 0}}, - {2430, {wxPrintData, getPrinterName, 0}}, - {2431, {wxPrintData, getQuality, 0}}, - {2432, {wxPrintData, isOk, 0}}, - {2433, {wxPrintData, setBin, 1}}, - {2434, {wxPrintData, setCollate, 1}}, - {2435, {wxPrintData, setColour, 1}}, - {2436, {wxPrintData, setDuplex, 1}}, - {2437, {wxPrintData, setNoCopies, 1}}, - {2438, {wxPrintData, setOrientation, 1}}, - {2439, {wxPrintData, setPaperId, 1}}, - {2440, {wxPrintData, setPrinterName, 1}}, - {2441, {wxPrintData, setQuality, 1}}, - {2444, {wxPrintPreview, new_2, 2}}, - {2445, {wxPrintPreview, new_3, 3}}, - {2447, {wxPrintPreview, destruct, 0}}, - {2448, {wxPrintPreview, getCanvas, 0}}, - {2449, {wxPrintPreview, getCurrentPage, 0}}, - {2450, {wxPrintPreview, getFrame, 0}}, - {2451, {wxPrintPreview, getMaxPage, 0}}, - {2452, {wxPrintPreview, getMinPage, 0}}, - {2453, {wxPrintPreview, getPrintout, 0}}, - {2454, {wxPrintPreview, getPrintoutForPrinting, 0}}, - {2455, {wxPrintPreview, isOk, 0}}, - {2456, {wxPrintPreview, paintPage, 2}}, - {2457, {wxPrintPreview, print, 1}}, - {2458, {wxPrintPreview, renderPage, 1}}, - {2459, {wxPrintPreview, setCanvas, 1}}, - {2460, {wxPrintPreview, setCurrentPage, 1}}, - {2461, {wxPrintPreview, setFrame, 1}}, - {2462, {wxPrintPreview, setPrintout, 1}}, - {2463, {wxPrintPreview, setZoom, 1}}, - {2464, {wxPreviewFrame, new, 3}}, - {2465, {wxPreviewFrame, destruct, 0}}, - {2466, {wxPreviewFrame, createControlBar, 0}}, - {2467, {wxPreviewFrame, createCanvas, 0}}, - {2468, {wxPreviewFrame, initialize, 0}}, - {2469, {wxPreviewFrame, onCloseWindow, 1}}, - {2470, {wxPreviewControlBar, new, 4}}, - {2471, {wxPreviewControlBar, destruct, 0}}, - {2472, {wxPreviewControlBar, createButtons, 0}}, - {2473, {wxPreviewControlBar, getPrintPreview, 0}}, - {2474, {wxPreviewControlBar, getZoomControl, 0}}, - {2475, {wxPreviewControlBar, setZoomControl, 1}}, - {2477, {wxPrinter, new, 1}}, - {2478, {wxPrinter, createAbortWindow, 2}}, - {2479, {wxPrinter, getAbort, 0}}, - {2480, {wxPrinter, getLastError, 0}}, - {2481, {wxPrinter, getPrintDialogData, 0}}, - {2482, {wxPrinter, print, 3}}, - {2483, {wxPrinter, printDialog, 1}}, - {2484, {wxPrinter, reportError, 3}}, - {2485, {wxPrinter, setup, 1}}, - {2486, {wxPrinter, 'Destroy', undefined}}, - {2487, {wxXmlResource, new_1, 1}}, - {2488, {wxXmlResource, new_2, 2}}, - {2489, {wxXmlResource, destruct, 0}}, - {2490, {wxXmlResource, attachUnknownControl, 3}}, - {2491, {wxXmlResource, clearHandlers, 0}}, - {2492, {wxXmlResource, compareVersion, 4}}, - {2493, {wxXmlResource, get, 0}}, - {2494, {wxXmlResource, getFlags, 0}}, - {2495, {wxXmlResource, getVersion, 0}}, - {2496, {wxXmlResource, getXRCID, 2}}, - {2497, {wxXmlResource, initAllHandlers, 0}}, - {2498, {wxXmlResource, load, 1}}, - {2499, {wxXmlResource, loadBitmap, 1}}, - {2500, {wxXmlResource, loadDialog_2, 2}}, - {2501, {wxXmlResource, loadDialog_3, 3}}, - {2502, {wxXmlResource, loadFrame_2, 2}}, - {2503, {wxXmlResource, loadFrame_3, 3}}, - {2504, {wxXmlResource, loadIcon, 1}}, - {2505, {wxXmlResource, loadMenu, 1}}, - {2506, {wxXmlResource, loadMenuBar_2, 2}}, - {2507, {wxXmlResource, loadMenuBar_1, 1}}, - {2508, {wxXmlResource, loadPanel_2, 2}}, - {2509, {wxXmlResource, loadPanel_3, 3}}, - {2510, {wxXmlResource, loadToolBar, 2}}, - {2511, {wxXmlResource, set, 1}}, - {2512, {wxXmlResource, setFlags, 1}}, - {2513, {wxXmlResource, unload, 1}}, - {2514, {wxXmlResource, xrcctrl, 3}}, - {2515, {wxHtmlEasyPrinting, new, 1}}, - {2516, {wxHtmlEasyPrinting, destruct, 0}}, - {2517, {wxHtmlEasyPrinting, getPrintData, 0}}, - {2518, {wxHtmlEasyPrinting, getPageSetupData, 0}}, - {2519, {wxHtmlEasyPrinting, previewFile, 1}}, - {2520, {wxHtmlEasyPrinting, previewText, 2}}, - {2521, {wxHtmlEasyPrinting, printFile, 1}}, - {2522, {wxHtmlEasyPrinting, printText, 2}}, - {2523, {wxHtmlEasyPrinting, pageSetup, 0}}, - {2524, {wxHtmlEasyPrinting, setFonts, 3}}, - {2525, {wxHtmlEasyPrinting, setHeader, 2}}, - {2526, {wxHtmlEasyPrinting, setFooter, 2}}, - {2528, {wxGLCanvas, new_2, 2}}, - {2529, {wxGLCanvas, new_3_1, 3}}, - {2530, {wxGLCanvas, new_3_0, 3}}, - {2531, {wxGLCanvas, getContext, 0}}, - {2533, {wxGLCanvas, setCurrent, 0}}, - {2534, {wxGLCanvas, swapBuffers, 0}}, - {2535, {wxGLCanvas, 'Destroy', undefined}}, - {2536, {wxAuiManager, new, 1}}, - {2537, {wxAuiManager, destruct, 0}}, - {2538, {wxAuiManager, addPane_2_1, 2}}, - {2539, {wxAuiManager, addPane_3, 3}}, - {2540, {wxAuiManager, addPane_2_0, 2}}, - {2541, {wxAuiManager, detachPane, 1}}, - {2542, {wxAuiManager, getAllPanes, 0}}, - {2543, {wxAuiManager, getArtProvider, 0}}, - {2544, {wxAuiManager, getDockSizeConstraint, 2}}, - {2545, {wxAuiManager, getFlags, 0}}, - {2546, {wxAuiManager, getManagedWindow, 0}}, - {2547, {wxAuiManager, getManager, 1}}, - {2548, {wxAuiManager, getPane_1_1, 1}}, - {2549, {wxAuiManager, getPane_1_0, 1}}, - {2550, {wxAuiManager, hideHint, 0}}, - {2551, {wxAuiManager, insertPane, 3}}, - {2552, {wxAuiManager, loadPaneInfo, 2}}, - {2553, {wxAuiManager, loadPerspective, 2}}, - {2554, {wxAuiManager, savePaneInfo, 1}}, - {2555, {wxAuiManager, savePerspective, 0}}, - {2556, {wxAuiManager, setArtProvider, 1}}, - {2557, {wxAuiManager, setDockSizeConstraint, 2}}, - {2558, {wxAuiManager, setFlags, 1}}, - {2559, {wxAuiManager, setManagedWindow, 1}}, - {2560, {wxAuiManager, showHint, 1}}, - {2561, {wxAuiManager, unInit, 0}}, - {2562, {wxAuiManager, update, 0}}, - {2563, {wxAuiPaneInfo, new_0, 0}}, - {2564, {wxAuiPaneInfo, new_1, 1}}, - {2565, {wxAuiPaneInfo, destruct, 0}}, - {2566, {wxAuiPaneInfo, bestSize_1, 1}}, - {2567, {wxAuiPaneInfo, bestSize_2, 2}}, - {2568, {wxAuiPaneInfo, bottom, 0}}, - {2569, {wxAuiPaneInfo, bottomDockable, 1}}, - {2570, {wxAuiPaneInfo, caption, 1}}, - {2571, {wxAuiPaneInfo, captionVisible, 1}}, - {2572, {wxAuiPaneInfo, centre, 0}}, - {2573, {wxAuiPaneInfo, centrePane, 0}}, - {2574, {wxAuiPaneInfo, closeButton, 1}}, - {2575, {wxAuiPaneInfo, defaultPane, 0}}, - {2576, {wxAuiPaneInfo, destroyOnClose, 1}}, - {2577, {wxAuiPaneInfo, direction, 1}}, - {2578, {wxAuiPaneInfo, dock, 0}}, - {2579, {wxAuiPaneInfo, dockable, 1}}, - {2580, {wxAuiPaneInfo, fixed, 0}}, - {2581, {wxAuiPaneInfo, float, 0}}, - {2582, {wxAuiPaneInfo, floatable, 1}}, - {2583, {wxAuiPaneInfo, floatingPosition_1, 1}}, - {2584, {wxAuiPaneInfo, floatingPosition_2, 2}}, - {2585, {wxAuiPaneInfo, floatingSize_1, 1}}, - {2586, {wxAuiPaneInfo, floatingSize_2, 2}}, - {2587, {wxAuiPaneInfo, gripper, 1}}, - {2588, {wxAuiPaneInfo, gripperTop, 1}}, - {2589, {wxAuiPaneInfo, hasBorder, 0}}, - {2590, {wxAuiPaneInfo, hasCaption, 0}}, - {2591, {wxAuiPaneInfo, hasCloseButton, 0}}, - {2592, {wxAuiPaneInfo, hasFlag, 1}}, - {2593, {wxAuiPaneInfo, hasGripper, 0}}, - {2594, {wxAuiPaneInfo, hasGripperTop, 0}}, - {2595, {wxAuiPaneInfo, hasMaximizeButton, 0}}, - {2596, {wxAuiPaneInfo, hasMinimizeButton, 0}}, - {2597, {wxAuiPaneInfo, hasPinButton, 0}}, - {2598, {wxAuiPaneInfo, hide, 0}}, - {2599, {wxAuiPaneInfo, isBottomDockable, 0}}, - {2600, {wxAuiPaneInfo, isDocked, 0}}, - {2601, {wxAuiPaneInfo, isFixed, 0}}, - {2602, {wxAuiPaneInfo, isFloatable, 0}}, - {2603, {wxAuiPaneInfo, isFloating, 0}}, - {2604, {wxAuiPaneInfo, isLeftDockable, 0}}, - {2605, {wxAuiPaneInfo, isMovable, 0}}, - {2606, {wxAuiPaneInfo, isOk, 0}}, - {2607, {wxAuiPaneInfo, isResizable, 0}}, - {2608, {wxAuiPaneInfo, isRightDockable, 0}}, - {2609, {wxAuiPaneInfo, isShown, 0}}, - {2610, {wxAuiPaneInfo, isToolbar, 0}}, - {2611, {wxAuiPaneInfo, isTopDockable, 0}}, - {2612, {wxAuiPaneInfo, layer, 1}}, - {2613, {wxAuiPaneInfo, left, 0}}, - {2614, {wxAuiPaneInfo, leftDockable, 1}}, - {2615, {wxAuiPaneInfo, maxSize_1, 1}}, - {2616, {wxAuiPaneInfo, maxSize_2, 2}}, - {2617, {wxAuiPaneInfo, maximizeButton, 1}}, - {2618, {wxAuiPaneInfo, minSize_1, 1}}, - {2619, {wxAuiPaneInfo, minSize_2, 2}}, - {2620, {wxAuiPaneInfo, minimizeButton, 1}}, - {2621, {wxAuiPaneInfo, movable, 1}}, - {2622, {wxAuiPaneInfo, name, 1}}, - {2623, {wxAuiPaneInfo, paneBorder, 1}}, - {2624, {wxAuiPaneInfo, pinButton, 1}}, - {2625, {wxAuiPaneInfo, position, 1}}, - {2626, {wxAuiPaneInfo, resizable, 1}}, - {2627, {wxAuiPaneInfo, right, 0}}, - {2628, {wxAuiPaneInfo, rightDockable, 1}}, - {2629, {wxAuiPaneInfo, row, 1}}, - {2630, {wxAuiPaneInfo, safeSet, 1}}, - {2631, {wxAuiPaneInfo, setFlag, 2}}, - {2632, {wxAuiPaneInfo, show, 1}}, - {2633, {wxAuiPaneInfo, toolbarPane, 0}}, - {2634, {wxAuiPaneInfo, top, 0}}, - {2635, {wxAuiPaneInfo, topDockable, 1}}, - {2636, {wxAuiPaneInfo, window, 1}}, - {2637, {wxAuiNotebook, new_0, 0}}, - {2638, {wxAuiNotebook, new_2, 2}}, - {2639, {wxAuiNotebook, addPage, 3}}, - {2640, {wxAuiNotebook, create, 2}}, - {2641, {wxAuiNotebook, deletePage, 1}}, - {2642, {wxAuiNotebook, getArtProvider, 0}}, - {2643, {wxAuiNotebook, getPage, 1}}, - {2644, {wxAuiNotebook, getPageBitmap, 1}}, - {2645, {wxAuiNotebook, getPageCount, 0}}, - {2646, {wxAuiNotebook, getPageIndex, 1}}, - {2647, {wxAuiNotebook, getPageText, 1}}, - {2648, {wxAuiNotebook, getSelection, 0}}, - {2649, {wxAuiNotebook, insertPage, 4}}, - {2650, {wxAuiNotebook, removePage, 1}}, - {2651, {wxAuiNotebook, setArtProvider, 1}}, - {2652, {wxAuiNotebook, setFont, 1}}, - {2653, {wxAuiNotebook, setPageBitmap, 2}}, - {2654, {wxAuiNotebook, setPageText, 2}}, - {2655, {wxAuiNotebook, setSelection, 1}}, - {2656, {wxAuiNotebook, setTabCtrlHeight, 1}}, - {2657, {wxAuiNotebook, setUniformBitmapSize, 1}}, - {2658, {wxAuiNotebook, 'Destroy', undefined}}, - {2659, {wxMDIParentFrame, new_0, 0}}, - {2660, {wxMDIParentFrame, new_4, 4}}, - {2661, {wxMDIParentFrame, destruct, 0}}, - {2662, {wxMDIParentFrame, activateNext, 0}}, - {2663, {wxMDIParentFrame, activatePrevious, 0}}, - {2664, {wxMDIParentFrame, arrangeIcons, 0}}, - {2665, {wxMDIParentFrame, cascade, 0}}, - {2666, {wxMDIParentFrame, create, 4}}, - {2667, {wxMDIParentFrame, getActiveChild, 0}}, - {2668, {wxMDIParentFrame, getClientWindow, 0}}, - {2669, {wxMDIParentFrame, tile, 1}}, - {2670, {wxMDIChildFrame, new_0, 0}}, - {2671, {wxMDIChildFrame, new_4, 4}}, - {2672, {wxMDIChildFrame, destruct, 0}}, - {2673, {wxMDIChildFrame, activate, 0}}, - {2674, {wxMDIChildFrame, create, 4}}, - {2675, {wxMDIChildFrame, maximize, 1}}, - {2676, {wxMDIChildFrame, restore, 0}}, - {2677, {wxMDIClientWindow, new_0, 0}}, - {2678, {wxMDIClientWindow, new_2, 2}}, - {2679, {wxMDIClientWindow, destruct, 0}}, - {2680, {wxMDIClientWindow, createClient, 2}}, - {2681, {wxLayoutAlgorithm, new, 0}}, - {2682, {wxLayoutAlgorithm, layoutFrame, 2}}, - {2683, {wxLayoutAlgorithm, layoutMDIFrame, 2}}, - {2684, {wxLayoutAlgorithm, layoutWindow, 2}}, - {2685, {wxLayoutAlgorithm, 'Destroy', undefined}}, - {2686, {wxEvent, getId, 0}}, - {2687, {wxEvent, getSkipped, 0}}, - {2688, {wxEvent, getTimestamp, 0}}, - {2689, {wxEvent, isCommandEvent, 0}}, - {2690, {wxEvent, resumePropagation, 1}}, - {2691, {wxEvent, shouldPropagate, 0}}, - {2692, {wxEvent, skip, 1}}, - {2693, {wxEvent, stopPropagation, 0}}, - {2694, {wxCommandEvent, getClientData, 0}}, - {2695, {wxCommandEvent, getExtraLong, 0}}, - {2696, {wxCommandEvent, getInt, 0}}, - {2697, {wxCommandEvent, getSelection, 0}}, - {2698, {wxCommandEvent, getString, 0}}, - {2699, {wxCommandEvent, isChecked, 0}}, - {2700, {wxCommandEvent, isSelection, 0}}, - {2701, {wxCommandEvent, setInt, 1}}, - {2702, {wxCommandEvent, setString, 1}}, - {2703, {wxScrollEvent, getOrientation, 0}}, - {2704, {wxScrollEvent, getPosition, 0}}, - {2705, {wxScrollWinEvent, getOrientation, 0}}, - {2706, {wxScrollWinEvent, getPosition, 0}}, - {2707, {wxMouseEvent, altDown, 0}}, - {2708, {wxMouseEvent, button, 1}}, - {2709, {wxMouseEvent, buttonDClick, 1}}, - {2710, {wxMouseEvent, buttonDown, 1}}, - {2711, {wxMouseEvent, buttonUp, 1}}, - {2712, {wxMouseEvent, cmdDown, 0}}, - {2713, {wxMouseEvent, controlDown, 0}}, - {2714, {wxMouseEvent, dragging, 0}}, - {2715, {wxMouseEvent, entering, 0}}, - {2716, {wxMouseEvent, getButton, 0}}, - {2719, {wxMouseEvent, getPosition, 0}}, - {2720, {wxMouseEvent, getLogicalPosition, 1}}, - {2721, {wxMouseEvent, getLinesPerAction, 0}}, - {2722, {wxMouseEvent, getWheelRotation, 0}}, - {2723, {wxMouseEvent, getWheelDelta, 0}}, - {2724, {wxMouseEvent, getX, 0}}, - {2725, {wxMouseEvent, getY, 0}}, - {2726, {wxMouseEvent, isButton, 0}}, - {2727, {wxMouseEvent, isPageScroll, 0}}, - {2728, {wxMouseEvent, leaving, 0}}, - {2729, {wxMouseEvent, leftDClick, 0}}, - {2730, {wxMouseEvent, leftDown, 0}}, - {2731, {wxMouseEvent, leftIsDown, 0}}, - {2732, {wxMouseEvent, leftUp, 0}}, - {2733, {wxMouseEvent, metaDown, 0}}, - {2734, {wxMouseEvent, middleDClick, 0}}, - {2735, {wxMouseEvent, middleDown, 0}}, - {2736, {wxMouseEvent, middleIsDown, 0}}, - {2737, {wxMouseEvent, middleUp, 0}}, - {2738, {wxMouseEvent, moving, 0}}, - {2739, {wxMouseEvent, rightDClick, 0}}, - {2740, {wxMouseEvent, rightDown, 0}}, - {2741, {wxMouseEvent, rightIsDown, 0}}, - {2742, {wxMouseEvent, rightUp, 0}}, - {2743, {wxMouseEvent, shiftDown, 0}}, - {2744, {wxSetCursorEvent, getCursor, 0}}, - {2745, {wxSetCursorEvent, getX, 0}}, - {2746, {wxSetCursorEvent, getY, 0}}, - {2747, {wxSetCursorEvent, hasCursor, 0}}, - {2748, {wxSetCursorEvent, setCursor, 1}}, - {2749, {wxKeyEvent, altDown, 0}}, - {2750, {wxKeyEvent, cmdDown, 0}}, - {2751, {wxKeyEvent, controlDown, 0}}, - {2752, {wxKeyEvent, getKeyCode, 0}}, - {2753, {wxKeyEvent, getModifiers, 0}}, - {2756, {wxKeyEvent, getPosition, 0}}, - {2757, {wxKeyEvent, getRawKeyCode, 0}}, - {2758, {wxKeyEvent, getRawKeyFlags, 0}}, - {2759, {wxKeyEvent, getUnicodeKey, 0}}, - {2760, {wxKeyEvent, getX, 0}}, - {2761, {wxKeyEvent, getY, 0}}, - {2762, {wxKeyEvent, hasModifiers, 0}}, - {2763, {wxKeyEvent, metaDown, 0}}, - {2764, {wxKeyEvent, shiftDown, 0}}, - {2765, {wxSizeEvent, getSize, 0}}, - {2766, {wxMoveEvent, getPosition, 0}}, - {2767, {wxEraseEvent, getDC, 0}}, - {2768, {wxFocusEvent, getWindow, 0}}, - {2769, {wxChildFocusEvent, getWindow, 0}}, - {2770, {wxMenuEvent, getMenu, 0}}, - {2771, {wxMenuEvent, getMenuId, 0}}, - {2772, {wxMenuEvent, isPopup, 0}}, - {2773, {wxCloseEvent, canVeto, 0}}, - {2774, {wxCloseEvent, getLoggingOff, 0}}, - {2775, {wxCloseEvent, setCanVeto, 1}}, - {2776, {wxCloseEvent, setLoggingOff, 1}}, - {2777, {wxCloseEvent, veto, 1}}, - {2778, {wxShowEvent, setShow, 1}}, - {2779, {wxShowEvent, getShow, 0}}, - {2780, {wxIconizeEvent, iconized, 0}}, - {2781, {wxJoystickEvent, buttonDown, 1}}, - {2782, {wxJoystickEvent, buttonIsDown, 1}}, - {2783, {wxJoystickEvent, buttonUp, 1}}, - {2784, {wxJoystickEvent, getButtonChange, 0}}, - {2785, {wxJoystickEvent, getButtonState, 0}}, - {2786, {wxJoystickEvent, getJoystick, 0}}, - {2787, {wxJoystickEvent, getPosition, 0}}, - {2788, {wxJoystickEvent, getZPosition, 0}}, - {2789, {wxJoystickEvent, isButton, 0}}, - {2790, {wxJoystickEvent, isMove, 0}}, - {2791, {wxJoystickEvent, isZMove, 0}}, - {2792, {wxUpdateUIEvent, canUpdate, 1}}, - {2793, {wxUpdateUIEvent, check, 1}}, - {2794, {wxUpdateUIEvent, enable, 1}}, - {2795, {wxUpdateUIEvent, show, 1}}, - {2796, {wxUpdateUIEvent, getChecked, 0}}, - {2797, {wxUpdateUIEvent, getEnabled, 0}}, - {2798, {wxUpdateUIEvent, getShown, 0}}, - {2799, {wxUpdateUIEvent, getSetChecked, 0}}, - {2800, {wxUpdateUIEvent, getSetEnabled, 0}}, - {2801, {wxUpdateUIEvent, getSetShown, 0}}, - {2802, {wxUpdateUIEvent, getSetText, 0}}, - {2803, {wxUpdateUIEvent, getText, 0}}, - {2804, {wxUpdateUIEvent, getMode, 0}}, - {2805, {wxUpdateUIEvent, getUpdateInterval, 0}}, - {2806, {wxUpdateUIEvent, resetUpdateTime, 0}}, - {2807, {wxUpdateUIEvent, setMode, 1}}, - {2808, {wxUpdateUIEvent, setText, 1}}, - {2809, {wxUpdateUIEvent, setUpdateInterval, 1}}, - {2810, {wxMouseCaptureChangedEvent, getCapturedWindow, 0}}, - {2811, {wxPaletteChangedEvent, setChangedWindow, 1}}, - {2812, {wxPaletteChangedEvent, getChangedWindow, 0}}, - {2813, {wxQueryNewPaletteEvent, setPaletteRealized, 1}}, - {2814, {wxQueryNewPaletteEvent, getPaletteRealized, 0}}, - {2815, {wxNavigationKeyEvent, getDirection, 0}}, - {2816, {wxNavigationKeyEvent, setDirection, 1}}, - {2817, {wxNavigationKeyEvent, isWindowChange, 0}}, - {2818, {wxNavigationKeyEvent, setWindowChange, 1}}, - {2819, {wxNavigationKeyEvent, isFromTab, 0}}, - {2820, {wxNavigationKeyEvent, setFromTab, 1}}, - {2821, {wxNavigationKeyEvent, getCurrentFocus, 0}}, - {2822, {wxNavigationKeyEvent, setCurrentFocus, 1}}, - {2823, {wxHelpEvent, getOrigin, 0}}, - {2824, {wxHelpEvent, getPosition, 0}}, - {2825, {wxHelpEvent, setOrigin, 1}}, - {2826, {wxHelpEvent, setPosition, 1}}, - {2827, {wxContextMenuEvent, getPosition, 0}}, - {2828, {wxContextMenuEvent, setPosition, 1}}, - {2829, {wxIdleEvent, canSend, 1}}, - {2830, {wxIdleEvent, getMode, 0}}, - {2831, {wxIdleEvent, requestMore, 1}}, - {2832, {wxIdleEvent, moreRequested, 0}}, - {2833, {wxIdleEvent, setMode, 1}}, - {2834, {wxGridEvent, altDown, 0}}, - {2835, {wxGridEvent, controlDown, 0}}, - {2836, {wxGridEvent, getCol, 0}}, - {2837, {wxGridEvent, getPosition, 0}}, - {2838, {wxGridEvent, getRow, 0}}, - {2839, {wxGridEvent, metaDown, 0}}, - {2840, {wxGridEvent, selecting, 0}}, - {2841, {wxGridEvent, shiftDown, 0}}, - {2842, {wxNotifyEvent, allow, 0}}, - {2843, {wxNotifyEvent, isAllowed, 0}}, - {2844, {wxNotifyEvent, veto, 0}}, - {2845, {wxSashEvent, getEdge, 0}}, - {2846, {wxSashEvent, getDragRect, 0}}, - {2847, {wxSashEvent, getDragStatus, 0}}, - {2848, {wxListEvent, getCacheFrom, 0}}, - {2849, {wxListEvent, getCacheTo, 0}}, - {2850, {wxListEvent, getKeyCode, 0}}, - {2851, {wxListEvent, getIndex, 0}}, - {2852, {wxListEvent, getColumn, 0}}, - {2853, {wxListEvent, getPoint, 0}}, - {2854, {wxListEvent, getLabel, 0}}, - {2855, {wxListEvent, getText, 0}}, - {2856, {wxListEvent, getImage, 0}}, - {2857, {wxListEvent, getData, 0}}, - {2858, {wxListEvent, getMask, 0}}, - {2859, {wxListEvent, getItem, 0}}, - {2860, {wxListEvent, isEditCancelled, 0}}, - {2861, {wxDateEvent, getDate, 0}}, - {2862, {wxCalendarEvent, getWeekDay, 0}}, - {2863, {wxFileDirPickerEvent, getPath, 0}}, - {2864, {wxColourPickerEvent, getColour, 0}}, - {2865, {wxFontPickerEvent, getFont, 0}}, - {2866, {wxStyledTextEvent, getPosition, 0}}, - {2867, {wxStyledTextEvent, getKey, 0}}, - {2868, {wxStyledTextEvent, getModifiers, 0}}, - {2869, {wxStyledTextEvent, getModificationType, 0}}, - {2870, {wxStyledTextEvent, getText, 0}}, - {2871, {wxStyledTextEvent, getLength, 0}}, - {2872, {wxStyledTextEvent, getLinesAdded, 0}}, - {2873, {wxStyledTextEvent, getLine, 0}}, - {2874, {wxStyledTextEvent, getFoldLevelNow, 0}}, - {2875, {wxStyledTextEvent, getFoldLevelPrev, 0}}, - {2876, {wxStyledTextEvent, getMargin, 0}}, - {2877, {wxStyledTextEvent, getMessage, 0}}, - {2878, {wxStyledTextEvent, getWParam, 0}}, - {2879, {wxStyledTextEvent, getLParam, 0}}, - {2880, {wxStyledTextEvent, getListType, 0}}, - {2881, {wxStyledTextEvent, getX, 0}}, - {2882, {wxStyledTextEvent, getY, 0}}, - {2883, {wxStyledTextEvent, getDragText, 0}}, - {2884, {wxStyledTextEvent, getDragAllowMove, 0}}, - {2885, {wxStyledTextEvent, getDragResult, 0}}, - {2886, {wxStyledTextEvent, getShift, 0}}, - {2887, {wxStyledTextEvent, getControl, 0}}, - {2888, {wxStyledTextEvent, getAlt, 0}}, - {2889, {utils, getKeyState, 1}}, - {2890, {utils, getMousePosition, 2}}, - {2891, {utils, getMouseState, 0}}, - {2892, {utils, setDetectableAutoRepeat, 1}}, - {2893, {utils, bell, 0}}, - {2894, {utils, findMenuItemId, 3}}, - {2895, {utils, genericFindWindowAtPoint, 1}}, - {2896, {utils, findWindowAtPoint, 1}}, - {2897, {utils, beginBusyCursor, 1}}, - {2898, {utils, endBusyCursor, 0}}, - {2899, {utils, isBusy, 0}}, - {2900, {utils, shutdown, 1}}, - {2901, {utils, shell, 1}}, - {2902, {utils, launchDefaultBrowser, 2}}, - {2903, {utils, getEmailAddress, 0}}, - {2904, {utils, getUserId, 0}}, - {2905, {utils, getHomeDir, 0}}, - {2906, {utils, newId, 0}}, - {2907, {utils, registerId, 1}}, - {2908, {utils, getCurrentId, 0}}, - {2909, {utils, getOsDescription, 0}}, - {2910, {utils, isPlatformLittleEndian, 0}}, - {2911, {utils, isPlatform64Bit, 0}}, - {2912, {wxPrintout, new, 1}}, - {2913, {wxPrintout, destruct, 0}}, - {2914, {wxPrintout, getDC, 0}}, - {2915, {wxPrintout, getPageSizeMM, 2}}, - {2916, {wxPrintout, getPageSizePixels, 2}}, - {2917, {wxPrintout, getPaperRectPixels, 0}}, - {2918, {wxPrintout, getPPIPrinter, 2}}, - {2919, {wxPrintout, getPPIScreen, 2}}, - {2920, {wxPrintout, getTitle, 0}}, - {2921, {wxPrintout, isPreview, 0}}, - {2922, {wxPrintout, fitThisSizeToPaper, 1}}, - {2923, {wxPrintout, fitThisSizeToPage, 1}}, - {2924, {wxPrintout, fitThisSizeToPageMargins, 2}}, - {2925, {wxPrintout, mapScreenSizeToPaper, 0}}, - {2926, {wxPrintout, mapScreenSizeToPage, 0}}, - {2927, {wxPrintout, mapScreenSizeToPageMargins, 1}}, - {2928, {wxPrintout, mapScreenSizeToDevice, 0}}, - {2929, {wxPrintout, getLogicalPaperRect, 0}}, - {2930, {wxPrintout, getLogicalPageRect, 0}}, - {2931, {wxPrintout, getLogicalPageMarginsRect, 1}}, - {2932, {wxPrintout, setLogicalOrigin, 2}}, - {2933, {wxPrintout, offsetLogicalOrigin, 2}}, - {2934, {wxStyledTextCtrl, new_2, 2}}, - {2935, {wxStyledTextCtrl, new_0, 0}}, - {2936, {wxStyledTextCtrl, destruct, 0}}, - {2937, {wxStyledTextCtrl, create, 2}}, - {2938, {wxStyledTextCtrl, addText, 1}}, - {2939, {wxStyledTextCtrl, addStyledText, 1}}, - {2940, {wxStyledTextCtrl, insertText, 2}}, - {2941, {wxStyledTextCtrl, clearAll, 0}}, - {2942, {wxStyledTextCtrl, clearDocumentStyle, 0}}, - {2943, {wxStyledTextCtrl, getLength, 0}}, - {2944, {wxStyledTextCtrl, getCharAt, 1}}, - {2945, {wxStyledTextCtrl, getCurrentPos, 0}}, - {2946, {wxStyledTextCtrl, getAnchor, 0}}, - {2947, {wxStyledTextCtrl, getStyleAt, 1}}, - {2948, {wxStyledTextCtrl, redo, 0}}, - {2949, {wxStyledTextCtrl, setUndoCollection, 1}}, - {2950, {wxStyledTextCtrl, selectAll, 0}}, - {2951, {wxStyledTextCtrl, setSavePoint, 0}}, - {2952, {wxStyledTextCtrl, getStyledText, 2}}, - {2953, {wxStyledTextCtrl, canRedo, 0}}, - {2954, {wxStyledTextCtrl, markerLineFromHandle, 1}}, - {2955, {wxStyledTextCtrl, markerDeleteHandle, 1}}, - {2956, {wxStyledTextCtrl, getUndoCollection, 0}}, - {2957, {wxStyledTextCtrl, getViewWhiteSpace, 0}}, - {2958, {wxStyledTextCtrl, setViewWhiteSpace, 1}}, - {2959, {wxStyledTextCtrl, positionFromPoint, 1}}, - {2960, {wxStyledTextCtrl, positionFromPointClose, 2}}, - {2961, {wxStyledTextCtrl, gotoLine, 1}}, - {2962, {wxStyledTextCtrl, gotoPos, 1}}, - {2963, {wxStyledTextCtrl, setAnchor, 1}}, - {2964, {wxStyledTextCtrl, getCurLine, 1}}, - {2965, {wxStyledTextCtrl, getEndStyled, 0}}, - {2966, {wxStyledTextCtrl, convertEOLs, 1}}, - {2967, {wxStyledTextCtrl, getEOLMode, 0}}, - {2968, {wxStyledTextCtrl, setEOLMode, 1}}, - {2969, {wxStyledTextCtrl, startStyling, 2}}, - {2970, {wxStyledTextCtrl, setStyling, 2}}, - {2971, {wxStyledTextCtrl, getBufferedDraw, 0}}, - {2972, {wxStyledTextCtrl, setBufferedDraw, 1}}, - {2973, {wxStyledTextCtrl, setTabWidth, 1}}, - {2974, {wxStyledTextCtrl, getTabWidth, 0}}, - {2975, {wxStyledTextCtrl, setCodePage, 1}}, - {2976, {wxStyledTextCtrl, markerDefine, 3}}, - {2977, {wxStyledTextCtrl, markerSetForeground, 2}}, - {2978, {wxStyledTextCtrl, markerSetBackground, 2}}, - {2979, {wxStyledTextCtrl, markerAdd, 2}}, - {2980, {wxStyledTextCtrl, markerDelete, 2}}, - {2981, {wxStyledTextCtrl, markerDeleteAll, 1}}, - {2982, {wxStyledTextCtrl, markerGet, 1}}, - {2983, {wxStyledTextCtrl, markerNext, 2}}, - {2984, {wxStyledTextCtrl, markerPrevious, 2}}, - {2985, {wxStyledTextCtrl, markerDefineBitmap, 2}}, - {2986, {wxStyledTextCtrl, markerAddSet, 2}}, - {2987, {wxStyledTextCtrl, markerSetAlpha, 2}}, - {2988, {wxStyledTextCtrl, setMarginType, 2}}, - {2989, {wxStyledTextCtrl, getMarginType, 1}}, - {2990, {wxStyledTextCtrl, setMarginWidth, 2}}, - {2991, {wxStyledTextCtrl, getMarginWidth, 1}}, - {2992, {wxStyledTextCtrl, setMarginMask, 2}}, - {2993, {wxStyledTextCtrl, getMarginMask, 1}}, - {2994, {wxStyledTextCtrl, setMarginSensitive, 2}}, - {2995, {wxStyledTextCtrl, getMarginSensitive, 1}}, - {2996, {wxStyledTextCtrl, styleClearAll, 0}}, - {2997, {wxStyledTextCtrl, styleSetForeground, 2}}, - {2998, {wxStyledTextCtrl, styleSetBackground, 2}}, - {2999, {wxStyledTextCtrl, styleSetBold, 2}}, - {3000, {wxStyledTextCtrl, styleSetItalic, 2}}, - {3001, {wxStyledTextCtrl, styleSetSize, 2}}, - {3002, {wxStyledTextCtrl, styleSetFaceName, 2}}, - {3003, {wxStyledTextCtrl, styleSetEOLFilled, 2}}, - {3004, {wxStyledTextCtrl, styleResetDefault, 0}}, - {3005, {wxStyledTextCtrl, styleSetUnderline, 2}}, - {3006, {wxStyledTextCtrl, styleSetCase, 2}}, - {3007, {wxStyledTextCtrl, styleSetHotSpot, 2}}, - {3008, {wxStyledTextCtrl, setSelForeground, 2}}, - {3009, {wxStyledTextCtrl, setSelBackground, 2}}, - {3010, {wxStyledTextCtrl, getSelAlpha, 0}}, - {3011, {wxStyledTextCtrl, setSelAlpha, 1}}, - {3012, {wxStyledTextCtrl, setCaretForeground, 1}}, - {3013, {wxStyledTextCtrl, cmdKeyAssign, 3}}, - {3014, {wxStyledTextCtrl, cmdKeyClear, 2}}, - {3015, {wxStyledTextCtrl, cmdKeyClearAll, 0}}, - {3016, {wxStyledTextCtrl, setStyleBytes, 2}}, - {3017, {wxStyledTextCtrl, styleSetVisible, 2}}, - {3018, {wxStyledTextCtrl, getCaretPeriod, 0}}, - {3019, {wxStyledTextCtrl, setCaretPeriod, 1}}, - {3020, {wxStyledTextCtrl, setWordChars, 1}}, - {3021, {wxStyledTextCtrl, beginUndoAction, 0}}, - {3022, {wxStyledTextCtrl, endUndoAction, 0}}, - {3023, {wxStyledTextCtrl, indicatorSetStyle, 2}}, - {3024, {wxStyledTextCtrl, indicatorGetStyle, 1}}, - {3025, {wxStyledTextCtrl, indicatorSetForeground, 2}}, - {3026, {wxStyledTextCtrl, indicatorGetForeground, 1}}, - {3027, {wxStyledTextCtrl, setWhitespaceForeground, 2}}, - {3028, {wxStyledTextCtrl, setWhitespaceBackground, 2}}, - {3029, {wxStyledTextCtrl, getStyleBits, 0}}, - {3030, {wxStyledTextCtrl, setLineState, 2}}, - {3031, {wxStyledTextCtrl, getLineState, 1}}, - {3032, {wxStyledTextCtrl, getMaxLineState, 0}}, - {3033, {wxStyledTextCtrl, getCaretLineVisible, 0}}, - {3034, {wxStyledTextCtrl, setCaretLineVisible, 1}}, - {3035, {wxStyledTextCtrl, getCaretLineBackground, 0}}, - {3036, {wxStyledTextCtrl, setCaretLineBackground, 1}}, - {3037, {wxStyledTextCtrl, autoCompShow, 2}}, - {3038, {wxStyledTextCtrl, autoCompCancel, 0}}, - {3039, {wxStyledTextCtrl, autoCompActive, 0}}, - {3040, {wxStyledTextCtrl, autoCompPosStart, 0}}, - {3041, {wxStyledTextCtrl, autoCompComplete, 0}}, - {3042, {wxStyledTextCtrl, autoCompStops, 1}}, - {3043, {wxStyledTextCtrl, autoCompSetSeparator, 1}}, - {3044, {wxStyledTextCtrl, autoCompGetSeparator, 0}}, - {3045, {wxStyledTextCtrl, autoCompSelect, 1}}, - {3046, {wxStyledTextCtrl, autoCompSetCancelAtStart, 1}}, - {3047, {wxStyledTextCtrl, autoCompGetCancelAtStart, 0}}, - {3048, {wxStyledTextCtrl, autoCompSetFillUps, 1}}, - {3049, {wxStyledTextCtrl, autoCompSetChooseSingle, 1}}, - {3050, {wxStyledTextCtrl, autoCompGetChooseSingle, 0}}, - {3051, {wxStyledTextCtrl, autoCompSetIgnoreCase, 1}}, - {3052, {wxStyledTextCtrl, autoCompGetIgnoreCase, 0}}, - {3053, {wxStyledTextCtrl, userListShow, 2}}, - {3054, {wxStyledTextCtrl, autoCompSetAutoHide, 1}}, - {3055, {wxStyledTextCtrl, autoCompGetAutoHide, 0}}, - {3056, {wxStyledTextCtrl, autoCompSetDropRestOfWord, 1}}, - {3057, {wxStyledTextCtrl, autoCompGetDropRestOfWord, 0}}, - {3058, {wxStyledTextCtrl, registerImage, 2}}, - {3059, {wxStyledTextCtrl, clearRegisteredImages, 0}}, - {3060, {wxStyledTextCtrl, autoCompGetTypeSeparator, 0}}, - {3061, {wxStyledTextCtrl, autoCompSetTypeSeparator, 1}}, - {3062, {wxStyledTextCtrl, autoCompSetMaxWidth, 1}}, - {3063, {wxStyledTextCtrl, autoCompGetMaxWidth, 0}}, - {3064, {wxStyledTextCtrl, autoCompSetMaxHeight, 1}}, - {3065, {wxStyledTextCtrl, autoCompGetMaxHeight, 0}}, - {3066, {wxStyledTextCtrl, setIndent, 1}}, - {3067, {wxStyledTextCtrl, getIndent, 0}}, - {3068, {wxStyledTextCtrl, setUseTabs, 1}}, - {3069, {wxStyledTextCtrl, getUseTabs, 0}}, - {3070, {wxStyledTextCtrl, setLineIndentation, 2}}, - {3071, {wxStyledTextCtrl, getLineIndentation, 1}}, - {3072, {wxStyledTextCtrl, getLineIndentPosition, 1}}, - {3073, {wxStyledTextCtrl, getColumn, 1}}, - {3074, {wxStyledTextCtrl, setUseHorizontalScrollBar, 1}}, - {3075, {wxStyledTextCtrl, getUseHorizontalScrollBar, 0}}, - {3076, {wxStyledTextCtrl, setIndentationGuides, 1}}, - {3077, {wxStyledTextCtrl, getIndentationGuides, 0}}, - {3078, {wxStyledTextCtrl, setHighlightGuide, 1}}, - {3079, {wxStyledTextCtrl, getHighlightGuide, 0}}, - {3080, {wxStyledTextCtrl, getLineEndPosition, 1}}, - {3081, {wxStyledTextCtrl, getCodePage, 0}}, - {3082, {wxStyledTextCtrl, getCaretForeground, 0}}, - {3083, {wxStyledTextCtrl, getReadOnly, 0}}, - {3084, {wxStyledTextCtrl, setCurrentPos, 1}}, - {3085, {wxStyledTextCtrl, setSelectionStart, 1}}, - {3086, {wxStyledTextCtrl, getSelectionStart, 0}}, - {3087, {wxStyledTextCtrl, setSelectionEnd, 1}}, - {3088, {wxStyledTextCtrl, getSelectionEnd, 0}}, - {3089, {wxStyledTextCtrl, setPrintMagnification, 1}}, - {3090, {wxStyledTextCtrl, getPrintMagnification, 0}}, - {3091, {wxStyledTextCtrl, setPrintColourMode, 1}}, - {3092, {wxStyledTextCtrl, getPrintColourMode, 0}}, - {3093, {wxStyledTextCtrl, findText, 4}}, - {3094, {wxStyledTextCtrl, formatRange, 7}}, - {3095, {wxStyledTextCtrl, getFirstVisibleLine, 0}}, - {3096, {wxStyledTextCtrl, getLine, 1}}, - {3097, {wxStyledTextCtrl, getLineCount, 0}}, - {3098, {wxStyledTextCtrl, setMarginLeft, 1}}, - {3099, {wxStyledTextCtrl, getMarginLeft, 0}}, - {3100, {wxStyledTextCtrl, setMarginRight, 1}}, - {3101, {wxStyledTextCtrl, getMarginRight, 0}}, - {3102, {wxStyledTextCtrl, getModify, 0}}, - {3103, {wxStyledTextCtrl, setSelection, 2}}, - {3104, {wxStyledTextCtrl, getSelectedText, 0}}, - {3105, {wxStyledTextCtrl, getTextRange, 2}}, - {3106, {wxStyledTextCtrl, hideSelection, 1}}, - {3107, {wxStyledTextCtrl, lineFromPosition, 1}}, - {3108, {wxStyledTextCtrl, positionFromLine, 1}}, - {3109, {wxStyledTextCtrl, lineScroll, 2}}, - {3110, {wxStyledTextCtrl, ensureCaretVisible, 0}}, - {3111, {wxStyledTextCtrl, replaceSelection, 1}}, - {3112, {wxStyledTextCtrl, setReadOnly, 1}}, - {3113, {wxStyledTextCtrl, canPaste, 0}}, - {3114, {wxStyledTextCtrl, canUndo, 0}}, - {3115, {wxStyledTextCtrl, emptyUndoBuffer, 0}}, - {3116, {wxStyledTextCtrl, undo, 0}}, - {3117, {wxStyledTextCtrl, cut, 0}}, - {3118, {wxStyledTextCtrl, copy, 0}}, - {3119, {wxStyledTextCtrl, paste, 0}}, - {3120, {wxStyledTextCtrl, clear, 0}}, - {3121, {wxStyledTextCtrl, setText, 1}}, - {3122, {wxStyledTextCtrl, getText, 0}}, - {3123, {wxStyledTextCtrl, getTextLength, 0}}, - {3124, {wxStyledTextCtrl, getOvertype, 0}}, - {3125, {wxStyledTextCtrl, setCaretWidth, 1}}, - {3126, {wxStyledTextCtrl, getCaretWidth, 0}}, - {3127, {wxStyledTextCtrl, setTargetStart, 1}}, - {3128, {wxStyledTextCtrl, getTargetStart, 0}}, - {3129, {wxStyledTextCtrl, setTargetEnd, 1}}, - {3130, {wxStyledTextCtrl, getTargetEnd, 0}}, - {3131, {wxStyledTextCtrl, replaceTarget, 1}}, - {3132, {wxStyledTextCtrl, searchInTarget, 1}}, - {3133, {wxStyledTextCtrl, setSearchFlags, 1}}, - {3134, {wxStyledTextCtrl, getSearchFlags, 0}}, - {3135, {wxStyledTextCtrl, callTipShow, 2}}, - {3136, {wxStyledTextCtrl, callTipCancel, 0}}, - {3137, {wxStyledTextCtrl, callTipActive, 0}}, - {3138, {wxStyledTextCtrl, callTipPosAtStart, 0}}, - {3139, {wxStyledTextCtrl, callTipSetHighlight, 2}}, - {3140, {wxStyledTextCtrl, callTipSetBackground, 1}}, - {3141, {wxStyledTextCtrl, callTipSetForeground, 1}}, - {3142, {wxStyledTextCtrl, callTipSetForegroundHighlight, 1}}, - {3143, {wxStyledTextCtrl, callTipUseStyle, 1}}, - {3144, {wxStyledTextCtrl, visibleFromDocLine, 1}}, - {3145, {wxStyledTextCtrl, docLineFromVisible, 1}}, - {3146, {wxStyledTextCtrl, wrapCount, 1}}, - {3147, {wxStyledTextCtrl, setFoldLevel, 2}}, - {3148, {wxStyledTextCtrl, getFoldLevel, 1}}, - {3149, {wxStyledTextCtrl, getLastChild, 2}}, - {3150, {wxStyledTextCtrl, getFoldParent, 1}}, - {3151, {wxStyledTextCtrl, showLines, 2}}, - {3152, {wxStyledTextCtrl, hideLines, 2}}, - {3153, {wxStyledTextCtrl, getLineVisible, 1}}, - {3154, {wxStyledTextCtrl, setFoldExpanded, 2}}, - {3155, {wxStyledTextCtrl, getFoldExpanded, 1}}, - {3156, {wxStyledTextCtrl, toggleFold, 1}}, - {3157, {wxStyledTextCtrl, ensureVisible, 1}}, - {3158, {wxStyledTextCtrl, setFoldFlags, 1}}, - {3159, {wxStyledTextCtrl, ensureVisibleEnforcePolicy, 1}}, - {3160, {wxStyledTextCtrl, setTabIndents, 1}}, - {3161, {wxStyledTextCtrl, getTabIndents, 0}}, - {3162, {wxStyledTextCtrl, setBackSpaceUnIndents, 1}}, - {3163, {wxStyledTextCtrl, getBackSpaceUnIndents, 0}}, - {3164, {wxStyledTextCtrl, setMouseDwellTime, 1}}, - {3165, {wxStyledTextCtrl, getMouseDwellTime, 0}}, - {3166, {wxStyledTextCtrl, wordStartPosition, 2}}, - {3167, {wxStyledTextCtrl, wordEndPosition, 2}}, - {3168, {wxStyledTextCtrl, setWrapMode, 1}}, - {3169, {wxStyledTextCtrl, getWrapMode, 0}}, - {3170, {wxStyledTextCtrl, setWrapVisualFlags, 1}}, - {3171, {wxStyledTextCtrl, getWrapVisualFlags, 0}}, - {3172, {wxStyledTextCtrl, setWrapVisualFlagsLocation, 1}}, - {3173, {wxStyledTextCtrl, getWrapVisualFlagsLocation, 0}}, - {3174, {wxStyledTextCtrl, setWrapStartIndent, 1}}, - {3175, {wxStyledTextCtrl, getWrapStartIndent, 0}}, - {3176, {wxStyledTextCtrl, setLayoutCache, 1}}, - {3177, {wxStyledTextCtrl, getLayoutCache, 0}}, - {3178, {wxStyledTextCtrl, setScrollWidth, 1}}, - {3179, {wxStyledTextCtrl, getScrollWidth, 0}}, - {3180, {wxStyledTextCtrl, textWidth, 2}}, - {3181, {wxStyledTextCtrl, getEndAtLastLine, 0}}, - {3182, {wxStyledTextCtrl, textHeight, 1}}, - {3183, {wxStyledTextCtrl, setUseVerticalScrollBar, 1}}, - {3184, {wxStyledTextCtrl, getUseVerticalScrollBar, 0}}, - {3185, {wxStyledTextCtrl, appendText, 1}}, - {3186, {wxStyledTextCtrl, getTwoPhaseDraw, 0}}, - {3187, {wxStyledTextCtrl, setTwoPhaseDraw, 1}}, - {3188, {wxStyledTextCtrl, targetFromSelection, 0}}, - {3189, {wxStyledTextCtrl, linesJoin, 0}}, - {3190, {wxStyledTextCtrl, linesSplit, 1}}, - {3191, {wxStyledTextCtrl, setFoldMarginColour, 2}}, - {3192, {wxStyledTextCtrl, setFoldMarginHiColour, 2}}, - {3193, {wxStyledTextCtrl, lineDown, 0}}, - {3194, {wxStyledTextCtrl, lineDownExtend, 0}}, - {3195, {wxStyledTextCtrl, lineUp, 0}}, - {3196, {wxStyledTextCtrl, lineUpExtend, 0}}, - {3197, {wxStyledTextCtrl, charLeft, 0}}, - {3198, {wxStyledTextCtrl, charLeftExtend, 0}}, - {3199, {wxStyledTextCtrl, charRight, 0}}, - {3200, {wxStyledTextCtrl, charRightExtend, 0}}, - {3201, {wxStyledTextCtrl, wordLeft, 0}}, - {3202, {wxStyledTextCtrl, wordLeftExtend, 0}}, - {3203, {wxStyledTextCtrl, wordRight, 0}}, - {3204, {wxStyledTextCtrl, wordRightExtend, 0}}, - {3205, {wxStyledTextCtrl, home, 0}}, - {3206, {wxStyledTextCtrl, homeExtend, 0}}, - {3207, {wxStyledTextCtrl, lineEnd, 0}}, - {3208, {wxStyledTextCtrl, lineEndExtend, 0}}, - {3209, {wxStyledTextCtrl, documentStart, 0}}, - {3210, {wxStyledTextCtrl, documentStartExtend, 0}}, - {3211, {wxStyledTextCtrl, documentEnd, 0}}, - {3212, {wxStyledTextCtrl, documentEndExtend, 0}}, - {3213, {wxStyledTextCtrl, pageUp, 0}}, - {3214, {wxStyledTextCtrl, pageUpExtend, 0}}, - {3215, {wxStyledTextCtrl, pageDown, 0}}, - {3216, {wxStyledTextCtrl, pageDownExtend, 0}}, - {3217, {wxStyledTextCtrl, editToggleOvertype, 0}}, - {3218, {wxStyledTextCtrl, cancel, 0}}, - {3219, {wxStyledTextCtrl, deleteBack, 0}}, - {3220, {wxStyledTextCtrl, tab, 0}}, - {3221, {wxStyledTextCtrl, backTab, 0}}, - {3222, {wxStyledTextCtrl, newLine, 0}}, - {3223, {wxStyledTextCtrl, formFeed, 0}}, - {3224, {wxStyledTextCtrl, vCHome, 0}}, - {3225, {wxStyledTextCtrl, vCHomeExtend, 0}}, - {3226, {wxStyledTextCtrl, zoomIn, 0}}, - {3227, {wxStyledTextCtrl, zoomOut, 0}}, - {3228, {wxStyledTextCtrl, delWordLeft, 0}}, - {3229, {wxStyledTextCtrl, delWordRight, 0}}, - {3230, {wxStyledTextCtrl, lineCut, 0}}, - {3231, {wxStyledTextCtrl, lineDelete, 0}}, - {3232, {wxStyledTextCtrl, lineTranspose, 0}}, - {3233, {wxStyledTextCtrl, lineDuplicate, 0}}, - {3234, {wxStyledTextCtrl, lowerCase, 0}}, - {3235, {wxStyledTextCtrl, upperCase, 0}}, - {3236, {wxStyledTextCtrl, lineScrollDown, 0}}, - {3237, {wxStyledTextCtrl, lineScrollUp, 0}}, - {3238, {wxStyledTextCtrl, deleteBackNotLine, 0}}, - {3239, {wxStyledTextCtrl, homeDisplay, 0}}, - {3240, {wxStyledTextCtrl, homeDisplayExtend, 0}}, - {3241, {wxStyledTextCtrl, lineEndDisplay, 0}}, - {3242, {wxStyledTextCtrl, lineEndDisplayExtend, 0}}, - {3243, {wxStyledTextCtrl, homeWrapExtend, 0}}, - {3244, {wxStyledTextCtrl, lineEndWrap, 0}}, - {3245, {wxStyledTextCtrl, lineEndWrapExtend, 0}}, - {3246, {wxStyledTextCtrl, vCHomeWrap, 0}}, - {3247, {wxStyledTextCtrl, vCHomeWrapExtend, 0}}, - {3248, {wxStyledTextCtrl, lineCopy, 0}}, - {3249, {wxStyledTextCtrl, moveCaretInsideView, 0}}, - {3250, {wxStyledTextCtrl, lineLength, 1}}, - {3251, {wxStyledTextCtrl, braceHighlight, 2}}, - {3252, {wxStyledTextCtrl, braceBadLight, 1}}, - {3253, {wxStyledTextCtrl, braceMatch, 1}}, - {3254, {wxStyledTextCtrl, getViewEOL, 0}}, - {3255, {wxStyledTextCtrl, setViewEOL, 1}}, - {3256, {wxStyledTextCtrl, setModEventMask, 1}}, - {3257, {wxStyledTextCtrl, getEdgeColumn, 0}}, - {3258, {wxStyledTextCtrl, setEdgeColumn, 1}}, - {3259, {wxStyledTextCtrl, getEdgeMode, 0}}, - {3260, {wxStyledTextCtrl, getEdgeColour, 0}}, - {3261, {wxStyledTextCtrl, setEdgeColour, 1}}, - {3262, {wxStyledTextCtrl, searchAnchor, 0}}, - {3263, {wxStyledTextCtrl, searchNext, 2}}, - {3264, {wxStyledTextCtrl, searchPrev, 2}}, - {3265, {wxStyledTextCtrl, linesOnScreen, 0}}, - {3266, {wxStyledTextCtrl, usePopUp, 1}}, - {3267, {wxStyledTextCtrl, selectionIsRectangle, 0}}, - {3268, {wxStyledTextCtrl, setZoom, 1}}, - {3269, {wxStyledTextCtrl, getZoom, 0}}, - {3270, {wxStyledTextCtrl, getModEventMask, 0}}, - {3271, {wxStyledTextCtrl, setSTCFocus, 1}}, - {3272, {wxStyledTextCtrl, getSTCFocus, 0}}, - {3273, {wxStyledTextCtrl, setStatus, 1}}, - {3274, {wxStyledTextCtrl, getStatus, 0}}, - {3275, {wxStyledTextCtrl, setMouseDownCaptures, 1}}, - {3276, {wxStyledTextCtrl, getMouseDownCaptures, 0}}, - {3277, {wxStyledTextCtrl, setSTCCursor, 1}}, - {3278, {wxStyledTextCtrl, getSTCCursor, 0}}, - {3279, {wxStyledTextCtrl, setControlCharSymbol, 1}}, - {3280, {wxStyledTextCtrl, getControlCharSymbol, 0}}, - {3281, {wxStyledTextCtrl, wordPartLeft, 0}}, - {3282, {wxStyledTextCtrl, wordPartLeftExtend, 0}}, - {3283, {wxStyledTextCtrl, wordPartRight, 0}}, - {3284, {wxStyledTextCtrl, wordPartRightExtend, 0}}, - {3285, {wxStyledTextCtrl, setVisiblePolicy, 2}}, - {3286, {wxStyledTextCtrl, delLineLeft, 0}}, - {3287, {wxStyledTextCtrl, delLineRight, 0}}, - {3288, {wxStyledTextCtrl, getXOffset, 0}}, - {3289, {wxStyledTextCtrl, chooseCaretX, 0}}, - {3290, {wxStyledTextCtrl, setXCaretPolicy, 2}}, - {3291, {wxStyledTextCtrl, setYCaretPolicy, 2}}, - {3292, {wxStyledTextCtrl, getPrintWrapMode, 0}}, - {3293, {wxStyledTextCtrl, setHotspotActiveForeground, 2}}, - {3294, {wxStyledTextCtrl, setHotspotActiveBackground, 2}}, - {3295, {wxStyledTextCtrl, setHotspotActiveUnderline, 1}}, - {3296, {wxStyledTextCtrl, setHotspotSingleLine, 1}}, - {3297, {wxStyledTextCtrl, paraDownExtend, 0}}, - {3298, {wxStyledTextCtrl, paraUp, 0}}, - {3299, {wxStyledTextCtrl, paraUpExtend, 0}}, - {3300, {wxStyledTextCtrl, positionBefore, 1}}, - {3301, {wxStyledTextCtrl, positionAfter, 1}}, - {3302, {wxStyledTextCtrl, copyRange, 2}}, - {3303, {wxStyledTextCtrl, copyText, 2}}, - {3304, {wxStyledTextCtrl, setSelectionMode, 1}}, - {3305, {wxStyledTextCtrl, getSelectionMode, 0}}, - {3306, {wxStyledTextCtrl, lineDownRectExtend, 0}}, - {3307, {wxStyledTextCtrl, lineUpRectExtend, 0}}, - {3308, {wxStyledTextCtrl, charLeftRectExtend, 0}}, - {3309, {wxStyledTextCtrl, charRightRectExtend, 0}}, - {3310, {wxStyledTextCtrl, homeRectExtend, 0}}, - {3311, {wxStyledTextCtrl, vCHomeRectExtend, 0}}, - {3312, {wxStyledTextCtrl, lineEndRectExtend, 0}}, - {3313, {wxStyledTextCtrl, pageUpRectExtend, 0}}, - {3314, {wxStyledTextCtrl, pageDownRectExtend, 0}}, - {3315, {wxStyledTextCtrl, stutteredPageUp, 0}}, - {3316, {wxStyledTextCtrl, stutteredPageUpExtend, 0}}, - {3317, {wxStyledTextCtrl, stutteredPageDown, 0}}, - {3318, {wxStyledTextCtrl, stutteredPageDownExtend, 0}}, - {3319, {wxStyledTextCtrl, wordLeftEnd, 0}}, - {3320, {wxStyledTextCtrl, wordLeftEndExtend, 0}}, - {3321, {wxStyledTextCtrl, wordRightEnd, 0}}, - {3322, {wxStyledTextCtrl, wordRightEndExtend, 0}}, - {3323, {wxStyledTextCtrl, setWhitespaceChars, 1}}, - {3324, {wxStyledTextCtrl, setCharsDefault, 0}}, - {3325, {wxStyledTextCtrl, autoCompGetCurrent, 0}}, - {3326, {wxStyledTextCtrl, allocate, 1}}, - {3327, {wxStyledTextCtrl, findColumn, 2}}, - {3328, {wxStyledTextCtrl, getCaretSticky, 0}}, - {3329, {wxStyledTextCtrl, setCaretSticky, 1}}, - {3330, {wxStyledTextCtrl, toggleCaretSticky, 0}}, - {3331, {wxStyledTextCtrl, setPasteConvertEndings, 1}}, - {3332, {wxStyledTextCtrl, getPasteConvertEndings, 0}}, - {3333, {wxStyledTextCtrl, selectionDuplicate, 0}}, - {3334, {wxStyledTextCtrl, setCaretLineBackAlpha, 1}}, - {3335, {wxStyledTextCtrl, getCaretLineBackAlpha, 0}}, - {3336, {wxStyledTextCtrl, startRecord, 0}}, - {3337, {wxStyledTextCtrl, stopRecord, 0}}, - {3338, {wxStyledTextCtrl, setLexer, 1}}, - {3339, {wxStyledTextCtrl, getLexer, 0}}, - {3340, {wxStyledTextCtrl, colourise, 2}}, - {3341, {wxStyledTextCtrl, setProperty, 2}}, - {3342, {wxStyledTextCtrl, setKeyWords, 2}}, - {3343, {wxStyledTextCtrl, setLexerLanguage, 1}}, - {3344, {wxStyledTextCtrl, getProperty, 1}}, - {3345, {wxStyledTextCtrl, getStyleBitsNeeded, 0}}, - {3346, {wxStyledTextCtrl, getCurrentLine, 0}}, - {3347, {wxStyledTextCtrl, styleSetSpec, 2}}, - {3348, {wxStyledTextCtrl, styleSetFont, 2}}, - {3349, {wxStyledTextCtrl, styleSetFontAttr, 7}}, - {3350, {wxStyledTextCtrl, styleSetCharacterSet, 2}}, - {3351, {wxStyledTextCtrl, styleSetFontEncoding, 2}}, - {3352, {wxStyledTextCtrl, cmdKeyExecute, 1}}, - {3353, {wxStyledTextCtrl, setMargins, 2}}, - {3354, {wxStyledTextCtrl, getSelection, 2}}, - {3355, {wxStyledTextCtrl, pointFromPosition, 1}}, - {3356, {wxStyledTextCtrl, scrollToLine, 1}}, - {3357, {wxStyledTextCtrl, scrollToColumn, 1}}, - {3358, {wxStyledTextCtrl, sendMsg, 2}}, - {3359, {wxStyledTextCtrl, setVScrollBar, 1}}, - {3360, {wxStyledTextCtrl, setHScrollBar, 1}}, - {3361, {wxStyledTextCtrl, getLastKeydownProcessed, 0}}, - {3362, {wxStyledTextCtrl, setLastKeydownProcessed, 1}}, - {3363, {wxStyledTextCtrl, saveFile, 1}}, - {3364, {wxStyledTextCtrl, loadFile, 1}}, - {3365, {wxStyledTextCtrl, doDragOver, 3}}, - {3366, {wxStyledTextCtrl, doDropText, 3}}, - {3367, {wxStyledTextCtrl, getUseAntiAliasing, 0}}, - {3368, {wxStyledTextCtrl, addTextRaw, 1}}, - {3369, {wxStyledTextCtrl, insertTextRaw, 2}}, - {3370, {wxStyledTextCtrl, getCurLineRaw, 1}}, - {3371, {wxStyledTextCtrl, getLineRaw, 1}}, - {3372, {wxStyledTextCtrl, getSelectedTextRaw, 0}}, - {3373, {wxStyledTextCtrl, getTextRangeRaw, 2}}, - {3374, {wxStyledTextCtrl, setTextRaw, 1}}, - {3375, {wxStyledTextCtrl, getTextRaw, 0}}, - {3376, {wxStyledTextCtrl, appendTextRaw, 1}}, - {3377, {wxArtProvider, getBitmap, 2}}, - {3378, {wxArtProvider, getIcon, 2}}, - {3379, {wxTreeEvent, getKeyCode, 0}}, - {3380, {wxTreeEvent, getItem, 0}}, - {3381, {wxTreeEvent, getKeyEvent, 0}}, - {3382, {wxTreeEvent, getLabel, 0}}, - {3383, {wxTreeEvent, getOldItem, 0}}, - {3384, {wxTreeEvent, getPoint, 0}}, - {3385, {wxTreeEvent, isEditCancelled, 0}}, - {3386, {wxTreeEvent, setToolTip, 1}}, - {3387, {wxNotebookEvent, getOldSelection, 0}}, - {3388, {wxNotebookEvent, getSelection, 0}}, - {3389, {wxNotebookEvent, setOldSelection, 1}}, - {3390, {wxNotebookEvent, setSelection, 1}}, - {3391, {wxFileDataObject, new, 0}}, - {3392, {wxFileDataObject, addFile, 1}}, - {3393, {wxFileDataObject, getFilenames, 0}}, - {3394, {wxFileDataObject, 'Destroy', undefined}}, - {3395, {wxTextDataObject, new, 1}}, - {3396, {wxTextDataObject, getTextLength, 0}}, - {3397, {wxTextDataObject, getText, 0}}, - {3398, {wxTextDataObject, setText, 1}}, - {3399, {wxTextDataObject, 'Destroy', undefined}}, - {3400, {wxBitmapDataObject, new_1_1, 1}}, - {3401, {wxBitmapDataObject, new_1_0, 1}}, - {3402, {wxBitmapDataObject, getBitmap, 0}}, - {3403, {wxBitmapDataObject, setBitmap, 1}}, - {3404, {wxBitmapDataObject, 'Destroy', undefined}}, - {3406, {wxClipboard, new, 0}}, - {3407, {wxClipboard, destruct, 0}}, - {3408, {wxClipboard, addData, 1}}, - {3409, {wxClipboard, clear, 0}}, - {3410, {wxClipboard, close, 0}}, - {3411, {wxClipboard, flush, 0}}, - {3412, {wxClipboard, getData, 1}}, - {3413, {wxClipboard, isOpened, 0}}, - {3414, {wxClipboard, open, 0}}, - {3415, {wxClipboard, setData, 1}}, - {3417, {wxClipboard, usePrimarySelection, 1}}, - {3418, {wxClipboard, isSupported, 1}}, - {3419, {wxClipboard, get, 0}}, - {3420, {wxSpinEvent, getPosition, 0}}, - {3421, {wxSpinEvent, setPosition, 1}}, - {3422, {wxSplitterWindow, new_0, 0}}, - {3423, {wxSplitterWindow, new_2, 2}}, - {3424, {wxSplitterWindow, destruct, 0}}, - {3425, {wxSplitterWindow, create, 2}}, - {3426, {wxSplitterWindow, getMinimumPaneSize, 0}}, - {3427, {wxSplitterWindow, getSashGravity, 0}}, - {3428, {wxSplitterWindow, getSashPosition, 0}}, - {3429, {wxSplitterWindow, getSplitMode, 0}}, - {3430, {wxSplitterWindow, getWindow1, 0}}, - {3431, {wxSplitterWindow, getWindow2, 0}}, - {3432, {wxSplitterWindow, initialize, 1}}, - {3433, {wxSplitterWindow, isSplit, 0}}, - {3434, {wxSplitterWindow, replaceWindow, 2}}, - {3435, {wxSplitterWindow, setSashGravity, 1}}, - {3436, {wxSplitterWindow, setSashPosition, 2}}, - {3437, {wxSplitterWindow, setSashSize, 1}}, - {3438, {wxSplitterWindow, setMinimumPaneSize, 1}}, - {3439, {wxSplitterWindow, setSplitMode, 1}}, - {3440, {wxSplitterWindow, splitHorizontally, 3}}, - {3441, {wxSplitterWindow, splitVertically, 3}}, - {3442, {wxSplitterWindow, unsplit, 1}}, - {3443, {wxSplitterWindow, updateSize, 0}}, - {3444, {wxSplitterEvent, getSashPosition, 0}}, - {3445, {wxSplitterEvent, getX, 0}}, - {3446, {wxSplitterEvent, getY, 0}}, - {3447, {wxSplitterEvent, getWindowBeingRemoved, 0}}, - {3448, {wxSplitterEvent, setSashPosition, 1}}, - {3449, {wxHtmlWindow, new_0, 0}}, - {3450, {wxHtmlWindow, new_2, 2}}, - {3451, {wxHtmlWindow, appendToPage, 1}}, - {3452, {wxHtmlWindow, getOpenedAnchor, 0}}, - {3453, {wxHtmlWindow, getOpenedPage, 0}}, - {3454, {wxHtmlWindow, getOpenedPageTitle, 0}}, - {3455, {wxHtmlWindow, getRelatedFrame, 0}}, - {3456, {wxHtmlWindow, historyBack, 0}}, - {3457, {wxHtmlWindow, historyCanBack, 0}}, - {3458, {wxHtmlWindow, historyCanForward, 0}}, - {3459, {wxHtmlWindow, historyClear, 0}}, - {3460, {wxHtmlWindow, historyForward, 0}}, - {3461, {wxHtmlWindow, loadFile, 1}}, - {3462, {wxHtmlWindow, loadPage, 1}}, - {3463, {wxHtmlWindow, selectAll, 0}}, - {3464, {wxHtmlWindow, selectionToText, 0}}, - {3465, {wxHtmlWindow, selectLine, 1}}, - {3466, {wxHtmlWindow, selectWord, 1}}, - {3467, {wxHtmlWindow, setBorders, 1}}, - {3468, {wxHtmlWindow, setFonts, 3}}, - {3469, {wxHtmlWindow, setPage, 1}}, - {3470, {wxHtmlWindow, setRelatedFrame, 2}}, - {3471, {wxHtmlWindow, setRelatedStatusBar, 1}}, - {3472, {wxHtmlWindow, toText, 0}}, - {3473, {wxHtmlWindow, 'Destroy', undefined}}, - {3474, {wxHtmlLinkEvent, getLinkInfo, 0}}, - {3475, {wxAuiNotebookEvent, setSelection, 1}}, - {3476, {wxAuiNotebookEvent, getSelection, 0}}, - {3477, {wxAuiNotebookEvent, setOldSelection, 1}}, - {3478, {wxAuiNotebookEvent, getOldSelection, 0}}, - {3479, {wxAuiNotebookEvent, setDragSource, 1}}, - {3480, {wxAuiNotebookEvent, getDragSource, 0}}, - {3481, {wxAuiManagerEvent, setManager, 1}}, - {3482, {wxAuiManagerEvent, getManager, 0}}, - {3483, {wxAuiManagerEvent, setPane, 1}}, - {3484, {wxAuiManagerEvent, getPane, 0}}, - {3485, {wxAuiManagerEvent, setButton, 1}}, - {3486, {wxAuiManagerEvent, getButton, 0}}, - {3487, {wxAuiManagerEvent, setDC, 1}}, - {3488, {wxAuiManagerEvent, getDC, 0}}, - {3489, {wxAuiManagerEvent, veto, 1}}, - {3490, {wxAuiManagerEvent, getVeto, 0}}, - {3491, {wxAuiManagerEvent, setCanVeto, 1}}, - {3492, {wxAuiManagerEvent, canVeto, 0}}, - {3493, {wxLogNull, new, 0}}, - {3494, {wxLogNull, 'Destroy', undefined}}, + {2010, {wxTreeCtrl, editLabel, 1}}, + {2011, {wxTreeCtrl, ensureVisible, 1}}, + {2012, {wxTreeCtrl, expand, 1}}, + {2013, {wxTreeCtrl, getBoundingRect, 3}}, + {2015, {wxTreeCtrl, getChildrenCount, 2}}, + {2016, {wxTreeCtrl, getCount, 0}}, + {2017, {wxTreeCtrl, getEditControl, 0}}, + {2018, {wxTreeCtrl, getFirstChild, 2}}, + {2019, {wxTreeCtrl, getNextChild, 2}}, + {2020, {wxTreeCtrl, getFirstVisibleItem, 0}}, + {2021, {wxTreeCtrl, getImageList, 0}}, + {2022, {wxTreeCtrl, getIndent, 0}}, + {2023, {wxTreeCtrl, getItemBackgroundColour, 1}}, + {2024, {wxTreeCtrl, getItemData, 1}}, + {2025, {wxTreeCtrl, getItemFont, 1}}, + {2026, {wxTreeCtrl, getItemImage_1, 1}}, + {2027, {wxTreeCtrl, getItemImage_2, 2}}, + {2028, {wxTreeCtrl, getItemText, 1}}, + {2029, {wxTreeCtrl, getItemTextColour, 1}}, + {2030, {wxTreeCtrl, getLastChild, 1}}, + {2031, {wxTreeCtrl, getNextSibling, 1}}, + {2032, {wxTreeCtrl, getNextVisible, 1}}, + {2033, {wxTreeCtrl, getItemParent, 1}}, + {2034, {wxTreeCtrl, getPrevSibling, 1}}, + {2035, {wxTreeCtrl, getPrevVisible, 1}}, + {2036, {wxTreeCtrl, getRootItem, 0}}, + {2037, {wxTreeCtrl, getSelection, 0}}, + {2038, {wxTreeCtrl, getSelections, 1}}, + {2039, {wxTreeCtrl, getStateImageList, 0}}, + {2040, {wxTreeCtrl, hitTest, 1}}, + {2042, {wxTreeCtrl, insertItem, 4}}, + {2043, {wxTreeCtrl, isBold, 1}}, + {2044, {wxTreeCtrl, isExpanded, 1}}, + {2045, {wxTreeCtrl, isSelected, 1}}, + {2046, {wxTreeCtrl, isVisible, 1}}, + {2047, {wxTreeCtrl, itemHasChildren, 1}}, + {2048, {wxTreeCtrl, prependItem, 3}}, + {2049, {wxTreeCtrl, scrollTo, 1}}, + {2050, {wxTreeCtrl, selectItem_1, 1}}, + {2051, {wxTreeCtrl, selectItem_2, 2}}, + {2052, {wxTreeCtrl, setIndent, 1}}, + {2053, {wxTreeCtrl, setImageList, 1}}, + {2054, {wxTreeCtrl, setItemBackgroundColour, 2}}, + {2055, {wxTreeCtrl, setItemBold, 2}}, + {2056, {wxTreeCtrl, setItemData, 2}}, + {2057, {wxTreeCtrl, setItemDropHighlight, 2}}, + {2058, {wxTreeCtrl, setItemFont, 2}}, + {2059, {wxTreeCtrl, setItemHasChildren, 2}}, + {2060, {wxTreeCtrl, setItemImage_2, 2}}, + {2061, {wxTreeCtrl, setItemImage_3, 3}}, + {2062, {wxTreeCtrl, setItemText, 2}}, + {2063, {wxTreeCtrl, setItemTextColour, 2}}, + {2064, {wxTreeCtrl, setStateImageList, 1}}, + {2065, {wxTreeCtrl, setWindowStyle, 1}}, + {2066, {wxTreeCtrl, sortChildren, 1}}, + {2067, {wxTreeCtrl, toggle, 1}}, + {2068, {wxTreeCtrl, toggleItemSelection, 1}}, + {2069, {wxTreeCtrl, unselect, 0}}, + {2070, {wxTreeCtrl, unselectAll, 0}}, + {2071, {wxTreeCtrl, unselectItem, 1}}, + {2072, {wxScrollBar, new_0, 0}}, + {2073, {wxScrollBar, new_3, 3}}, + {2074, {wxScrollBar, destruct, 0}}, + {2075, {wxScrollBar, create, 3}}, + {2076, {wxScrollBar, getRange, 0}}, + {2077, {wxScrollBar, getPageSize, 0}}, + {2078, {wxScrollBar, getThumbPosition, 0}}, + {2079, {wxScrollBar, getThumbSize, 0}}, + {2080, {wxScrollBar, setThumbPosition, 1}}, + {2081, {wxScrollBar, setScrollbar, 5}}, + {2083, {wxSpinButton, new_2, 2}}, + {2084, {wxSpinButton, new_0, 0}}, + {2085, {wxSpinButton, create, 2}}, + {2086, {wxSpinButton, getMax, 0}}, + {2087, {wxSpinButton, getMin, 0}}, + {2088, {wxSpinButton, getValue, 0}}, + {2089, {wxSpinButton, setRange, 2}}, + {2090, {wxSpinButton, setValue, 1}}, + {2091, {wxSpinButton, 'Destroy', undefined}}, + {2092, {wxSpinCtrl, new_0, 0}}, + {2093, {wxSpinCtrl, new_2, 2}}, + {2095, {wxSpinCtrl, create, 2}}, + {2098, {wxSpinCtrl, setValue_1_1, 1}}, + {2099, {wxSpinCtrl, setValue_1_0, 1}}, + {2101, {wxSpinCtrl, getValue, 0}}, + {2103, {wxSpinCtrl, setRange, 2}}, + {2104, {wxSpinCtrl, setSelection, 2}}, + {2106, {wxSpinCtrl, getMin, 0}}, + {2108, {wxSpinCtrl, getMax, 0}}, + {2109, {wxSpinCtrl, 'Destroy', undefined}}, + {2110, {wxStaticText, new_0, 0}}, + {2111, {wxStaticText, new_4, 4}}, + {2112, {wxStaticText, create, 4}}, + {2113, {wxStaticText, getLabel, 0}}, + {2114, {wxStaticText, setLabel, 1}}, + {2115, {wxStaticText, wrap, 1}}, + {2116, {wxStaticText, 'Destroy', undefined}}, + {2117, {wxStaticBitmap, new_0, 0}}, + {2118, {wxStaticBitmap, new_4, 4}}, + {2119, {wxStaticBitmap, create, 4}}, + {2120, {wxStaticBitmap, getBitmap, 0}}, + {2121, {wxStaticBitmap, setBitmap, 1}}, + {2122, {wxStaticBitmap, 'Destroy', undefined}}, + {2123, {wxRadioBox, new, 7}}, + {2125, {wxRadioBox, destruct, 0}}, + {2126, {wxRadioBox, create, 7}}, + {2127, {wxRadioBox, enable_2, 2}}, + {2128, {wxRadioBox, enable_1, 1}}, + {2129, {wxRadioBox, getSelection, 0}}, + {2130, {wxRadioBox, getString, 1}}, + {2131, {wxRadioBox, setSelection, 1}}, + {2132, {wxRadioBox, show_2, 2}}, + {2133, {wxRadioBox, show_1, 1}}, + {2134, {wxRadioBox, getColumnCount, 0}}, + {2135, {wxRadioBox, getItemHelpText, 1}}, + {2136, {wxRadioBox, getItemToolTip, 1}}, + {2138, {wxRadioBox, getItemFromPoint, 1}}, + {2139, {wxRadioBox, getRowCount, 0}}, + {2140, {wxRadioBox, isItemEnabled, 1}}, + {2141, {wxRadioBox, isItemShown, 1}}, + {2142, {wxRadioBox, setItemHelpText, 2}}, + {2143, {wxRadioBox, setItemToolTip, 2}}, + {2144, {wxRadioButton, new_0, 0}}, + {2145, {wxRadioButton, new_4, 4}}, + {2146, {wxRadioButton, create, 4}}, + {2147, {wxRadioButton, getValue, 0}}, + {2148, {wxRadioButton, setValue, 1}}, + {2149, {wxRadioButton, 'Destroy', undefined}}, + {2151, {wxSlider, new_6, 6}}, + {2152, {wxSlider, new_0, 0}}, + {2153, {wxSlider, create, 6}}, + {2154, {wxSlider, getLineSize, 0}}, + {2155, {wxSlider, getMax, 0}}, + {2156, {wxSlider, getMin, 0}}, + {2157, {wxSlider, getPageSize, 0}}, + {2158, {wxSlider, getThumbLength, 0}}, + {2159, {wxSlider, getValue, 0}}, + {2160, {wxSlider, setLineSize, 1}}, + {2161, {wxSlider, setPageSize, 1}}, + {2162, {wxSlider, setRange, 2}}, + {2163, {wxSlider, setThumbLength, 1}}, + {2164, {wxSlider, setValue, 1}}, + {2165, {wxSlider, 'Destroy', undefined}}, + {2167, {wxDialog, new_4, 4}}, + {2168, {wxDialog, new_0, 0}}, + {2170, {wxDialog, destruct, 0}}, + {2171, {wxDialog, create, 4}}, + {2172, {wxDialog, createButtonSizer, 1}}, + {2173, {wxDialog, createStdDialogButtonSizer, 1}}, + {2174, {wxDialog, endModal, 1}}, + {2175, {wxDialog, getAffirmativeId, 0}}, + {2176, {wxDialog, getReturnCode, 0}}, + {2177, {wxDialog, isModal, 0}}, + {2178, {wxDialog, setAffirmativeId, 1}}, + {2179, {wxDialog, setReturnCode, 1}}, + {2180, {wxDialog, show, 1}}, + {2181, {wxDialog, showModal, 0}}, + {2182, {wxColourDialog, new_0, 0}}, + {2183, {wxColourDialog, new_2, 2}}, + {2184, {wxColourDialog, destruct, 0}}, + {2185, {wxColourDialog, create, 2}}, + {2186, {wxColourDialog, getColourData, 0}}, + {2187, {wxColourData, new_0, 0}}, + {2188, {wxColourData, new_1, 1}}, + {2189, {wxColourData, destruct, 0}}, + {2190, {wxColourData, getChooseFull, 0}}, + {2191, {wxColourData, getColour, 0}}, + {2193, {wxColourData, getCustomColour, 1}}, + {2194, {wxColourData, setChooseFull, 1}}, + {2195, {wxColourData, setColour, 1}}, + {2196, {wxColourData, setCustomColour, 2}}, + {2197, {wxPalette, new_0, 0}}, + {2198, {wxPalette, new_4, 4}}, + {2200, {wxPalette, destruct, 0}}, + {2201, {wxPalette, create, 4}}, + {2202, {wxPalette, getColoursCount, 0}}, + {2203, {wxPalette, getPixel, 3}}, + {2204, {wxPalette, getRGB, 4}}, + {2205, {wxPalette, isOk, 0}}, + {2209, {wxDirDialog, new, 2}}, + {2210, {wxDirDialog, destruct, 0}}, + {2211, {wxDirDialog, getPath, 0}}, + {2212, {wxDirDialog, getMessage, 0}}, + {2213, {wxDirDialog, setMessage, 1}}, + {2214, {wxDirDialog, setPath, 1}}, + {2218, {wxFileDialog, new, 2}}, + {2219, {wxFileDialog, destruct, 0}}, + {2220, {wxFileDialog, getDirectory, 0}}, + {2221, {wxFileDialog, getFilename, 0}}, + {2222, {wxFileDialog, getFilenames, 1}}, + {2223, {wxFileDialog, getFilterIndex, 0}}, + {2224, {wxFileDialog, getMessage, 0}}, + {2225, {wxFileDialog, getPath, 0}}, + {2226, {wxFileDialog, getPaths, 1}}, + {2227, {wxFileDialog, getWildcard, 0}}, + {2228, {wxFileDialog, setDirectory, 1}}, + {2229, {wxFileDialog, setFilename, 1}}, + {2230, {wxFileDialog, setFilterIndex, 1}}, + {2231, {wxFileDialog, setMessage, 1}}, + {2232, {wxFileDialog, setPath, 1}}, + {2233, {wxFileDialog, setWildcard, 1}}, + {2234, {wxPickerBase, setInternalMargin, 1}}, + {2235, {wxPickerBase, getInternalMargin, 0}}, + {2236, {wxPickerBase, setTextCtrlProportion, 1}}, + {2237, {wxPickerBase, setPickerCtrlProportion, 1}}, + {2238, {wxPickerBase, getTextCtrlProportion, 0}}, + {2239, {wxPickerBase, getPickerCtrlProportion, 0}}, + {2240, {wxPickerBase, hasTextCtrl, 0}}, + {2241, {wxPickerBase, getTextCtrl, 0}}, + {2242, {wxPickerBase, isTextCtrlGrowable, 0}}, + {2243, {wxPickerBase, setPickerCtrlGrowable, 1}}, + {2244, {wxPickerBase, setTextCtrlGrowable, 1}}, + {2245, {wxPickerBase, isPickerCtrlGrowable, 0}}, + {2246, {wxFilePickerCtrl, new_0, 0}}, + {2247, {wxFilePickerCtrl, new_3, 3}}, + {2248, {wxFilePickerCtrl, create, 3}}, + {2249, {wxFilePickerCtrl, getPath, 0}}, + {2250, {wxFilePickerCtrl, setPath, 1}}, + {2251, {wxFilePickerCtrl, 'Destroy', undefined}}, + {2252, {wxDirPickerCtrl, new_0, 0}}, + {2253, {wxDirPickerCtrl, new_3, 3}}, + {2254, {wxDirPickerCtrl, create, 3}}, + {2255, {wxDirPickerCtrl, getPath, 0}}, + {2256, {wxDirPickerCtrl, setPath, 1}}, + {2257, {wxDirPickerCtrl, 'Destroy', undefined}}, + {2258, {wxColourPickerCtrl, new_0, 0}}, + {2259, {wxColourPickerCtrl, new_3, 3}}, + {2260, {wxColourPickerCtrl, create, 3}}, + {2261, {wxColourPickerCtrl, getColour, 0}}, + {2262, {wxColourPickerCtrl, setColour_1_1, 1}}, + {2263, {wxColourPickerCtrl, setColour_1_0, 1}}, + {2264, {wxColourPickerCtrl, 'Destroy', undefined}}, + {2265, {wxDatePickerCtrl, new_0, 0}}, + {2266, {wxDatePickerCtrl, new_3, 3}}, + {2267, {wxDatePickerCtrl, getRange, 2}}, + {2268, {wxDatePickerCtrl, getValue, 0}}, + {2269, {wxDatePickerCtrl, setRange, 2}}, + {2270, {wxDatePickerCtrl, setValue, 1}}, + {2271, {wxDatePickerCtrl, 'Destroy', undefined}}, + {2272, {wxFontPickerCtrl, new_0, 0}}, + {2273, {wxFontPickerCtrl, new_3, 3}}, + {2274, {wxFontPickerCtrl, create, 3}}, + {2275, {wxFontPickerCtrl, getSelectedFont, 0}}, + {2276, {wxFontPickerCtrl, setSelectedFont, 1}}, + {2277, {wxFontPickerCtrl, getMaxPointSize, 0}}, + {2278, {wxFontPickerCtrl, setMaxPointSize, 1}}, + {2279, {wxFontPickerCtrl, 'Destroy', undefined}}, + {2282, {wxFindReplaceDialog, new_0, 0}}, + {2283, {wxFindReplaceDialog, new_4, 4}}, + {2284, {wxFindReplaceDialog, destruct, 0}}, + {2285, {wxFindReplaceDialog, create, 4}}, + {2286, {wxFindReplaceDialog, getData, 0}}, + {2287, {wxFindReplaceData, new_0, 0}}, + {2288, {wxFindReplaceData, new_1, 1}}, + {2289, {wxFindReplaceData, getFindString, 0}}, + {2290, {wxFindReplaceData, getReplaceString, 0}}, + {2291, {wxFindReplaceData, getFlags, 0}}, + {2292, {wxFindReplaceData, setFlags, 1}}, + {2293, {wxFindReplaceData, setFindString, 1}}, + {2294, {wxFindReplaceData, setReplaceString, 1}}, + {2295, {wxFindReplaceData, 'Destroy', undefined}}, + {2296, {wxMultiChoiceDialog, new_0, 0}}, + {2298, {wxMultiChoiceDialog, new_5, 5}}, + {2299, {wxMultiChoiceDialog, getSelections, 0}}, + {2300, {wxMultiChoiceDialog, setSelections, 1}}, + {2301, {wxMultiChoiceDialog, 'Destroy', undefined}}, + {2302, {wxSingleChoiceDialog, new_0, 0}}, + {2304, {wxSingleChoiceDialog, new_5, 5}}, + {2305, {wxSingleChoiceDialog, getSelection, 0}}, + {2306, {wxSingleChoiceDialog, getStringSelection, 0}}, + {2307, {wxSingleChoiceDialog, setSelection, 1}}, + {2308, {wxSingleChoiceDialog, 'Destroy', undefined}}, + {2309, {wxTextEntryDialog, new, 3}}, + {2310, {wxTextEntryDialog, getValue, 0}}, + {2311, {wxTextEntryDialog, setValue, 1}}, + {2312, {wxTextEntryDialog, 'Destroy', undefined}}, + {2313, {wxPasswordEntryDialog, new, 3}}, + {2314, {wxPasswordEntryDialog, 'Destroy', undefined}}, + {2315, {wxFontData, new_0, 0}}, + {2316, {wxFontData, new_1, 1}}, + {2317, {wxFontData, destruct, 0}}, + {2318, {wxFontData, enableEffects, 1}}, + {2319, {wxFontData, getAllowSymbols, 0}}, + {2320, {wxFontData, getColour, 0}}, + {2321, {wxFontData, getChosenFont, 0}}, + {2322, {wxFontData, getEnableEffects, 0}}, + {2323, {wxFontData, getInitialFont, 0}}, + {2324, {wxFontData, getShowHelp, 0}}, + {2325, {wxFontData, setAllowSymbols, 1}}, + {2326, {wxFontData, setChosenFont, 1}}, + {2327, {wxFontData, setColour, 1}}, + {2328, {wxFontData, setInitialFont, 1}}, + {2329, {wxFontData, setRange, 2}}, + {2330, {wxFontData, setShowHelp, 1}}, + {2334, {wxFontDialog, new_0, 0}}, + {2336, {wxFontDialog, new_2, 2}}, + {2338, {wxFontDialog, create, 2}}, + {2339, {wxFontDialog, getFontData, 0}}, + {2341, {wxFontDialog, 'Destroy', undefined}}, + {2342, {wxProgressDialog, new, 3}}, + {2343, {wxProgressDialog, destruct, 0}}, + {2344, {wxProgressDialog, resume, 0}}, + {2345, {wxProgressDialog, update_2, 2}}, + {2346, {wxProgressDialog, update_0, 0}}, + {2347, {wxMessageDialog, new, 3}}, + {2348, {wxMessageDialog, destruct, 0}}, + {2349, {wxPageSetupDialog, new, 2}}, + {2350, {wxPageSetupDialog, destruct, 0}}, + {2351, {wxPageSetupDialog, getPageSetupData, 0}}, + {2352, {wxPageSetupDialog, showModal, 0}}, + {2353, {wxPageSetupDialogData, new_0, 0}}, + {2354, {wxPageSetupDialogData, new_1_0, 1}}, + {2355, {wxPageSetupDialogData, new_1_1, 1}}, + {2356, {wxPageSetupDialogData, destruct, 0}}, + {2357, {wxPageSetupDialogData, enableHelp, 1}}, + {2358, {wxPageSetupDialogData, enableMargins, 1}}, + {2359, {wxPageSetupDialogData, enableOrientation, 1}}, + {2360, {wxPageSetupDialogData, enablePaper, 1}}, + {2361, {wxPageSetupDialogData, enablePrinter, 1}}, + {2362, {wxPageSetupDialogData, getDefaultMinMargins, 0}}, + {2363, {wxPageSetupDialogData, getEnableMargins, 0}}, + {2364, {wxPageSetupDialogData, getEnableOrientation, 0}}, + {2365, {wxPageSetupDialogData, getEnablePaper, 0}}, + {2366, {wxPageSetupDialogData, getEnablePrinter, 0}}, + {2367, {wxPageSetupDialogData, getEnableHelp, 0}}, + {2368, {wxPageSetupDialogData, getDefaultInfo, 0}}, + {2369, {wxPageSetupDialogData, getMarginTopLeft, 0}}, + {2370, {wxPageSetupDialogData, getMarginBottomRight, 0}}, + {2371, {wxPageSetupDialogData, getMinMarginTopLeft, 0}}, + {2372, {wxPageSetupDialogData, getMinMarginBottomRight, 0}}, + {2373, {wxPageSetupDialogData, getPaperId, 0}}, + {2374, {wxPageSetupDialogData, getPaperSize, 0}}, + {2376, {wxPageSetupDialogData, getPrintData, 0}}, + {2377, {wxPageSetupDialogData, isOk, 0}}, + {2378, {wxPageSetupDialogData, setDefaultInfo, 1}}, + {2379, {wxPageSetupDialogData, setDefaultMinMargins, 1}}, + {2380, {wxPageSetupDialogData, setMarginTopLeft, 1}}, + {2381, {wxPageSetupDialogData, setMarginBottomRight, 1}}, + {2382, {wxPageSetupDialogData, setMinMarginTopLeft, 1}}, + {2383, {wxPageSetupDialogData, setMinMarginBottomRight, 1}}, + {2384, {wxPageSetupDialogData, setPaperId, 1}}, + {2385, {wxPageSetupDialogData, setPaperSize_1_1, 1}}, + {2386, {wxPageSetupDialogData, setPaperSize_1_0, 1}}, + {2387, {wxPageSetupDialogData, setPrintData, 1}}, + {2388, {wxPrintDialog, new_2_0, 2}}, + {2389, {wxPrintDialog, new_2_1, 2}}, + {2390, {wxPrintDialog, destruct, 0}}, + {2391, {wxPrintDialog, getPrintDialogData, 0}}, + {2392, {wxPrintDialog, getPrintDC, 0}}, + {2393, {wxPrintDialogData, new_0, 0}}, + {2394, {wxPrintDialogData, new_1_1, 1}}, + {2395, {wxPrintDialogData, new_1_0, 1}}, + {2396, {wxPrintDialogData, destruct, 0}}, + {2397, {wxPrintDialogData, enableHelp, 1}}, + {2398, {wxPrintDialogData, enablePageNumbers, 1}}, + {2399, {wxPrintDialogData, enablePrintToFile, 1}}, + {2400, {wxPrintDialogData, enableSelection, 1}}, + {2401, {wxPrintDialogData, getAllPages, 0}}, + {2402, {wxPrintDialogData, getCollate, 0}}, + {2403, {wxPrintDialogData, getFromPage, 0}}, + {2404, {wxPrintDialogData, getMaxPage, 0}}, + {2405, {wxPrintDialogData, getMinPage, 0}}, + {2406, {wxPrintDialogData, getNoCopies, 0}}, + {2407, {wxPrintDialogData, getPrintData, 0}}, + {2408, {wxPrintDialogData, getPrintToFile, 0}}, + {2409, {wxPrintDialogData, getSelection, 0}}, + {2410, {wxPrintDialogData, getToPage, 0}}, + {2411, {wxPrintDialogData, isOk, 0}}, + {2412, {wxPrintDialogData, setCollate, 1}}, + {2413, {wxPrintDialogData, setFromPage, 1}}, + {2414, {wxPrintDialogData, setMaxPage, 1}}, + {2415, {wxPrintDialogData, setMinPage, 1}}, + {2416, {wxPrintDialogData, setNoCopies, 1}}, + {2417, {wxPrintDialogData, setPrintData, 1}}, + {2418, {wxPrintDialogData, setPrintToFile, 1}}, + {2419, {wxPrintDialogData, setSelection, 1}}, + {2420, {wxPrintDialogData, setToPage, 1}}, + {2421, {wxPrintData, new_0, 0}}, + {2422, {wxPrintData, new_1, 1}}, + {2423, {wxPrintData, destruct, 0}}, + {2424, {wxPrintData, getCollate, 0}}, + {2425, {wxPrintData, getBin, 0}}, + {2426, {wxPrintData, getColour, 0}}, + {2427, {wxPrintData, getDuplex, 0}}, + {2428, {wxPrintData, getNoCopies, 0}}, + {2429, {wxPrintData, getOrientation, 0}}, + {2430, {wxPrintData, getPaperId, 0}}, + {2431, {wxPrintData, getPrinterName, 0}}, + {2432, {wxPrintData, getQuality, 0}}, + {2433, {wxPrintData, isOk, 0}}, + {2434, {wxPrintData, setBin, 1}}, + {2435, {wxPrintData, setCollate, 1}}, + {2436, {wxPrintData, setColour, 1}}, + {2437, {wxPrintData, setDuplex, 1}}, + {2438, {wxPrintData, setNoCopies, 1}}, + {2439, {wxPrintData, setOrientation, 1}}, + {2440, {wxPrintData, setPaperId, 1}}, + {2441, {wxPrintData, setPrinterName, 1}}, + {2442, {wxPrintData, setQuality, 1}}, + {2445, {wxPrintPreview, new_2, 2}}, + {2446, {wxPrintPreview, new_3, 3}}, + {2448, {wxPrintPreview, destruct, 0}}, + {2449, {wxPrintPreview, getCanvas, 0}}, + {2450, {wxPrintPreview, getCurrentPage, 0}}, + {2451, {wxPrintPreview, getFrame, 0}}, + {2452, {wxPrintPreview, getMaxPage, 0}}, + {2453, {wxPrintPreview, getMinPage, 0}}, + {2454, {wxPrintPreview, getPrintout, 0}}, + {2455, {wxPrintPreview, getPrintoutForPrinting, 0}}, + {2456, {wxPrintPreview, isOk, 0}}, + {2457, {wxPrintPreview, paintPage, 2}}, + {2458, {wxPrintPreview, print, 1}}, + {2459, {wxPrintPreview, renderPage, 1}}, + {2460, {wxPrintPreview, setCanvas, 1}}, + {2461, {wxPrintPreview, setCurrentPage, 1}}, + {2462, {wxPrintPreview, setFrame, 1}}, + {2463, {wxPrintPreview, setPrintout, 1}}, + {2464, {wxPrintPreview, setZoom, 1}}, + {2465, {wxPreviewFrame, new, 3}}, + {2466, {wxPreviewFrame, destruct, 0}}, + {2467, {wxPreviewFrame, createControlBar, 0}}, + {2468, {wxPreviewFrame, createCanvas, 0}}, + {2469, {wxPreviewFrame, initialize, 0}}, + {2470, {wxPreviewFrame, onCloseWindow, 1}}, + {2471, {wxPreviewControlBar, new, 4}}, + {2472, {wxPreviewControlBar, destruct, 0}}, + {2473, {wxPreviewControlBar, createButtons, 0}}, + {2474, {wxPreviewControlBar, getPrintPreview, 0}}, + {2475, {wxPreviewControlBar, getZoomControl, 0}}, + {2476, {wxPreviewControlBar, setZoomControl, 1}}, + {2478, {wxPrinter, new, 1}}, + {2479, {wxPrinter, createAbortWindow, 2}}, + {2480, {wxPrinter, getAbort, 0}}, + {2481, {wxPrinter, getLastError, 0}}, + {2482, {wxPrinter, getPrintDialogData, 0}}, + {2483, {wxPrinter, print, 3}}, + {2484, {wxPrinter, printDialog, 1}}, + {2485, {wxPrinter, reportError, 3}}, + {2486, {wxPrinter, setup, 1}}, + {2487, {wxPrinter, 'Destroy', undefined}}, + {2488, {wxXmlResource, new_1, 1}}, + {2489, {wxXmlResource, new_2, 2}}, + {2490, {wxXmlResource, destruct, 0}}, + {2491, {wxXmlResource, attachUnknownControl, 3}}, + {2492, {wxXmlResource, clearHandlers, 0}}, + {2493, {wxXmlResource, compareVersion, 4}}, + {2494, {wxXmlResource, get, 0}}, + {2495, {wxXmlResource, getFlags, 0}}, + {2496, {wxXmlResource, getVersion, 0}}, + {2497, {wxXmlResource, getXRCID, 2}}, + {2498, {wxXmlResource, initAllHandlers, 0}}, + {2499, {wxXmlResource, load, 1}}, + {2500, {wxXmlResource, loadBitmap, 1}}, + {2501, {wxXmlResource, loadDialog_2, 2}}, + {2502, {wxXmlResource, loadDialog_3, 3}}, + {2503, {wxXmlResource, loadFrame_2, 2}}, + {2504, {wxXmlResource, loadFrame_3, 3}}, + {2505, {wxXmlResource, loadIcon, 1}}, + {2506, {wxXmlResource, loadMenu, 1}}, + {2507, {wxXmlResource, loadMenuBar_2, 2}}, + {2508, {wxXmlResource, loadMenuBar_1, 1}}, + {2509, {wxXmlResource, loadPanel_2, 2}}, + {2510, {wxXmlResource, loadPanel_3, 3}}, + {2511, {wxXmlResource, loadToolBar, 2}}, + {2512, {wxXmlResource, set, 1}}, + {2513, {wxXmlResource, setFlags, 1}}, + {2514, {wxXmlResource, unload, 1}}, + {2515, {wxXmlResource, xrcctrl, 3}}, + {2516, {wxHtmlEasyPrinting, new, 1}}, + {2517, {wxHtmlEasyPrinting, destruct, 0}}, + {2518, {wxHtmlEasyPrinting, getPrintData, 0}}, + {2519, {wxHtmlEasyPrinting, getPageSetupData, 0}}, + {2520, {wxHtmlEasyPrinting, previewFile, 1}}, + {2521, {wxHtmlEasyPrinting, previewText, 2}}, + {2522, {wxHtmlEasyPrinting, printFile, 1}}, + {2523, {wxHtmlEasyPrinting, printText, 2}}, + {2524, {wxHtmlEasyPrinting, pageSetup, 0}}, + {2525, {wxHtmlEasyPrinting, setFonts, 3}}, + {2526, {wxHtmlEasyPrinting, setHeader, 2}}, + {2527, {wxHtmlEasyPrinting, setFooter, 2}}, + {2529, {wxGLCanvas, new_2, 2}}, + {2530, {wxGLCanvas, new_3_1, 3}}, + {2531, {wxGLCanvas, new_3_0, 3}}, + {2532, {wxGLCanvas, getContext, 0}}, + {2534, {wxGLCanvas, setCurrent, 0}}, + {2535, {wxGLCanvas, swapBuffers, 0}}, + {2536, {wxGLCanvas, 'Destroy', undefined}}, + {2537, {wxAuiManager, new, 1}}, + {2538, {wxAuiManager, destruct, 0}}, + {2539, {wxAuiManager, addPane_2_1, 2}}, + {2540, {wxAuiManager, addPane_3, 3}}, + {2541, {wxAuiManager, addPane_2_0, 2}}, + {2542, {wxAuiManager, detachPane, 1}}, + {2543, {wxAuiManager, getAllPanes, 0}}, + {2544, {wxAuiManager, getArtProvider, 0}}, + {2545, {wxAuiManager, getDockSizeConstraint, 2}}, + {2546, {wxAuiManager, getFlags, 0}}, + {2547, {wxAuiManager, getManagedWindow, 0}}, + {2548, {wxAuiManager, getManager, 1}}, + {2549, {wxAuiManager, getPane_1_1, 1}}, + {2550, {wxAuiManager, getPane_1_0, 1}}, + {2551, {wxAuiManager, hideHint, 0}}, + {2552, {wxAuiManager, insertPane, 3}}, + {2553, {wxAuiManager, loadPaneInfo, 2}}, + {2554, {wxAuiManager, loadPerspective, 2}}, + {2555, {wxAuiManager, savePaneInfo, 1}}, + {2556, {wxAuiManager, savePerspective, 0}}, + {2557, {wxAuiManager, setArtProvider, 1}}, + {2558, {wxAuiManager, setDockSizeConstraint, 2}}, + {2559, {wxAuiManager, setFlags, 1}}, + {2560, {wxAuiManager, setManagedWindow, 1}}, + {2561, {wxAuiManager, showHint, 1}}, + {2562, {wxAuiManager, unInit, 0}}, + {2563, {wxAuiManager, update, 0}}, + {2564, {wxAuiPaneInfo, new_0, 0}}, + {2565, {wxAuiPaneInfo, new_1, 1}}, + {2566, {wxAuiPaneInfo, destruct, 0}}, + {2567, {wxAuiPaneInfo, bestSize_1, 1}}, + {2568, {wxAuiPaneInfo, bestSize_2, 2}}, + {2569, {wxAuiPaneInfo, bottom, 0}}, + {2570, {wxAuiPaneInfo, bottomDockable, 1}}, + {2571, {wxAuiPaneInfo, caption, 1}}, + {2572, {wxAuiPaneInfo, captionVisible, 1}}, + {2573, {wxAuiPaneInfo, centre, 0}}, + {2574, {wxAuiPaneInfo, centrePane, 0}}, + {2575, {wxAuiPaneInfo, closeButton, 1}}, + {2576, {wxAuiPaneInfo, defaultPane, 0}}, + {2577, {wxAuiPaneInfo, destroyOnClose, 1}}, + {2578, {wxAuiPaneInfo, direction, 1}}, + {2579, {wxAuiPaneInfo, dock, 0}}, + {2580, {wxAuiPaneInfo, dockable, 1}}, + {2581, {wxAuiPaneInfo, fixed, 0}}, + {2582, {wxAuiPaneInfo, float, 0}}, + {2583, {wxAuiPaneInfo, floatable, 1}}, + {2584, {wxAuiPaneInfo, floatingPosition_1, 1}}, + {2585, {wxAuiPaneInfo, floatingPosition_2, 2}}, + {2586, {wxAuiPaneInfo, floatingSize_1, 1}}, + {2587, {wxAuiPaneInfo, floatingSize_2, 2}}, + {2588, {wxAuiPaneInfo, gripper, 1}}, + {2589, {wxAuiPaneInfo, gripperTop, 1}}, + {2590, {wxAuiPaneInfo, hasBorder, 0}}, + {2591, {wxAuiPaneInfo, hasCaption, 0}}, + {2592, {wxAuiPaneInfo, hasCloseButton, 0}}, + {2593, {wxAuiPaneInfo, hasFlag, 1}}, + {2594, {wxAuiPaneInfo, hasGripper, 0}}, + {2595, {wxAuiPaneInfo, hasGripperTop, 0}}, + {2596, {wxAuiPaneInfo, hasMaximizeButton, 0}}, + {2597, {wxAuiPaneInfo, hasMinimizeButton, 0}}, + {2598, {wxAuiPaneInfo, hasPinButton, 0}}, + {2599, {wxAuiPaneInfo, hide, 0}}, + {2600, {wxAuiPaneInfo, isBottomDockable, 0}}, + {2601, {wxAuiPaneInfo, isDocked, 0}}, + {2602, {wxAuiPaneInfo, isFixed, 0}}, + {2603, {wxAuiPaneInfo, isFloatable, 0}}, + {2604, {wxAuiPaneInfo, isFloating, 0}}, + {2605, {wxAuiPaneInfo, isLeftDockable, 0}}, + {2606, {wxAuiPaneInfo, isMovable, 0}}, + {2607, {wxAuiPaneInfo, isOk, 0}}, + {2608, {wxAuiPaneInfo, isResizable, 0}}, + {2609, {wxAuiPaneInfo, isRightDockable, 0}}, + {2610, {wxAuiPaneInfo, isShown, 0}}, + {2611, {wxAuiPaneInfo, isToolbar, 0}}, + {2612, {wxAuiPaneInfo, isTopDockable, 0}}, + {2613, {wxAuiPaneInfo, layer, 1}}, + {2614, {wxAuiPaneInfo, left, 0}}, + {2615, {wxAuiPaneInfo, leftDockable, 1}}, + {2616, {wxAuiPaneInfo, maxSize_1, 1}}, + {2617, {wxAuiPaneInfo, maxSize_2, 2}}, + {2618, {wxAuiPaneInfo, maximizeButton, 1}}, + {2619, {wxAuiPaneInfo, minSize_1, 1}}, + {2620, {wxAuiPaneInfo, minSize_2, 2}}, + {2621, {wxAuiPaneInfo, minimizeButton, 1}}, + {2622, {wxAuiPaneInfo, movable, 1}}, + {2623, {wxAuiPaneInfo, name, 1}}, + {2624, {wxAuiPaneInfo, paneBorder, 1}}, + {2625, {wxAuiPaneInfo, pinButton, 1}}, + {2626, {wxAuiPaneInfo, position, 1}}, + {2627, {wxAuiPaneInfo, resizable, 1}}, + {2628, {wxAuiPaneInfo, right, 0}}, + {2629, {wxAuiPaneInfo, rightDockable, 1}}, + {2630, {wxAuiPaneInfo, row, 1}}, + {2631, {wxAuiPaneInfo, safeSet, 1}}, + {2632, {wxAuiPaneInfo, setFlag, 2}}, + {2633, {wxAuiPaneInfo, show, 1}}, + {2634, {wxAuiPaneInfo, toolbarPane, 0}}, + {2635, {wxAuiPaneInfo, top, 0}}, + {2636, {wxAuiPaneInfo, topDockable, 1}}, + {2637, {wxAuiPaneInfo, window, 1}}, + {2638, {wxAuiNotebook, new_0, 0}}, + {2639, {wxAuiNotebook, new_2, 2}}, + {2640, {wxAuiNotebook, addPage, 3}}, + {2641, {wxAuiNotebook, create, 2}}, + {2642, {wxAuiNotebook, deletePage, 1}}, + {2643, {wxAuiNotebook, getArtProvider, 0}}, + {2644, {wxAuiNotebook, getPage, 1}}, + {2645, {wxAuiNotebook, getPageBitmap, 1}}, + {2646, {wxAuiNotebook, getPageCount, 0}}, + {2647, {wxAuiNotebook, getPageIndex, 1}}, + {2648, {wxAuiNotebook, getPageText, 1}}, + {2649, {wxAuiNotebook, getSelection, 0}}, + {2650, {wxAuiNotebook, insertPage, 4}}, + {2651, {wxAuiNotebook, removePage, 1}}, + {2652, {wxAuiNotebook, setArtProvider, 1}}, + {2653, {wxAuiNotebook, setFont, 1}}, + {2654, {wxAuiNotebook, setPageBitmap, 2}}, + {2655, {wxAuiNotebook, setPageText, 2}}, + {2656, {wxAuiNotebook, setSelection, 1}}, + {2657, {wxAuiNotebook, setTabCtrlHeight, 1}}, + {2658, {wxAuiNotebook, setUniformBitmapSize, 1}}, + {2659, {wxAuiNotebook, 'Destroy', undefined}}, + {2660, {wxMDIParentFrame, new_0, 0}}, + {2661, {wxMDIParentFrame, new_4, 4}}, + {2662, {wxMDIParentFrame, destruct, 0}}, + {2663, {wxMDIParentFrame, activateNext, 0}}, + {2664, {wxMDIParentFrame, activatePrevious, 0}}, + {2665, {wxMDIParentFrame, arrangeIcons, 0}}, + {2666, {wxMDIParentFrame, cascade, 0}}, + {2667, {wxMDIParentFrame, create, 4}}, + {2668, {wxMDIParentFrame, getActiveChild, 0}}, + {2669, {wxMDIParentFrame, getClientWindow, 0}}, + {2670, {wxMDIParentFrame, tile, 1}}, + {2671, {wxMDIChildFrame, new_0, 0}}, + {2672, {wxMDIChildFrame, new_4, 4}}, + {2673, {wxMDIChildFrame, destruct, 0}}, + {2674, {wxMDIChildFrame, activate, 0}}, + {2675, {wxMDIChildFrame, create, 4}}, + {2676, {wxMDIChildFrame, maximize, 1}}, + {2677, {wxMDIChildFrame, restore, 0}}, + {2678, {wxMDIClientWindow, new_0, 0}}, + {2679, {wxMDIClientWindow, new_2, 2}}, + {2680, {wxMDIClientWindow, destruct, 0}}, + {2681, {wxMDIClientWindow, createClient, 2}}, + {2682, {wxLayoutAlgorithm, new, 0}}, + {2683, {wxLayoutAlgorithm, layoutFrame, 2}}, + {2684, {wxLayoutAlgorithm, layoutMDIFrame, 2}}, + {2685, {wxLayoutAlgorithm, layoutWindow, 2}}, + {2686, {wxLayoutAlgorithm, 'Destroy', undefined}}, + {2687, {wxEvent, getId, 0}}, + {2688, {wxEvent, getSkipped, 0}}, + {2689, {wxEvent, getTimestamp, 0}}, + {2690, {wxEvent, isCommandEvent, 0}}, + {2691, {wxEvent, resumePropagation, 1}}, + {2692, {wxEvent, shouldPropagate, 0}}, + {2693, {wxEvent, skip, 1}}, + {2694, {wxEvent, stopPropagation, 0}}, + {2695, {wxCommandEvent, getClientData, 0}}, + {2696, {wxCommandEvent, getExtraLong, 0}}, + {2697, {wxCommandEvent, getInt, 0}}, + {2698, {wxCommandEvent, getSelection, 0}}, + {2699, {wxCommandEvent, getString, 0}}, + {2700, {wxCommandEvent, isChecked, 0}}, + {2701, {wxCommandEvent, isSelection, 0}}, + {2702, {wxCommandEvent, setInt, 1}}, + {2703, {wxCommandEvent, setString, 1}}, + {2704, {wxScrollEvent, getOrientation, 0}}, + {2705, {wxScrollEvent, getPosition, 0}}, + {2706, {wxScrollWinEvent, getOrientation, 0}}, + {2707, {wxScrollWinEvent, getPosition, 0}}, + {2708, {wxMouseEvent, altDown, 0}}, + {2709, {wxMouseEvent, button, 1}}, + {2710, {wxMouseEvent, buttonDClick, 1}}, + {2711, {wxMouseEvent, buttonDown, 1}}, + {2712, {wxMouseEvent, buttonUp, 1}}, + {2713, {wxMouseEvent, cmdDown, 0}}, + {2714, {wxMouseEvent, controlDown, 0}}, + {2715, {wxMouseEvent, dragging, 0}}, + {2716, {wxMouseEvent, entering, 0}}, + {2717, {wxMouseEvent, getButton, 0}}, + {2720, {wxMouseEvent, getPosition, 0}}, + {2721, {wxMouseEvent, getLogicalPosition, 1}}, + {2722, {wxMouseEvent, getLinesPerAction, 0}}, + {2723, {wxMouseEvent, getWheelRotation, 0}}, + {2724, {wxMouseEvent, getWheelDelta, 0}}, + {2725, {wxMouseEvent, getX, 0}}, + {2726, {wxMouseEvent, getY, 0}}, + {2727, {wxMouseEvent, isButton, 0}}, + {2728, {wxMouseEvent, isPageScroll, 0}}, + {2729, {wxMouseEvent, leaving, 0}}, + {2730, {wxMouseEvent, leftDClick, 0}}, + {2731, {wxMouseEvent, leftDown, 0}}, + {2732, {wxMouseEvent, leftIsDown, 0}}, + {2733, {wxMouseEvent, leftUp, 0}}, + {2734, {wxMouseEvent, metaDown, 0}}, + {2735, {wxMouseEvent, middleDClick, 0}}, + {2736, {wxMouseEvent, middleDown, 0}}, + {2737, {wxMouseEvent, middleIsDown, 0}}, + {2738, {wxMouseEvent, middleUp, 0}}, + {2739, {wxMouseEvent, moving, 0}}, + {2740, {wxMouseEvent, rightDClick, 0}}, + {2741, {wxMouseEvent, rightDown, 0}}, + {2742, {wxMouseEvent, rightIsDown, 0}}, + {2743, {wxMouseEvent, rightUp, 0}}, + {2744, {wxMouseEvent, shiftDown, 0}}, + {2745, {wxSetCursorEvent, getCursor, 0}}, + {2746, {wxSetCursorEvent, getX, 0}}, + {2747, {wxSetCursorEvent, getY, 0}}, + {2748, {wxSetCursorEvent, hasCursor, 0}}, + {2749, {wxSetCursorEvent, setCursor, 1}}, + {2750, {wxKeyEvent, altDown, 0}}, + {2751, {wxKeyEvent, cmdDown, 0}}, + {2752, {wxKeyEvent, controlDown, 0}}, + {2753, {wxKeyEvent, getKeyCode, 0}}, + {2754, {wxKeyEvent, getModifiers, 0}}, + {2757, {wxKeyEvent, getPosition, 0}}, + {2758, {wxKeyEvent, getRawKeyCode, 0}}, + {2759, {wxKeyEvent, getRawKeyFlags, 0}}, + {2760, {wxKeyEvent, getUnicodeKey, 0}}, + {2761, {wxKeyEvent, getX, 0}}, + {2762, {wxKeyEvent, getY, 0}}, + {2763, {wxKeyEvent, hasModifiers, 0}}, + {2764, {wxKeyEvent, metaDown, 0}}, + {2765, {wxKeyEvent, shiftDown, 0}}, + {2766, {wxSizeEvent, getSize, 0}}, + {2767, {wxMoveEvent, getPosition, 0}}, + {2768, {wxEraseEvent, getDC, 0}}, + {2769, {wxFocusEvent, getWindow, 0}}, + {2770, {wxChildFocusEvent, getWindow, 0}}, + {2771, {wxMenuEvent, getMenu, 0}}, + {2772, {wxMenuEvent, getMenuId, 0}}, + {2773, {wxMenuEvent, isPopup, 0}}, + {2774, {wxCloseEvent, canVeto, 0}}, + {2775, {wxCloseEvent, getLoggingOff, 0}}, + {2776, {wxCloseEvent, setCanVeto, 1}}, + {2777, {wxCloseEvent, setLoggingOff, 1}}, + {2778, {wxCloseEvent, veto, 1}}, + {2779, {wxShowEvent, setShow, 1}}, + {2780, {wxShowEvent, getShow, 0}}, + {2781, {wxIconizeEvent, iconized, 0}}, + {2782, {wxJoystickEvent, buttonDown, 1}}, + {2783, {wxJoystickEvent, buttonIsDown, 1}}, + {2784, {wxJoystickEvent, buttonUp, 1}}, + {2785, {wxJoystickEvent, getButtonChange, 0}}, + {2786, {wxJoystickEvent, getButtonState, 0}}, + {2787, {wxJoystickEvent, getJoystick, 0}}, + {2788, {wxJoystickEvent, getPosition, 0}}, + {2789, {wxJoystickEvent, getZPosition, 0}}, + {2790, {wxJoystickEvent, isButton, 0}}, + {2791, {wxJoystickEvent, isMove, 0}}, + {2792, {wxJoystickEvent, isZMove, 0}}, + {2793, {wxUpdateUIEvent, canUpdate, 1}}, + {2794, {wxUpdateUIEvent, check, 1}}, + {2795, {wxUpdateUIEvent, enable, 1}}, + {2796, {wxUpdateUIEvent, show, 1}}, + {2797, {wxUpdateUIEvent, getChecked, 0}}, + {2798, {wxUpdateUIEvent, getEnabled, 0}}, + {2799, {wxUpdateUIEvent, getShown, 0}}, + {2800, {wxUpdateUIEvent, getSetChecked, 0}}, + {2801, {wxUpdateUIEvent, getSetEnabled, 0}}, + {2802, {wxUpdateUIEvent, getSetShown, 0}}, + {2803, {wxUpdateUIEvent, getSetText, 0}}, + {2804, {wxUpdateUIEvent, getText, 0}}, + {2805, {wxUpdateUIEvent, getMode, 0}}, + {2806, {wxUpdateUIEvent, getUpdateInterval, 0}}, + {2807, {wxUpdateUIEvent, resetUpdateTime, 0}}, + {2808, {wxUpdateUIEvent, setMode, 1}}, + {2809, {wxUpdateUIEvent, setText, 1}}, + {2810, {wxUpdateUIEvent, setUpdateInterval, 1}}, + {2811, {wxMouseCaptureChangedEvent, getCapturedWindow, 0}}, + {2812, {wxPaletteChangedEvent, setChangedWindow, 1}}, + {2813, {wxPaletteChangedEvent, getChangedWindow, 0}}, + {2814, {wxQueryNewPaletteEvent, setPaletteRealized, 1}}, + {2815, {wxQueryNewPaletteEvent, getPaletteRealized, 0}}, + {2816, {wxNavigationKeyEvent, getDirection, 0}}, + {2817, {wxNavigationKeyEvent, setDirection, 1}}, + {2818, {wxNavigationKeyEvent, isWindowChange, 0}}, + {2819, {wxNavigationKeyEvent, setWindowChange, 1}}, + {2820, {wxNavigationKeyEvent, isFromTab, 0}}, + {2821, {wxNavigationKeyEvent, setFromTab, 1}}, + {2822, {wxNavigationKeyEvent, getCurrentFocus, 0}}, + {2823, {wxNavigationKeyEvent, setCurrentFocus, 1}}, + {2824, {wxHelpEvent, getOrigin, 0}}, + {2825, {wxHelpEvent, getPosition, 0}}, + {2826, {wxHelpEvent, setOrigin, 1}}, + {2827, {wxHelpEvent, setPosition, 1}}, + {2828, {wxContextMenuEvent, getPosition, 0}}, + {2829, {wxContextMenuEvent, setPosition, 1}}, + {2830, {wxIdleEvent, canSend, 1}}, + {2831, {wxIdleEvent, getMode, 0}}, + {2832, {wxIdleEvent, requestMore, 1}}, + {2833, {wxIdleEvent, moreRequested, 0}}, + {2834, {wxIdleEvent, setMode, 1}}, + {2835, {wxGridEvent, altDown, 0}}, + {2836, {wxGridEvent, controlDown, 0}}, + {2837, {wxGridEvent, getCol, 0}}, + {2838, {wxGridEvent, getPosition, 0}}, + {2839, {wxGridEvent, getRow, 0}}, + {2840, {wxGridEvent, metaDown, 0}}, + {2841, {wxGridEvent, selecting, 0}}, + {2842, {wxGridEvent, shiftDown, 0}}, + {2843, {wxNotifyEvent, allow, 0}}, + {2844, {wxNotifyEvent, isAllowed, 0}}, + {2845, {wxNotifyEvent, veto, 0}}, + {2846, {wxSashEvent, getEdge, 0}}, + {2847, {wxSashEvent, getDragRect, 0}}, + {2848, {wxSashEvent, getDragStatus, 0}}, + {2849, {wxListEvent, getCacheFrom, 0}}, + {2850, {wxListEvent, getCacheTo, 0}}, + {2851, {wxListEvent, getKeyCode, 0}}, + {2852, {wxListEvent, getIndex, 0}}, + {2853, {wxListEvent, getColumn, 0}}, + {2854, {wxListEvent, getPoint, 0}}, + {2855, {wxListEvent, getLabel, 0}}, + {2856, {wxListEvent, getText, 0}}, + {2857, {wxListEvent, getImage, 0}}, + {2858, {wxListEvent, getData, 0}}, + {2859, {wxListEvent, getMask, 0}}, + {2860, {wxListEvent, getItem, 0}}, + {2861, {wxListEvent, isEditCancelled, 0}}, + {2862, {wxDateEvent, getDate, 0}}, + {2863, {wxCalendarEvent, getWeekDay, 0}}, + {2864, {wxFileDirPickerEvent, getPath, 0}}, + {2865, {wxColourPickerEvent, getColour, 0}}, + {2866, {wxFontPickerEvent, getFont, 0}}, + {2867, {wxStyledTextEvent, getPosition, 0}}, + {2868, {wxStyledTextEvent, getKey, 0}}, + {2869, {wxStyledTextEvent, getModifiers, 0}}, + {2870, {wxStyledTextEvent, getModificationType, 0}}, + {2871, {wxStyledTextEvent, getText, 0}}, + {2872, {wxStyledTextEvent, getLength, 0}}, + {2873, {wxStyledTextEvent, getLinesAdded, 0}}, + {2874, {wxStyledTextEvent, getLine, 0}}, + {2875, {wxStyledTextEvent, getFoldLevelNow, 0}}, + {2876, {wxStyledTextEvent, getFoldLevelPrev, 0}}, + {2877, {wxStyledTextEvent, getMargin, 0}}, + {2878, {wxStyledTextEvent, getMessage, 0}}, + {2879, {wxStyledTextEvent, getWParam, 0}}, + {2880, {wxStyledTextEvent, getLParam, 0}}, + {2881, {wxStyledTextEvent, getListType, 0}}, + {2882, {wxStyledTextEvent, getX, 0}}, + {2883, {wxStyledTextEvent, getY, 0}}, + {2884, {wxStyledTextEvent, getDragText, 0}}, + {2885, {wxStyledTextEvent, getDragAllowMove, 0}}, + {2886, {wxStyledTextEvent, getDragResult, 0}}, + {2887, {wxStyledTextEvent, getShift, 0}}, + {2888, {wxStyledTextEvent, getControl, 0}}, + {2889, {wxStyledTextEvent, getAlt, 0}}, + {2890, {utils, getKeyState, 1}}, + {2891, {utils, getMousePosition, 2}}, + {2892, {utils, getMouseState, 0}}, + {2893, {utils, setDetectableAutoRepeat, 1}}, + {2894, {utils, bell, 0}}, + {2895, {utils, findMenuItemId, 3}}, + {2896, {utils, genericFindWindowAtPoint, 1}}, + {2897, {utils, findWindowAtPoint, 1}}, + {2898, {utils, beginBusyCursor, 1}}, + {2899, {utils, endBusyCursor, 0}}, + {2900, {utils, isBusy, 0}}, + {2901, {utils, shutdown, 1}}, + {2902, {utils, shell, 1}}, + {2903, {utils, launchDefaultBrowser, 2}}, + {2904, {utils, getEmailAddress, 0}}, + {2905, {utils, getUserId, 0}}, + {2906, {utils, getHomeDir, 0}}, + {2907, {utils, newId, 0}}, + {2908, {utils, registerId, 1}}, + {2909, {utils, getCurrentId, 0}}, + {2910, {utils, getOsDescription, 0}}, + {2911, {utils, isPlatformLittleEndian, 0}}, + {2912, {utils, isPlatform64Bit, 0}}, + {2913, {wxPrintout, new, 1}}, + {2914, {wxPrintout, destruct, 0}}, + {2915, {wxPrintout, getDC, 0}}, + {2916, {wxPrintout, getPageSizeMM, 2}}, + {2917, {wxPrintout, getPageSizePixels, 2}}, + {2918, {wxPrintout, getPaperRectPixels, 0}}, + {2919, {wxPrintout, getPPIPrinter, 2}}, + {2920, {wxPrintout, getPPIScreen, 2}}, + {2921, {wxPrintout, getTitle, 0}}, + {2922, {wxPrintout, isPreview, 0}}, + {2923, {wxPrintout, fitThisSizeToPaper, 1}}, + {2924, {wxPrintout, fitThisSizeToPage, 1}}, + {2925, {wxPrintout, fitThisSizeToPageMargins, 2}}, + {2926, {wxPrintout, mapScreenSizeToPaper, 0}}, + {2927, {wxPrintout, mapScreenSizeToPage, 0}}, + {2928, {wxPrintout, mapScreenSizeToPageMargins, 1}}, + {2929, {wxPrintout, mapScreenSizeToDevice, 0}}, + {2930, {wxPrintout, getLogicalPaperRect, 0}}, + {2931, {wxPrintout, getLogicalPageRect, 0}}, + {2932, {wxPrintout, getLogicalPageMarginsRect, 1}}, + {2933, {wxPrintout, setLogicalOrigin, 2}}, + {2934, {wxPrintout, offsetLogicalOrigin, 2}}, + {2935, {wxStyledTextCtrl, new_2, 2}}, + {2936, {wxStyledTextCtrl, new_0, 0}}, + {2937, {wxStyledTextCtrl, destruct, 0}}, + {2938, {wxStyledTextCtrl, create, 2}}, + {2939, {wxStyledTextCtrl, addText, 1}}, + {2940, {wxStyledTextCtrl, addStyledText, 1}}, + {2941, {wxStyledTextCtrl, insertText, 2}}, + {2942, {wxStyledTextCtrl, clearAll, 0}}, + {2943, {wxStyledTextCtrl, clearDocumentStyle, 0}}, + {2944, {wxStyledTextCtrl, getLength, 0}}, + {2945, {wxStyledTextCtrl, getCharAt, 1}}, + {2946, {wxStyledTextCtrl, getCurrentPos, 0}}, + {2947, {wxStyledTextCtrl, getAnchor, 0}}, + {2948, {wxStyledTextCtrl, getStyleAt, 1}}, + {2949, {wxStyledTextCtrl, redo, 0}}, + {2950, {wxStyledTextCtrl, setUndoCollection, 1}}, + {2951, {wxStyledTextCtrl, selectAll, 0}}, + {2952, {wxStyledTextCtrl, setSavePoint, 0}}, + {2953, {wxStyledTextCtrl, getStyledText, 2}}, + {2954, {wxStyledTextCtrl, canRedo, 0}}, + {2955, {wxStyledTextCtrl, markerLineFromHandle, 1}}, + {2956, {wxStyledTextCtrl, markerDeleteHandle, 1}}, + {2957, {wxStyledTextCtrl, getUndoCollection, 0}}, + {2958, {wxStyledTextCtrl, getViewWhiteSpace, 0}}, + {2959, {wxStyledTextCtrl, setViewWhiteSpace, 1}}, + {2960, {wxStyledTextCtrl, positionFromPoint, 1}}, + {2961, {wxStyledTextCtrl, positionFromPointClose, 2}}, + {2962, {wxStyledTextCtrl, gotoLine, 1}}, + {2963, {wxStyledTextCtrl, gotoPos, 1}}, + {2964, {wxStyledTextCtrl, setAnchor, 1}}, + {2965, {wxStyledTextCtrl, getCurLine, 1}}, + {2966, {wxStyledTextCtrl, getEndStyled, 0}}, + {2967, {wxStyledTextCtrl, convertEOLs, 1}}, + {2968, {wxStyledTextCtrl, getEOLMode, 0}}, + {2969, {wxStyledTextCtrl, setEOLMode, 1}}, + {2970, {wxStyledTextCtrl, startStyling, 2}}, + {2971, {wxStyledTextCtrl, setStyling, 2}}, + {2972, {wxStyledTextCtrl, getBufferedDraw, 0}}, + {2973, {wxStyledTextCtrl, setBufferedDraw, 1}}, + {2974, {wxStyledTextCtrl, setTabWidth, 1}}, + {2975, {wxStyledTextCtrl, getTabWidth, 0}}, + {2976, {wxStyledTextCtrl, setCodePage, 1}}, + {2977, {wxStyledTextCtrl, markerDefine, 3}}, + {2978, {wxStyledTextCtrl, markerSetForeground, 2}}, + {2979, {wxStyledTextCtrl, markerSetBackground, 2}}, + {2980, {wxStyledTextCtrl, markerAdd, 2}}, + {2981, {wxStyledTextCtrl, markerDelete, 2}}, + {2982, {wxStyledTextCtrl, markerDeleteAll, 1}}, + {2983, {wxStyledTextCtrl, markerGet, 1}}, + {2984, {wxStyledTextCtrl, markerNext, 2}}, + {2985, {wxStyledTextCtrl, markerPrevious, 2}}, + {2986, {wxStyledTextCtrl, markerDefineBitmap, 2}}, + {2987, {wxStyledTextCtrl, markerAddSet, 2}}, + {2988, {wxStyledTextCtrl, markerSetAlpha, 2}}, + {2989, {wxStyledTextCtrl, setMarginType, 2}}, + {2990, {wxStyledTextCtrl, getMarginType, 1}}, + {2991, {wxStyledTextCtrl, setMarginWidth, 2}}, + {2992, {wxStyledTextCtrl, getMarginWidth, 1}}, + {2993, {wxStyledTextCtrl, setMarginMask, 2}}, + {2994, {wxStyledTextCtrl, getMarginMask, 1}}, + {2995, {wxStyledTextCtrl, setMarginSensitive, 2}}, + {2996, {wxStyledTextCtrl, getMarginSensitive, 1}}, + {2997, {wxStyledTextCtrl, styleClearAll, 0}}, + {2998, {wxStyledTextCtrl, styleSetForeground, 2}}, + {2999, {wxStyledTextCtrl, styleSetBackground, 2}}, + {3000, {wxStyledTextCtrl, styleSetBold, 2}}, + {3001, {wxStyledTextCtrl, styleSetItalic, 2}}, + {3002, {wxStyledTextCtrl, styleSetSize, 2}}, + {3003, {wxStyledTextCtrl, styleSetFaceName, 2}}, + {3004, {wxStyledTextCtrl, styleSetEOLFilled, 2}}, + {3005, {wxStyledTextCtrl, styleResetDefault, 0}}, + {3006, {wxStyledTextCtrl, styleSetUnderline, 2}}, + {3007, {wxStyledTextCtrl, styleSetCase, 2}}, + {3008, {wxStyledTextCtrl, styleSetHotSpot, 2}}, + {3009, {wxStyledTextCtrl, setSelForeground, 2}}, + {3010, {wxStyledTextCtrl, setSelBackground, 2}}, + {3011, {wxStyledTextCtrl, getSelAlpha, 0}}, + {3012, {wxStyledTextCtrl, setSelAlpha, 1}}, + {3013, {wxStyledTextCtrl, setCaretForeground, 1}}, + {3014, {wxStyledTextCtrl, cmdKeyAssign, 3}}, + {3015, {wxStyledTextCtrl, cmdKeyClear, 2}}, + {3016, {wxStyledTextCtrl, cmdKeyClearAll, 0}}, + {3017, {wxStyledTextCtrl, setStyleBytes, 2}}, + {3018, {wxStyledTextCtrl, styleSetVisible, 2}}, + {3019, {wxStyledTextCtrl, getCaretPeriod, 0}}, + {3020, {wxStyledTextCtrl, setCaretPeriod, 1}}, + {3021, {wxStyledTextCtrl, setWordChars, 1}}, + {3022, {wxStyledTextCtrl, beginUndoAction, 0}}, + {3023, {wxStyledTextCtrl, endUndoAction, 0}}, + {3024, {wxStyledTextCtrl, indicatorSetStyle, 2}}, + {3025, {wxStyledTextCtrl, indicatorGetStyle, 1}}, + {3026, {wxStyledTextCtrl, indicatorSetForeground, 2}}, + {3027, {wxStyledTextCtrl, indicatorGetForeground, 1}}, + {3028, {wxStyledTextCtrl, setWhitespaceForeground, 2}}, + {3029, {wxStyledTextCtrl, setWhitespaceBackground, 2}}, + {3030, {wxStyledTextCtrl, getStyleBits, 0}}, + {3031, {wxStyledTextCtrl, setLineState, 2}}, + {3032, {wxStyledTextCtrl, getLineState, 1}}, + {3033, {wxStyledTextCtrl, getMaxLineState, 0}}, + {3034, {wxStyledTextCtrl, getCaretLineVisible, 0}}, + {3035, {wxStyledTextCtrl, setCaretLineVisible, 1}}, + {3036, {wxStyledTextCtrl, getCaretLineBackground, 0}}, + {3037, {wxStyledTextCtrl, setCaretLineBackground, 1}}, + {3038, {wxStyledTextCtrl, autoCompShow, 2}}, + {3039, {wxStyledTextCtrl, autoCompCancel, 0}}, + {3040, {wxStyledTextCtrl, autoCompActive, 0}}, + {3041, {wxStyledTextCtrl, autoCompPosStart, 0}}, + {3042, {wxStyledTextCtrl, autoCompComplete, 0}}, + {3043, {wxStyledTextCtrl, autoCompStops, 1}}, + {3044, {wxStyledTextCtrl, autoCompSetSeparator, 1}}, + {3045, {wxStyledTextCtrl, autoCompGetSeparator, 0}}, + {3046, {wxStyledTextCtrl, autoCompSelect, 1}}, + {3047, {wxStyledTextCtrl, autoCompSetCancelAtStart, 1}}, + {3048, {wxStyledTextCtrl, autoCompGetCancelAtStart, 0}}, + {3049, {wxStyledTextCtrl, autoCompSetFillUps, 1}}, + {3050, {wxStyledTextCtrl, autoCompSetChooseSingle, 1}}, + {3051, {wxStyledTextCtrl, autoCompGetChooseSingle, 0}}, + {3052, {wxStyledTextCtrl, autoCompSetIgnoreCase, 1}}, + {3053, {wxStyledTextCtrl, autoCompGetIgnoreCase, 0}}, + {3054, {wxStyledTextCtrl, userListShow, 2}}, + {3055, {wxStyledTextCtrl, autoCompSetAutoHide, 1}}, + {3056, {wxStyledTextCtrl, autoCompGetAutoHide, 0}}, + {3057, {wxStyledTextCtrl, autoCompSetDropRestOfWord, 1}}, + {3058, {wxStyledTextCtrl, autoCompGetDropRestOfWord, 0}}, + {3059, {wxStyledTextCtrl, registerImage, 2}}, + {3060, {wxStyledTextCtrl, clearRegisteredImages, 0}}, + {3061, {wxStyledTextCtrl, autoCompGetTypeSeparator, 0}}, + {3062, {wxStyledTextCtrl, autoCompSetTypeSeparator, 1}}, + {3063, {wxStyledTextCtrl, autoCompSetMaxWidth, 1}}, + {3064, {wxStyledTextCtrl, autoCompGetMaxWidth, 0}}, + {3065, {wxStyledTextCtrl, autoCompSetMaxHeight, 1}}, + {3066, {wxStyledTextCtrl, autoCompGetMaxHeight, 0}}, + {3067, {wxStyledTextCtrl, setIndent, 1}}, + {3068, {wxStyledTextCtrl, getIndent, 0}}, + {3069, {wxStyledTextCtrl, setUseTabs, 1}}, + {3070, {wxStyledTextCtrl, getUseTabs, 0}}, + {3071, {wxStyledTextCtrl, setLineIndentation, 2}}, + {3072, {wxStyledTextCtrl, getLineIndentation, 1}}, + {3073, {wxStyledTextCtrl, getLineIndentPosition, 1}}, + {3074, {wxStyledTextCtrl, getColumn, 1}}, + {3075, {wxStyledTextCtrl, setUseHorizontalScrollBar, 1}}, + {3076, {wxStyledTextCtrl, getUseHorizontalScrollBar, 0}}, + {3077, {wxStyledTextCtrl, setIndentationGuides, 1}}, + {3078, {wxStyledTextCtrl, getIndentationGuides, 0}}, + {3079, {wxStyledTextCtrl, setHighlightGuide, 1}}, + {3080, {wxStyledTextCtrl, getHighlightGuide, 0}}, + {3081, {wxStyledTextCtrl, getLineEndPosition, 1}}, + {3082, {wxStyledTextCtrl, getCodePage, 0}}, + {3083, {wxStyledTextCtrl, getCaretForeground, 0}}, + {3084, {wxStyledTextCtrl, getReadOnly, 0}}, + {3085, {wxStyledTextCtrl, setCurrentPos, 1}}, + {3086, {wxStyledTextCtrl, setSelectionStart, 1}}, + {3087, {wxStyledTextCtrl, getSelectionStart, 0}}, + {3088, {wxStyledTextCtrl, setSelectionEnd, 1}}, + {3089, {wxStyledTextCtrl, getSelectionEnd, 0}}, + {3090, {wxStyledTextCtrl, setPrintMagnification, 1}}, + {3091, {wxStyledTextCtrl, getPrintMagnification, 0}}, + {3092, {wxStyledTextCtrl, setPrintColourMode, 1}}, + {3093, {wxStyledTextCtrl, getPrintColourMode, 0}}, + {3094, {wxStyledTextCtrl, findText, 4}}, + {3095, {wxStyledTextCtrl, formatRange, 7}}, + {3096, {wxStyledTextCtrl, getFirstVisibleLine, 0}}, + {3097, {wxStyledTextCtrl, getLine, 1}}, + {3098, {wxStyledTextCtrl, getLineCount, 0}}, + {3099, {wxStyledTextCtrl, setMarginLeft, 1}}, + {3100, {wxStyledTextCtrl, getMarginLeft, 0}}, + {3101, {wxStyledTextCtrl, setMarginRight, 1}}, + {3102, {wxStyledTextCtrl, getMarginRight, 0}}, + {3103, {wxStyledTextCtrl, getModify, 0}}, + {3104, {wxStyledTextCtrl, setSelection, 2}}, + {3105, {wxStyledTextCtrl, getSelectedText, 0}}, + {3106, {wxStyledTextCtrl, getTextRange, 2}}, + {3107, {wxStyledTextCtrl, hideSelection, 1}}, + {3108, {wxStyledTextCtrl, lineFromPosition, 1}}, + {3109, {wxStyledTextCtrl, positionFromLine, 1}}, + {3110, {wxStyledTextCtrl, lineScroll, 2}}, + {3111, {wxStyledTextCtrl, ensureCaretVisible, 0}}, + {3112, {wxStyledTextCtrl, replaceSelection, 1}}, + {3113, {wxStyledTextCtrl, setReadOnly, 1}}, + {3114, {wxStyledTextCtrl, canPaste, 0}}, + {3115, {wxStyledTextCtrl, canUndo, 0}}, + {3116, {wxStyledTextCtrl, emptyUndoBuffer, 0}}, + {3117, {wxStyledTextCtrl, undo, 0}}, + {3118, {wxStyledTextCtrl, cut, 0}}, + {3119, {wxStyledTextCtrl, copy, 0}}, + {3120, {wxStyledTextCtrl, paste, 0}}, + {3121, {wxStyledTextCtrl, clear, 0}}, + {3122, {wxStyledTextCtrl, setText, 1}}, + {3123, {wxStyledTextCtrl, getText, 0}}, + {3124, {wxStyledTextCtrl, getTextLength, 0}}, + {3125, {wxStyledTextCtrl, getOvertype, 0}}, + {3126, {wxStyledTextCtrl, setCaretWidth, 1}}, + {3127, {wxStyledTextCtrl, getCaretWidth, 0}}, + {3128, {wxStyledTextCtrl, setTargetStart, 1}}, + {3129, {wxStyledTextCtrl, getTargetStart, 0}}, + {3130, {wxStyledTextCtrl, setTargetEnd, 1}}, + {3131, {wxStyledTextCtrl, getTargetEnd, 0}}, + {3132, {wxStyledTextCtrl, replaceTarget, 1}}, + {3133, {wxStyledTextCtrl, searchInTarget, 1}}, + {3134, {wxStyledTextCtrl, setSearchFlags, 1}}, + {3135, {wxStyledTextCtrl, getSearchFlags, 0}}, + {3136, {wxStyledTextCtrl, callTipShow, 2}}, + {3137, {wxStyledTextCtrl, callTipCancel, 0}}, + {3138, {wxStyledTextCtrl, callTipActive, 0}}, + {3139, {wxStyledTextCtrl, callTipPosAtStart, 0}}, + {3140, {wxStyledTextCtrl, callTipSetHighlight, 2}}, + {3141, {wxStyledTextCtrl, callTipSetBackground, 1}}, + {3142, {wxStyledTextCtrl, callTipSetForeground, 1}}, + {3143, {wxStyledTextCtrl, callTipSetForegroundHighlight, 1}}, + {3144, {wxStyledTextCtrl, callTipUseStyle, 1}}, + {3145, {wxStyledTextCtrl, visibleFromDocLine, 1}}, + {3146, {wxStyledTextCtrl, docLineFromVisible, 1}}, + {3147, {wxStyledTextCtrl, wrapCount, 1}}, + {3148, {wxStyledTextCtrl, setFoldLevel, 2}}, + {3149, {wxStyledTextCtrl, getFoldLevel, 1}}, + {3150, {wxStyledTextCtrl, getLastChild, 2}}, + {3151, {wxStyledTextCtrl, getFoldParent, 1}}, + {3152, {wxStyledTextCtrl, showLines, 2}}, + {3153, {wxStyledTextCtrl, hideLines, 2}}, + {3154, {wxStyledTextCtrl, getLineVisible, 1}}, + {3155, {wxStyledTextCtrl, setFoldExpanded, 2}}, + {3156, {wxStyledTextCtrl, getFoldExpanded, 1}}, + {3157, {wxStyledTextCtrl, toggleFold, 1}}, + {3158, {wxStyledTextCtrl, ensureVisible, 1}}, + {3159, {wxStyledTextCtrl, setFoldFlags, 1}}, + {3160, {wxStyledTextCtrl, ensureVisibleEnforcePolicy, 1}}, + {3161, {wxStyledTextCtrl, setTabIndents, 1}}, + {3162, {wxStyledTextCtrl, getTabIndents, 0}}, + {3163, {wxStyledTextCtrl, setBackSpaceUnIndents, 1}}, + {3164, {wxStyledTextCtrl, getBackSpaceUnIndents, 0}}, + {3165, {wxStyledTextCtrl, setMouseDwellTime, 1}}, + {3166, {wxStyledTextCtrl, getMouseDwellTime, 0}}, + {3167, {wxStyledTextCtrl, wordStartPosition, 2}}, + {3168, {wxStyledTextCtrl, wordEndPosition, 2}}, + {3169, {wxStyledTextCtrl, setWrapMode, 1}}, + {3170, {wxStyledTextCtrl, getWrapMode, 0}}, + {3171, {wxStyledTextCtrl, setWrapVisualFlags, 1}}, + {3172, {wxStyledTextCtrl, getWrapVisualFlags, 0}}, + {3173, {wxStyledTextCtrl, setWrapVisualFlagsLocation, 1}}, + {3174, {wxStyledTextCtrl, getWrapVisualFlagsLocation, 0}}, + {3175, {wxStyledTextCtrl, setWrapStartIndent, 1}}, + {3176, {wxStyledTextCtrl, getWrapStartIndent, 0}}, + {3177, {wxStyledTextCtrl, setLayoutCache, 1}}, + {3178, {wxStyledTextCtrl, getLayoutCache, 0}}, + {3179, {wxStyledTextCtrl, setScrollWidth, 1}}, + {3180, {wxStyledTextCtrl, getScrollWidth, 0}}, + {3181, {wxStyledTextCtrl, textWidth, 2}}, + {3182, {wxStyledTextCtrl, getEndAtLastLine, 0}}, + {3183, {wxStyledTextCtrl, textHeight, 1}}, + {3184, {wxStyledTextCtrl, setUseVerticalScrollBar, 1}}, + {3185, {wxStyledTextCtrl, getUseVerticalScrollBar, 0}}, + {3186, {wxStyledTextCtrl, appendText, 1}}, + {3187, {wxStyledTextCtrl, getTwoPhaseDraw, 0}}, + {3188, {wxStyledTextCtrl, setTwoPhaseDraw, 1}}, + {3189, {wxStyledTextCtrl, targetFromSelection, 0}}, + {3190, {wxStyledTextCtrl, linesJoin, 0}}, + {3191, {wxStyledTextCtrl, linesSplit, 1}}, + {3192, {wxStyledTextCtrl, setFoldMarginColour, 2}}, + {3193, {wxStyledTextCtrl, setFoldMarginHiColour, 2}}, + {3194, {wxStyledTextCtrl, lineDown, 0}}, + {3195, {wxStyledTextCtrl, lineDownExtend, 0}}, + {3196, {wxStyledTextCtrl, lineUp, 0}}, + {3197, {wxStyledTextCtrl, lineUpExtend, 0}}, + {3198, {wxStyledTextCtrl, charLeft, 0}}, + {3199, {wxStyledTextCtrl, charLeftExtend, 0}}, + {3200, {wxStyledTextCtrl, charRight, 0}}, + {3201, {wxStyledTextCtrl, charRightExtend, 0}}, + {3202, {wxStyledTextCtrl, wordLeft, 0}}, + {3203, {wxStyledTextCtrl, wordLeftExtend, 0}}, + {3204, {wxStyledTextCtrl, wordRight, 0}}, + {3205, {wxStyledTextCtrl, wordRightExtend, 0}}, + {3206, {wxStyledTextCtrl, home, 0}}, + {3207, {wxStyledTextCtrl, homeExtend, 0}}, + {3208, {wxStyledTextCtrl, lineEnd, 0}}, + {3209, {wxStyledTextCtrl, lineEndExtend, 0}}, + {3210, {wxStyledTextCtrl, documentStart, 0}}, + {3211, {wxStyledTextCtrl, documentStartExtend, 0}}, + {3212, {wxStyledTextCtrl, documentEnd, 0}}, + {3213, {wxStyledTextCtrl, documentEndExtend, 0}}, + {3214, {wxStyledTextCtrl, pageUp, 0}}, + {3215, {wxStyledTextCtrl, pageUpExtend, 0}}, + {3216, {wxStyledTextCtrl, pageDown, 0}}, + {3217, {wxStyledTextCtrl, pageDownExtend, 0}}, + {3218, {wxStyledTextCtrl, editToggleOvertype, 0}}, + {3219, {wxStyledTextCtrl, cancel, 0}}, + {3220, {wxStyledTextCtrl, deleteBack, 0}}, + {3221, {wxStyledTextCtrl, tab, 0}}, + {3222, {wxStyledTextCtrl, backTab, 0}}, + {3223, {wxStyledTextCtrl, newLine, 0}}, + {3224, {wxStyledTextCtrl, formFeed, 0}}, + {3225, {wxStyledTextCtrl, vCHome, 0}}, + {3226, {wxStyledTextCtrl, vCHomeExtend, 0}}, + {3227, {wxStyledTextCtrl, zoomIn, 0}}, + {3228, {wxStyledTextCtrl, zoomOut, 0}}, + {3229, {wxStyledTextCtrl, delWordLeft, 0}}, + {3230, {wxStyledTextCtrl, delWordRight, 0}}, + {3231, {wxStyledTextCtrl, lineCut, 0}}, + {3232, {wxStyledTextCtrl, lineDelete, 0}}, + {3233, {wxStyledTextCtrl, lineTranspose, 0}}, + {3234, {wxStyledTextCtrl, lineDuplicate, 0}}, + {3235, {wxStyledTextCtrl, lowerCase, 0}}, + {3236, {wxStyledTextCtrl, upperCase, 0}}, + {3237, {wxStyledTextCtrl, lineScrollDown, 0}}, + {3238, {wxStyledTextCtrl, lineScrollUp, 0}}, + {3239, {wxStyledTextCtrl, deleteBackNotLine, 0}}, + {3240, {wxStyledTextCtrl, homeDisplay, 0}}, + {3241, {wxStyledTextCtrl, homeDisplayExtend, 0}}, + {3242, {wxStyledTextCtrl, lineEndDisplay, 0}}, + {3243, {wxStyledTextCtrl, lineEndDisplayExtend, 0}}, + {3244, {wxStyledTextCtrl, homeWrapExtend, 0}}, + {3245, {wxStyledTextCtrl, lineEndWrap, 0}}, + {3246, {wxStyledTextCtrl, lineEndWrapExtend, 0}}, + {3247, {wxStyledTextCtrl, vCHomeWrap, 0}}, + {3248, {wxStyledTextCtrl, vCHomeWrapExtend, 0}}, + {3249, {wxStyledTextCtrl, lineCopy, 0}}, + {3250, {wxStyledTextCtrl, moveCaretInsideView, 0}}, + {3251, {wxStyledTextCtrl, lineLength, 1}}, + {3252, {wxStyledTextCtrl, braceHighlight, 2}}, + {3253, {wxStyledTextCtrl, braceBadLight, 1}}, + {3254, {wxStyledTextCtrl, braceMatch, 1}}, + {3255, {wxStyledTextCtrl, getViewEOL, 0}}, + {3256, {wxStyledTextCtrl, setViewEOL, 1}}, + {3257, {wxStyledTextCtrl, setModEventMask, 1}}, + {3258, {wxStyledTextCtrl, getEdgeColumn, 0}}, + {3259, {wxStyledTextCtrl, setEdgeColumn, 1}}, + {3260, {wxStyledTextCtrl, getEdgeMode, 0}}, + {3261, {wxStyledTextCtrl, getEdgeColour, 0}}, + {3262, {wxStyledTextCtrl, setEdgeColour, 1}}, + {3263, {wxStyledTextCtrl, searchAnchor, 0}}, + {3264, {wxStyledTextCtrl, searchNext, 2}}, + {3265, {wxStyledTextCtrl, searchPrev, 2}}, + {3266, {wxStyledTextCtrl, linesOnScreen, 0}}, + {3267, {wxStyledTextCtrl, usePopUp, 1}}, + {3268, {wxStyledTextCtrl, selectionIsRectangle, 0}}, + {3269, {wxStyledTextCtrl, setZoom, 1}}, + {3270, {wxStyledTextCtrl, getZoom, 0}}, + {3271, {wxStyledTextCtrl, getModEventMask, 0}}, + {3272, {wxStyledTextCtrl, setSTCFocus, 1}}, + {3273, {wxStyledTextCtrl, getSTCFocus, 0}}, + {3274, {wxStyledTextCtrl, setStatus, 1}}, + {3275, {wxStyledTextCtrl, getStatus, 0}}, + {3276, {wxStyledTextCtrl, setMouseDownCaptures, 1}}, + {3277, {wxStyledTextCtrl, getMouseDownCaptures, 0}}, + {3278, {wxStyledTextCtrl, setSTCCursor, 1}}, + {3279, {wxStyledTextCtrl, getSTCCursor, 0}}, + {3280, {wxStyledTextCtrl, setControlCharSymbol, 1}}, + {3281, {wxStyledTextCtrl, getControlCharSymbol, 0}}, + {3282, {wxStyledTextCtrl, wordPartLeft, 0}}, + {3283, {wxStyledTextCtrl, wordPartLeftExtend, 0}}, + {3284, {wxStyledTextCtrl, wordPartRight, 0}}, + {3285, {wxStyledTextCtrl, wordPartRightExtend, 0}}, + {3286, {wxStyledTextCtrl, setVisiblePolicy, 2}}, + {3287, {wxStyledTextCtrl, delLineLeft, 0}}, + {3288, {wxStyledTextCtrl, delLineRight, 0}}, + {3289, {wxStyledTextCtrl, getXOffset, 0}}, + {3290, {wxStyledTextCtrl, chooseCaretX, 0}}, + {3291, {wxStyledTextCtrl, setXCaretPolicy, 2}}, + {3292, {wxStyledTextCtrl, setYCaretPolicy, 2}}, + {3293, {wxStyledTextCtrl, getPrintWrapMode, 0}}, + {3294, {wxStyledTextCtrl, setHotspotActiveForeground, 2}}, + {3295, {wxStyledTextCtrl, setHotspotActiveBackground, 2}}, + {3296, {wxStyledTextCtrl, setHotspotActiveUnderline, 1}}, + {3297, {wxStyledTextCtrl, setHotspotSingleLine, 1}}, + {3298, {wxStyledTextCtrl, paraDownExtend, 0}}, + {3299, {wxStyledTextCtrl, paraUp, 0}}, + {3300, {wxStyledTextCtrl, paraUpExtend, 0}}, + {3301, {wxStyledTextCtrl, positionBefore, 1}}, + {3302, {wxStyledTextCtrl, positionAfter, 1}}, + {3303, {wxStyledTextCtrl, copyRange, 2}}, + {3304, {wxStyledTextCtrl, copyText, 2}}, + {3305, {wxStyledTextCtrl, setSelectionMode, 1}}, + {3306, {wxStyledTextCtrl, getSelectionMode, 0}}, + {3307, {wxStyledTextCtrl, lineDownRectExtend, 0}}, + {3308, {wxStyledTextCtrl, lineUpRectExtend, 0}}, + {3309, {wxStyledTextCtrl, charLeftRectExtend, 0}}, + {3310, {wxStyledTextCtrl, charRightRectExtend, 0}}, + {3311, {wxStyledTextCtrl, homeRectExtend, 0}}, + {3312, {wxStyledTextCtrl, vCHomeRectExtend, 0}}, + {3313, {wxStyledTextCtrl, lineEndRectExtend, 0}}, + {3314, {wxStyledTextCtrl, pageUpRectExtend, 0}}, + {3315, {wxStyledTextCtrl, pageDownRectExtend, 0}}, + {3316, {wxStyledTextCtrl, stutteredPageUp, 0}}, + {3317, {wxStyledTextCtrl, stutteredPageUpExtend, 0}}, + {3318, {wxStyledTextCtrl, stutteredPageDown, 0}}, + {3319, {wxStyledTextCtrl, stutteredPageDownExtend, 0}}, + {3320, {wxStyledTextCtrl, wordLeftEnd, 0}}, + {3321, {wxStyledTextCtrl, wordLeftEndExtend, 0}}, + {3322, {wxStyledTextCtrl, wordRightEnd, 0}}, + {3323, {wxStyledTextCtrl, wordRightEndExtend, 0}}, + {3324, {wxStyledTextCtrl, setWhitespaceChars, 1}}, + {3325, {wxStyledTextCtrl, setCharsDefault, 0}}, + {3326, {wxStyledTextCtrl, autoCompGetCurrent, 0}}, + {3327, {wxStyledTextCtrl, allocate, 1}}, + {3328, {wxStyledTextCtrl, findColumn, 2}}, + {3329, {wxStyledTextCtrl, getCaretSticky, 0}}, + {3330, {wxStyledTextCtrl, setCaretSticky, 1}}, + {3331, {wxStyledTextCtrl, toggleCaretSticky, 0}}, + {3332, {wxStyledTextCtrl, setPasteConvertEndings, 1}}, + {3333, {wxStyledTextCtrl, getPasteConvertEndings, 0}}, + {3334, {wxStyledTextCtrl, selectionDuplicate, 0}}, + {3335, {wxStyledTextCtrl, setCaretLineBackAlpha, 1}}, + {3336, {wxStyledTextCtrl, getCaretLineBackAlpha, 0}}, + {3337, {wxStyledTextCtrl, startRecord, 0}}, + {3338, {wxStyledTextCtrl, stopRecord, 0}}, + {3339, {wxStyledTextCtrl, setLexer, 1}}, + {3340, {wxStyledTextCtrl, getLexer, 0}}, + {3341, {wxStyledTextCtrl, colourise, 2}}, + {3342, {wxStyledTextCtrl, setProperty, 2}}, + {3343, {wxStyledTextCtrl, setKeyWords, 2}}, + {3344, {wxStyledTextCtrl, setLexerLanguage, 1}}, + {3345, {wxStyledTextCtrl, getProperty, 1}}, + {3346, {wxStyledTextCtrl, getStyleBitsNeeded, 0}}, + {3347, {wxStyledTextCtrl, getCurrentLine, 0}}, + {3348, {wxStyledTextCtrl, styleSetSpec, 2}}, + {3349, {wxStyledTextCtrl, styleSetFont, 2}}, + {3350, {wxStyledTextCtrl, styleSetFontAttr, 7}}, + {3351, {wxStyledTextCtrl, styleSetCharacterSet, 2}}, + {3352, {wxStyledTextCtrl, styleSetFontEncoding, 2}}, + {3353, {wxStyledTextCtrl, cmdKeyExecute, 1}}, + {3354, {wxStyledTextCtrl, setMargins, 2}}, + {3355, {wxStyledTextCtrl, getSelection, 2}}, + {3356, {wxStyledTextCtrl, pointFromPosition, 1}}, + {3357, {wxStyledTextCtrl, scrollToLine, 1}}, + {3358, {wxStyledTextCtrl, scrollToColumn, 1}}, + {3359, {wxStyledTextCtrl, sendMsg, 2}}, + {3360, {wxStyledTextCtrl, setVScrollBar, 1}}, + {3361, {wxStyledTextCtrl, setHScrollBar, 1}}, + {3362, {wxStyledTextCtrl, getLastKeydownProcessed, 0}}, + {3363, {wxStyledTextCtrl, setLastKeydownProcessed, 1}}, + {3364, {wxStyledTextCtrl, saveFile, 1}}, + {3365, {wxStyledTextCtrl, loadFile, 1}}, + {3366, {wxStyledTextCtrl, doDragOver, 3}}, + {3367, {wxStyledTextCtrl, doDropText, 3}}, + {3368, {wxStyledTextCtrl, getUseAntiAliasing, 0}}, + {3369, {wxStyledTextCtrl, addTextRaw, 1}}, + {3370, {wxStyledTextCtrl, insertTextRaw, 2}}, + {3371, {wxStyledTextCtrl, getCurLineRaw, 1}}, + {3372, {wxStyledTextCtrl, getLineRaw, 1}}, + {3373, {wxStyledTextCtrl, getSelectedTextRaw, 0}}, + {3374, {wxStyledTextCtrl, getTextRangeRaw, 2}}, + {3375, {wxStyledTextCtrl, setTextRaw, 1}}, + {3376, {wxStyledTextCtrl, getTextRaw, 0}}, + {3377, {wxStyledTextCtrl, appendTextRaw, 1}}, + {3378, {wxArtProvider, getBitmap, 2}}, + {3379, {wxArtProvider, getIcon, 2}}, + {3380, {wxTreeEvent, getKeyCode, 0}}, + {3381, {wxTreeEvent, getItem, 0}}, + {3382, {wxTreeEvent, getKeyEvent, 0}}, + {3383, {wxTreeEvent, getLabel, 0}}, + {3384, {wxTreeEvent, getOldItem, 0}}, + {3385, {wxTreeEvent, getPoint, 0}}, + {3386, {wxTreeEvent, isEditCancelled, 0}}, + {3387, {wxTreeEvent, setToolTip, 1}}, + {3388, {wxNotebookEvent, getOldSelection, 0}}, + {3389, {wxNotebookEvent, getSelection, 0}}, + {3390, {wxNotebookEvent, setOldSelection, 1}}, + {3391, {wxNotebookEvent, setSelection, 1}}, + {3392, {wxFileDataObject, new, 0}}, + {3393, {wxFileDataObject, addFile, 1}}, + {3394, {wxFileDataObject, getFilenames, 0}}, + {3395, {wxFileDataObject, 'Destroy', undefined}}, + {3396, {wxTextDataObject, new, 1}}, + {3397, {wxTextDataObject, getTextLength, 0}}, + {3398, {wxTextDataObject, getText, 0}}, + {3399, {wxTextDataObject, setText, 1}}, + {3400, {wxTextDataObject, 'Destroy', undefined}}, + {3401, {wxBitmapDataObject, new_1_1, 1}}, + {3402, {wxBitmapDataObject, new_1_0, 1}}, + {3403, {wxBitmapDataObject, getBitmap, 0}}, + {3404, {wxBitmapDataObject, setBitmap, 1}}, + {3405, {wxBitmapDataObject, 'Destroy', undefined}}, + {3407, {wxClipboard, new, 0}}, + {3408, {wxClipboard, destruct, 0}}, + {3409, {wxClipboard, addData, 1}}, + {3410, {wxClipboard, clear, 0}}, + {3411, {wxClipboard, close, 0}}, + {3412, {wxClipboard, flush, 0}}, + {3413, {wxClipboard, getData, 1}}, + {3414, {wxClipboard, isOpened, 0}}, + {3415, {wxClipboard, open, 0}}, + {3416, {wxClipboard, setData, 1}}, + {3418, {wxClipboard, usePrimarySelection, 1}}, + {3419, {wxClipboard, isSupported, 1}}, + {3420, {wxClipboard, get, 0}}, + {3421, {wxSpinEvent, getPosition, 0}}, + {3422, {wxSpinEvent, setPosition, 1}}, + {3423, {wxSplitterWindow, new_0, 0}}, + {3424, {wxSplitterWindow, new_2, 2}}, + {3425, {wxSplitterWindow, destruct, 0}}, + {3426, {wxSplitterWindow, create, 2}}, + {3427, {wxSplitterWindow, getMinimumPaneSize, 0}}, + {3428, {wxSplitterWindow, getSashGravity, 0}}, + {3429, {wxSplitterWindow, getSashPosition, 0}}, + {3430, {wxSplitterWindow, getSplitMode, 0}}, + {3431, {wxSplitterWindow, getWindow1, 0}}, + {3432, {wxSplitterWindow, getWindow2, 0}}, + {3433, {wxSplitterWindow, initialize, 1}}, + {3434, {wxSplitterWindow, isSplit, 0}}, + {3435, {wxSplitterWindow, replaceWindow, 2}}, + {3436, {wxSplitterWindow, setSashGravity, 1}}, + {3437, {wxSplitterWindow, setSashPosition, 2}}, + {3438, {wxSplitterWindow, setSashSize, 1}}, + {3439, {wxSplitterWindow, setMinimumPaneSize, 1}}, + {3440, {wxSplitterWindow, setSplitMode, 1}}, + {3441, {wxSplitterWindow, splitHorizontally, 3}}, + {3442, {wxSplitterWindow, splitVertically, 3}}, + {3443, {wxSplitterWindow, unsplit, 1}}, + {3444, {wxSplitterWindow, updateSize, 0}}, + {3445, {wxSplitterEvent, getSashPosition, 0}}, + {3446, {wxSplitterEvent, getX, 0}}, + {3447, {wxSplitterEvent, getY, 0}}, + {3448, {wxSplitterEvent, getWindowBeingRemoved, 0}}, + {3449, {wxSplitterEvent, setSashPosition, 1}}, + {3450, {wxHtmlWindow, new_0, 0}}, + {3451, {wxHtmlWindow, new_2, 2}}, + {3452, {wxHtmlWindow, appendToPage, 1}}, + {3453, {wxHtmlWindow, getOpenedAnchor, 0}}, + {3454, {wxHtmlWindow, getOpenedPage, 0}}, + {3455, {wxHtmlWindow, getOpenedPageTitle, 0}}, + {3456, {wxHtmlWindow, getRelatedFrame, 0}}, + {3457, {wxHtmlWindow, historyBack, 0}}, + {3458, {wxHtmlWindow, historyCanBack, 0}}, + {3459, {wxHtmlWindow, historyCanForward, 0}}, + {3460, {wxHtmlWindow, historyClear, 0}}, + {3461, {wxHtmlWindow, historyForward, 0}}, + {3462, {wxHtmlWindow, loadFile, 1}}, + {3463, {wxHtmlWindow, loadPage, 1}}, + {3464, {wxHtmlWindow, selectAll, 0}}, + {3465, {wxHtmlWindow, selectionToText, 0}}, + {3466, {wxHtmlWindow, selectLine, 1}}, + {3467, {wxHtmlWindow, selectWord, 1}}, + {3468, {wxHtmlWindow, setBorders, 1}}, + {3469, {wxHtmlWindow, setFonts, 3}}, + {3470, {wxHtmlWindow, setPage, 1}}, + {3471, {wxHtmlWindow, setRelatedFrame, 2}}, + {3472, {wxHtmlWindow, setRelatedStatusBar, 1}}, + {3473, {wxHtmlWindow, toText, 0}}, + {3474, {wxHtmlWindow, 'Destroy', undefined}}, + {3475, {wxHtmlLinkEvent, getLinkInfo, 0}}, + {3476, {wxSystemSettings, getColour, 1}}, + {3477, {wxSystemSettings, getFont, 1}}, + {3478, {wxSystemSettings, getMetric, 2}}, + {3479, {wxSystemSettings, getScreenType, 0}}, + {3480, {wxAuiNotebookEvent, setSelection, 1}}, + {3481, {wxAuiNotebookEvent, getSelection, 0}}, + {3482, {wxAuiNotebookEvent, setOldSelection, 1}}, + {3483, {wxAuiNotebookEvent, getOldSelection, 0}}, + {3484, {wxAuiNotebookEvent, setDragSource, 1}}, + {3485, {wxAuiNotebookEvent, getDragSource, 0}}, + {3486, {wxAuiManagerEvent, setManager, 1}}, + {3487, {wxAuiManagerEvent, getManager, 0}}, + {3488, {wxAuiManagerEvent, setPane, 1}}, + {3489, {wxAuiManagerEvent, getPane, 0}}, + {3490, {wxAuiManagerEvent, setButton, 1}}, + {3491, {wxAuiManagerEvent, getButton, 0}}, + {3492, {wxAuiManagerEvent, setDC, 1}}, + {3493, {wxAuiManagerEvent, getDC, 0}}, + {3494, {wxAuiManagerEvent, veto, 1}}, + {3495, {wxAuiManagerEvent, getVeto, 0}}, + {3496, {wxAuiManagerEvent, setCanVeto, 1}}, + {3497, {wxAuiManagerEvent, canVeto, 0}}, + {3498, {wxLogNull, new, 0}}, + {3499, {wxLogNull, 'Destroy', undefined}}, {-1, {mod, func, -1}} ]. diff --git a/lib/wx/src/gen/wxe_funcs.hrl b/lib/wx/src/gen/wxe_funcs.hrl index 7b5ca229c8..cf672644c6 100644 --- a/lib/wx/src/gen/wxe_funcs.hrl +++ b/lib/wx/src/gen/wxe_funcs.hrl @@ -1834,1442 +1834,1447 @@ -define(wxTreeCtrl_Delete, 2007). -define(wxTreeCtrl_DeleteAllItems, 2008). -define(wxTreeCtrl_DeleteChildren, 2009). --define(wxTreeCtrl_EnsureVisible, 2010). --define(wxTreeCtrl_Expand, 2011). --define(wxTreeCtrl_GetBoundingRect, 2012). --define(wxTreeCtrl_GetChildrenCount, 2014). --define(wxTreeCtrl_GetCount, 2015). --define(wxTreeCtrl_GetEditControl, 2016). --define(wxTreeCtrl_GetFirstChild, 2017). --define(wxTreeCtrl_GetNextChild, 2018). --define(wxTreeCtrl_GetFirstVisibleItem, 2019). --define(wxTreeCtrl_GetImageList, 2020). --define(wxTreeCtrl_GetIndent, 2021). --define(wxTreeCtrl_GetItemBackgroundColour, 2022). --define(wxTreeCtrl_GetItemData, 2023). --define(wxTreeCtrl_GetItemFont, 2024). --define(wxTreeCtrl_GetItemImage_1, 2025). --define(wxTreeCtrl_GetItemImage_2, 2026). --define(wxTreeCtrl_GetItemText, 2027). --define(wxTreeCtrl_GetItemTextColour, 2028). --define(wxTreeCtrl_GetLastChild, 2029). --define(wxTreeCtrl_GetNextSibling, 2030). --define(wxTreeCtrl_GetNextVisible, 2031). --define(wxTreeCtrl_GetItemParent, 2032). --define(wxTreeCtrl_GetPrevSibling, 2033). --define(wxTreeCtrl_GetPrevVisible, 2034). --define(wxTreeCtrl_GetRootItem, 2035). --define(wxTreeCtrl_GetSelection, 2036). --define(wxTreeCtrl_GetSelections, 2037). --define(wxTreeCtrl_GetStateImageList, 2038). --define(wxTreeCtrl_HitTest, 2039). --define(wxTreeCtrl_InsertItem, 2041). --define(wxTreeCtrl_IsBold, 2042). --define(wxTreeCtrl_IsExpanded, 2043). --define(wxTreeCtrl_IsSelected, 2044). --define(wxTreeCtrl_IsVisible, 2045). --define(wxTreeCtrl_ItemHasChildren, 2046). --define(wxTreeCtrl_PrependItem, 2047). --define(wxTreeCtrl_ScrollTo, 2048). --define(wxTreeCtrl_SelectItem_1, 2049). --define(wxTreeCtrl_SelectItem_2, 2050). --define(wxTreeCtrl_SetIndent, 2051). --define(wxTreeCtrl_SetImageList, 2052). --define(wxTreeCtrl_SetItemBackgroundColour, 2053). --define(wxTreeCtrl_SetItemBold, 2054). --define(wxTreeCtrl_SetItemData, 2055). --define(wxTreeCtrl_SetItemDropHighlight, 2056). --define(wxTreeCtrl_SetItemFont, 2057). --define(wxTreeCtrl_SetItemHasChildren, 2058). --define(wxTreeCtrl_SetItemImage_2, 2059). --define(wxTreeCtrl_SetItemImage_3, 2060). --define(wxTreeCtrl_SetItemText, 2061). --define(wxTreeCtrl_SetItemTextColour, 2062). --define(wxTreeCtrl_SetStateImageList, 2063). --define(wxTreeCtrl_SetWindowStyle, 2064). --define(wxTreeCtrl_SortChildren, 2065). --define(wxTreeCtrl_Toggle, 2066). --define(wxTreeCtrl_ToggleItemSelection, 2067). --define(wxTreeCtrl_Unselect, 2068). --define(wxTreeCtrl_UnselectAll, 2069). --define(wxTreeCtrl_UnselectItem, 2070). --define(wxScrollBar_new_0, 2071). --define(wxScrollBar_new_3, 2072). --define(wxScrollBar_destruct, 2073). --define(wxScrollBar_Create, 2074). --define(wxScrollBar_GetRange, 2075). --define(wxScrollBar_GetPageSize, 2076). --define(wxScrollBar_GetThumbPosition, 2077). --define(wxScrollBar_GetThumbSize, 2078). --define(wxScrollBar_SetThumbPosition, 2079). --define(wxScrollBar_SetScrollbar, 2080). --define(wxSpinButton_new_2, 2082). --define(wxSpinButton_new_0, 2083). --define(wxSpinButton_Create, 2084). --define(wxSpinButton_GetMax, 2085). --define(wxSpinButton_GetMin, 2086). --define(wxSpinButton_GetValue, 2087). --define(wxSpinButton_SetRange, 2088). --define(wxSpinButton_SetValue, 2089). --define(wxSpinButton_destroy, 2090). --define(wxSpinCtrl_new_0, 2091). --define(wxSpinCtrl_new_2, 2092). --define(wxSpinCtrl_Create, 2094). --define(wxSpinCtrl_SetValue_1_1, 2097). --define(wxSpinCtrl_SetValue_1_0, 2098). --define(wxSpinCtrl_GetValue, 2100). --define(wxSpinCtrl_SetRange, 2102). --define(wxSpinCtrl_SetSelection, 2103). --define(wxSpinCtrl_GetMin, 2105). --define(wxSpinCtrl_GetMax, 2107). --define(wxSpinCtrl_destroy, 2108). --define(wxStaticText_new_0, 2109). --define(wxStaticText_new_4, 2110). --define(wxStaticText_Create, 2111). --define(wxStaticText_GetLabel, 2112). --define(wxStaticText_SetLabel, 2113). --define(wxStaticText_Wrap, 2114). --define(wxStaticText_destroy, 2115). --define(wxStaticBitmap_new_0, 2116). --define(wxStaticBitmap_new_4, 2117). --define(wxStaticBitmap_Create, 2118). --define(wxStaticBitmap_GetBitmap, 2119). --define(wxStaticBitmap_SetBitmap, 2120). --define(wxStaticBitmap_destroy, 2121). --define(wxRadioBox_new, 2122). --define(wxRadioBox_destruct, 2124). --define(wxRadioBox_Create, 2125). --define(wxRadioBox_Enable_2, 2126). --define(wxRadioBox_Enable_1, 2127). --define(wxRadioBox_GetSelection, 2128). --define(wxRadioBox_GetString, 2129). --define(wxRadioBox_SetSelection, 2130). --define(wxRadioBox_Show_2, 2131). --define(wxRadioBox_Show_1, 2132). --define(wxRadioBox_GetColumnCount, 2133). --define(wxRadioBox_GetItemHelpText, 2134). --define(wxRadioBox_GetItemToolTip, 2135). --define(wxRadioBox_GetItemFromPoint, 2137). --define(wxRadioBox_GetRowCount, 2138). --define(wxRadioBox_IsItemEnabled, 2139). --define(wxRadioBox_IsItemShown, 2140). --define(wxRadioBox_SetItemHelpText, 2141). --define(wxRadioBox_SetItemToolTip, 2142). --define(wxRadioButton_new_0, 2143). --define(wxRadioButton_new_4, 2144). --define(wxRadioButton_Create, 2145). --define(wxRadioButton_GetValue, 2146). --define(wxRadioButton_SetValue, 2147). --define(wxRadioButton_destroy, 2148). --define(wxSlider_new_6, 2150). --define(wxSlider_new_0, 2151). --define(wxSlider_Create, 2152). --define(wxSlider_GetLineSize, 2153). --define(wxSlider_GetMax, 2154). --define(wxSlider_GetMin, 2155). --define(wxSlider_GetPageSize, 2156). --define(wxSlider_GetThumbLength, 2157). --define(wxSlider_GetValue, 2158). --define(wxSlider_SetLineSize, 2159). --define(wxSlider_SetPageSize, 2160). --define(wxSlider_SetRange, 2161). --define(wxSlider_SetThumbLength, 2162). --define(wxSlider_SetValue, 2163). --define(wxSlider_destroy, 2164). --define(wxDialog_new_4, 2166). --define(wxDialog_new_0, 2167). --define(wxDialog_destruct, 2169). --define(wxDialog_Create, 2170). --define(wxDialog_CreateButtonSizer, 2171). --define(wxDialog_CreateStdDialogButtonSizer, 2172). --define(wxDialog_EndModal, 2173). --define(wxDialog_GetAffirmativeId, 2174). --define(wxDialog_GetReturnCode, 2175). --define(wxDialog_IsModal, 2176). --define(wxDialog_SetAffirmativeId, 2177). --define(wxDialog_SetReturnCode, 2178). --define(wxDialog_Show, 2179). --define(wxDialog_ShowModal, 2180). --define(wxColourDialog_new_0, 2181). --define(wxColourDialog_new_2, 2182). --define(wxColourDialog_destruct, 2183). --define(wxColourDialog_Create, 2184). --define(wxColourDialog_GetColourData, 2185). --define(wxColourData_new_0, 2186). --define(wxColourData_new_1, 2187). --define(wxColourData_destruct, 2188). --define(wxColourData_GetChooseFull, 2189). --define(wxColourData_GetColour, 2190). --define(wxColourData_GetCustomColour, 2192). --define(wxColourData_SetChooseFull, 2193). --define(wxColourData_SetColour, 2194). --define(wxColourData_SetCustomColour, 2195). --define(wxPalette_new_0, 2196). --define(wxPalette_new_4, 2197). --define(wxPalette_destruct, 2199). --define(wxPalette_Create, 2200). --define(wxPalette_GetColoursCount, 2201). --define(wxPalette_GetPixel, 2202). --define(wxPalette_GetRGB, 2203). --define(wxPalette_IsOk, 2204). --define(wxDirDialog_new, 2208). --define(wxDirDialog_destruct, 2209). --define(wxDirDialog_GetPath, 2210). --define(wxDirDialog_GetMessage, 2211). --define(wxDirDialog_SetMessage, 2212). --define(wxDirDialog_SetPath, 2213). --define(wxFileDialog_new, 2217). --define(wxFileDialog_destruct, 2218). --define(wxFileDialog_GetDirectory, 2219). --define(wxFileDialog_GetFilename, 2220). --define(wxFileDialog_GetFilenames, 2221). --define(wxFileDialog_GetFilterIndex, 2222). --define(wxFileDialog_GetMessage, 2223). --define(wxFileDialog_GetPath, 2224). --define(wxFileDialog_GetPaths, 2225). --define(wxFileDialog_GetWildcard, 2226). --define(wxFileDialog_SetDirectory, 2227). --define(wxFileDialog_SetFilename, 2228). --define(wxFileDialog_SetFilterIndex, 2229). --define(wxFileDialog_SetMessage, 2230). --define(wxFileDialog_SetPath, 2231). --define(wxFileDialog_SetWildcard, 2232). --define(wxPickerBase_SetInternalMargin, 2233). --define(wxPickerBase_GetInternalMargin, 2234). --define(wxPickerBase_SetTextCtrlProportion, 2235). --define(wxPickerBase_SetPickerCtrlProportion, 2236). --define(wxPickerBase_GetTextCtrlProportion, 2237). --define(wxPickerBase_GetPickerCtrlProportion, 2238). --define(wxPickerBase_HasTextCtrl, 2239). --define(wxPickerBase_GetTextCtrl, 2240). --define(wxPickerBase_IsTextCtrlGrowable, 2241). --define(wxPickerBase_SetPickerCtrlGrowable, 2242). --define(wxPickerBase_SetTextCtrlGrowable, 2243). --define(wxPickerBase_IsPickerCtrlGrowable, 2244). --define(wxFilePickerCtrl_new_0, 2245). --define(wxFilePickerCtrl_new_3, 2246). --define(wxFilePickerCtrl_Create, 2247). --define(wxFilePickerCtrl_GetPath, 2248). --define(wxFilePickerCtrl_SetPath, 2249). --define(wxFilePickerCtrl_destroy, 2250). --define(wxDirPickerCtrl_new_0, 2251). --define(wxDirPickerCtrl_new_3, 2252). --define(wxDirPickerCtrl_Create, 2253). --define(wxDirPickerCtrl_GetPath, 2254). --define(wxDirPickerCtrl_SetPath, 2255). --define(wxDirPickerCtrl_destroy, 2256). --define(wxColourPickerCtrl_new_0, 2257). --define(wxColourPickerCtrl_new_3, 2258). --define(wxColourPickerCtrl_Create, 2259). --define(wxColourPickerCtrl_GetColour, 2260). --define(wxColourPickerCtrl_SetColour_1_1, 2261). --define(wxColourPickerCtrl_SetColour_1_0, 2262). --define(wxColourPickerCtrl_destroy, 2263). --define(wxDatePickerCtrl_new_0, 2264). --define(wxDatePickerCtrl_new_3, 2265). --define(wxDatePickerCtrl_GetRange, 2266). --define(wxDatePickerCtrl_GetValue, 2267). --define(wxDatePickerCtrl_SetRange, 2268). --define(wxDatePickerCtrl_SetValue, 2269). --define(wxDatePickerCtrl_destroy, 2270). --define(wxFontPickerCtrl_new_0, 2271). --define(wxFontPickerCtrl_new_3, 2272). --define(wxFontPickerCtrl_Create, 2273). --define(wxFontPickerCtrl_GetSelectedFont, 2274). --define(wxFontPickerCtrl_SetSelectedFont, 2275). --define(wxFontPickerCtrl_GetMaxPointSize, 2276). --define(wxFontPickerCtrl_SetMaxPointSize, 2277). --define(wxFontPickerCtrl_destroy, 2278). --define(wxFindReplaceDialog_new_0, 2281). --define(wxFindReplaceDialog_new_4, 2282). --define(wxFindReplaceDialog_destruct, 2283). --define(wxFindReplaceDialog_Create, 2284). --define(wxFindReplaceDialog_GetData, 2285). --define(wxFindReplaceData_new_0, 2286). --define(wxFindReplaceData_new_1, 2287). --define(wxFindReplaceData_GetFindString, 2288). --define(wxFindReplaceData_GetReplaceString, 2289). --define(wxFindReplaceData_GetFlags, 2290). --define(wxFindReplaceData_SetFlags, 2291). --define(wxFindReplaceData_SetFindString, 2292). --define(wxFindReplaceData_SetReplaceString, 2293). --define(wxFindReplaceData_destroy, 2294). --define(wxMultiChoiceDialog_new_0, 2295). --define(wxMultiChoiceDialog_new_5, 2297). --define(wxMultiChoiceDialog_GetSelections, 2298). --define(wxMultiChoiceDialog_SetSelections, 2299). --define(wxMultiChoiceDialog_destroy, 2300). --define(wxSingleChoiceDialog_new_0, 2301). --define(wxSingleChoiceDialog_new_5, 2303). --define(wxSingleChoiceDialog_GetSelection, 2304). --define(wxSingleChoiceDialog_GetStringSelection, 2305). --define(wxSingleChoiceDialog_SetSelection, 2306). --define(wxSingleChoiceDialog_destroy, 2307). --define(wxTextEntryDialog_new, 2308). --define(wxTextEntryDialog_GetValue, 2309). --define(wxTextEntryDialog_SetValue, 2310). --define(wxTextEntryDialog_destroy, 2311). --define(wxPasswordEntryDialog_new, 2312). --define(wxPasswordEntryDialog_destroy, 2313). --define(wxFontData_new_0, 2314). --define(wxFontData_new_1, 2315). --define(wxFontData_destruct, 2316). --define(wxFontData_EnableEffects, 2317). --define(wxFontData_GetAllowSymbols, 2318). --define(wxFontData_GetColour, 2319). --define(wxFontData_GetChosenFont, 2320). --define(wxFontData_GetEnableEffects, 2321). --define(wxFontData_GetInitialFont, 2322). --define(wxFontData_GetShowHelp, 2323). --define(wxFontData_SetAllowSymbols, 2324). --define(wxFontData_SetChosenFont, 2325). --define(wxFontData_SetColour, 2326). --define(wxFontData_SetInitialFont, 2327). --define(wxFontData_SetRange, 2328). --define(wxFontData_SetShowHelp, 2329). --define(wxFontDialog_new_0, 2333). --define(wxFontDialog_new_2, 2335). --define(wxFontDialog_Create, 2337). --define(wxFontDialog_GetFontData, 2338). --define(wxFontDialog_destroy, 2340). --define(wxProgressDialog_new, 2341). --define(wxProgressDialog_destruct, 2342). --define(wxProgressDialog_Resume, 2343). --define(wxProgressDialog_Update_2, 2344). --define(wxProgressDialog_Update_0, 2345). --define(wxMessageDialog_new, 2346). --define(wxMessageDialog_destruct, 2347). --define(wxPageSetupDialog_new, 2348). --define(wxPageSetupDialog_destruct, 2349). --define(wxPageSetupDialog_GetPageSetupData, 2350). --define(wxPageSetupDialog_ShowModal, 2351). --define(wxPageSetupDialogData_new_0, 2352). --define(wxPageSetupDialogData_new_1_0, 2353). --define(wxPageSetupDialogData_new_1_1, 2354). --define(wxPageSetupDialogData_destruct, 2355). --define(wxPageSetupDialogData_EnableHelp, 2356). --define(wxPageSetupDialogData_EnableMargins, 2357). --define(wxPageSetupDialogData_EnableOrientation, 2358). --define(wxPageSetupDialogData_EnablePaper, 2359). --define(wxPageSetupDialogData_EnablePrinter, 2360). --define(wxPageSetupDialogData_GetDefaultMinMargins, 2361). --define(wxPageSetupDialogData_GetEnableMargins, 2362). --define(wxPageSetupDialogData_GetEnableOrientation, 2363). --define(wxPageSetupDialogData_GetEnablePaper, 2364). --define(wxPageSetupDialogData_GetEnablePrinter, 2365). --define(wxPageSetupDialogData_GetEnableHelp, 2366). --define(wxPageSetupDialogData_GetDefaultInfo, 2367). --define(wxPageSetupDialogData_GetMarginTopLeft, 2368). --define(wxPageSetupDialogData_GetMarginBottomRight, 2369). --define(wxPageSetupDialogData_GetMinMarginTopLeft, 2370). --define(wxPageSetupDialogData_GetMinMarginBottomRight, 2371). --define(wxPageSetupDialogData_GetPaperId, 2372). --define(wxPageSetupDialogData_GetPaperSize, 2373). --define(wxPageSetupDialogData_GetPrintData, 2375). --define(wxPageSetupDialogData_IsOk, 2376). --define(wxPageSetupDialogData_SetDefaultInfo, 2377). --define(wxPageSetupDialogData_SetDefaultMinMargins, 2378). --define(wxPageSetupDialogData_SetMarginTopLeft, 2379). --define(wxPageSetupDialogData_SetMarginBottomRight, 2380). --define(wxPageSetupDialogData_SetMinMarginTopLeft, 2381). --define(wxPageSetupDialogData_SetMinMarginBottomRight, 2382). --define(wxPageSetupDialogData_SetPaperId, 2383). --define(wxPageSetupDialogData_SetPaperSize_1_1, 2384). --define(wxPageSetupDialogData_SetPaperSize_1_0, 2385). --define(wxPageSetupDialogData_SetPrintData, 2386). --define(wxPrintDialog_new_2_0, 2387). --define(wxPrintDialog_new_2_1, 2388). --define(wxPrintDialog_destruct, 2389). --define(wxPrintDialog_GetPrintDialogData, 2390). --define(wxPrintDialog_GetPrintDC, 2391). --define(wxPrintDialogData_new_0, 2392). --define(wxPrintDialogData_new_1_1, 2393). --define(wxPrintDialogData_new_1_0, 2394). --define(wxPrintDialogData_destruct, 2395). --define(wxPrintDialogData_EnableHelp, 2396). --define(wxPrintDialogData_EnablePageNumbers, 2397). --define(wxPrintDialogData_EnablePrintToFile, 2398). --define(wxPrintDialogData_EnableSelection, 2399). --define(wxPrintDialogData_GetAllPages, 2400). --define(wxPrintDialogData_GetCollate, 2401). --define(wxPrintDialogData_GetFromPage, 2402). --define(wxPrintDialogData_GetMaxPage, 2403). --define(wxPrintDialogData_GetMinPage, 2404). --define(wxPrintDialogData_GetNoCopies, 2405). --define(wxPrintDialogData_GetPrintData, 2406). --define(wxPrintDialogData_GetPrintToFile, 2407). --define(wxPrintDialogData_GetSelection, 2408). --define(wxPrintDialogData_GetToPage, 2409). --define(wxPrintDialogData_IsOk, 2410). --define(wxPrintDialogData_SetCollate, 2411). --define(wxPrintDialogData_SetFromPage, 2412). --define(wxPrintDialogData_SetMaxPage, 2413). --define(wxPrintDialogData_SetMinPage, 2414). --define(wxPrintDialogData_SetNoCopies, 2415). --define(wxPrintDialogData_SetPrintData, 2416). --define(wxPrintDialogData_SetPrintToFile, 2417). --define(wxPrintDialogData_SetSelection, 2418). --define(wxPrintDialogData_SetToPage, 2419). --define(wxPrintData_new_0, 2420). --define(wxPrintData_new_1, 2421). --define(wxPrintData_destruct, 2422). --define(wxPrintData_GetCollate, 2423). --define(wxPrintData_GetBin, 2424). --define(wxPrintData_GetColour, 2425). --define(wxPrintData_GetDuplex, 2426). --define(wxPrintData_GetNoCopies, 2427). --define(wxPrintData_GetOrientation, 2428). --define(wxPrintData_GetPaperId, 2429). --define(wxPrintData_GetPrinterName, 2430). --define(wxPrintData_GetQuality, 2431). --define(wxPrintData_IsOk, 2432). --define(wxPrintData_SetBin, 2433). --define(wxPrintData_SetCollate, 2434). --define(wxPrintData_SetColour, 2435). --define(wxPrintData_SetDuplex, 2436). --define(wxPrintData_SetNoCopies, 2437). --define(wxPrintData_SetOrientation, 2438). --define(wxPrintData_SetPaperId, 2439). --define(wxPrintData_SetPrinterName, 2440). --define(wxPrintData_SetQuality, 2441). --define(wxPrintPreview_new_2, 2444). --define(wxPrintPreview_new_3, 2445). --define(wxPrintPreview_destruct, 2447). --define(wxPrintPreview_GetCanvas, 2448). --define(wxPrintPreview_GetCurrentPage, 2449). --define(wxPrintPreview_GetFrame, 2450). --define(wxPrintPreview_GetMaxPage, 2451). --define(wxPrintPreview_GetMinPage, 2452). --define(wxPrintPreview_GetPrintout, 2453). --define(wxPrintPreview_GetPrintoutForPrinting, 2454). --define(wxPrintPreview_IsOk, 2455). --define(wxPrintPreview_PaintPage, 2456). --define(wxPrintPreview_Print, 2457). --define(wxPrintPreview_RenderPage, 2458). --define(wxPrintPreview_SetCanvas, 2459). --define(wxPrintPreview_SetCurrentPage, 2460). --define(wxPrintPreview_SetFrame, 2461). --define(wxPrintPreview_SetPrintout, 2462). --define(wxPrintPreview_SetZoom, 2463). --define(wxPreviewFrame_new, 2464). --define(wxPreviewFrame_destruct, 2465). --define(wxPreviewFrame_CreateControlBar, 2466). --define(wxPreviewFrame_CreateCanvas, 2467). --define(wxPreviewFrame_Initialize, 2468). --define(wxPreviewFrame_OnCloseWindow, 2469). --define(wxPreviewControlBar_new, 2470). --define(wxPreviewControlBar_destruct, 2471). --define(wxPreviewControlBar_CreateButtons, 2472). --define(wxPreviewControlBar_GetPrintPreview, 2473). --define(wxPreviewControlBar_GetZoomControl, 2474). --define(wxPreviewControlBar_SetZoomControl, 2475). --define(wxPrinter_new, 2477). --define(wxPrinter_CreateAbortWindow, 2478). --define(wxPrinter_GetAbort, 2479). --define(wxPrinter_GetLastError, 2480). --define(wxPrinter_GetPrintDialogData, 2481). --define(wxPrinter_Print, 2482). --define(wxPrinter_PrintDialog, 2483). --define(wxPrinter_ReportError, 2484). --define(wxPrinter_Setup, 2485). --define(wxPrinter_destroy, 2486). --define(wxXmlResource_new_1, 2487). --define(wxXmlResource_new_2, 2488). --define(wxXmlResource_destruct, 2489). --define(wxXmlResource_AttachUnknownControl, 2490). --define(wxXmlResource_ClearHandlers, 2491). --define(wxXmlResource_CompareVersion, 2492). --define(wxXmlResource_Get, 2493). --define(wxXmlResource_GetFlags, 2494). --define(wxXmlResource_GetVersion, 2495). --define(wxXmlResource_GetXRCID, 2496). --define(wxXmlResource_InitAllHandlers, 2497). --define(wxXmlResource_Load, 2498). --define(wxXmlResource_LoadBitmap, 2499). --define(wxXmlResource_LoadDialog_2, 2500). --define(wxXmlResource_LoadDialog_3, 2501). --define(wxXmlResource_LoadFrame_2, 2502). --define(wxXmlResource_LoadFrame_3, 2503). --define(wxXmlResource_LoadIcon, 2504). --define(wxXmlResource_LoadMenu, 2505). --define(wxXmlResource_LoadMenuBar_2, 2506). --define(wxXmlResource_LoadMenuBar_1, 2507). --define(wxXmlResource_LoadPanel_2, 2508). --define(wxXmlResource_LoadPanel_3, 2509). --define(wxXmlResource_LoadToolBar, 2510). --define(wxXmlResource_Set, 2511). --define(wxXmlResource_SetFlags, 2512). --define(wxXmlResource_Unload, 2513). --define(wxXmlResource_xrcctrl, 2514). --define(wxHtmlEasyPrinting_new, 2515). --define(wxHtmlEasyPrinting_destruct, 2516). --define(wxHtmlEasyPrinting_GetPrintData, 2517). --define(wxHtmlEasyPrinting_GetPageSetupData, 2518). --define(wxHtmlEasyPrinting_PreviewFile, 2519). --define(wxHtmlEasyPrinting_PreviewText, 2520). --define(wxHtmlEasyPrinting_PrintFile, 2521). --define(wxHtmlEasyPrinting_PrintText, 2522). --define(wxHtmlEasyPrinting_PageSetup, 2523). --define(wxHtmlEasyPrinting_SetFonts, 2524). --define(wxHtmlEasyPrinting_SetHeader, 2525). --define(wxHtmlEasyPrinting_SetFooter, 2526). --define(wxGLCanvas_new_2, 2528). --define(wxGLCanvas_new_3_1, 2529). --define(wxGLCanvas_new_3_0, 2530). --define(wxGLCanvas_GetContext, 2531). --define(wxGLCanvas_SetCurrent, 2533). --define(wxGLCanvas_SwapBuffers, 2534). --define(wxGLCanvas_destroy, 2535). --define(wxAuiManager_new, 2536). --define(wxAuiManager_destruct, 2537). --define(wxAuiManager_AddPane_2_1, 2538). --define(wxAuiManager_AddPane_3, 2539). --define(wxAuiManager_AddPane_2_0, 2540). --define(wxAuiManager_DetachPane, 2541). --define(wxAuiManager_GetAllPanes, 2542). --define(wxAuiManager_GetArtProvider, 2543). --define(wxAuiManager_GetDockSizeConstraint, 2544). --define(wxAuiManager_GetFlags, 2545). --define(wxAuiManager_GetManagedWindow, 2546). --define(wxAuiManager_GetManager, 2547). --define(wxAuiManager_GetPane_1_1, 2548). --define(wxAuiManager_GetPane_1_0, 2549). --define(wxAuiManager_HideHint, 2550). --define(wxAuiManager_InsertPane, 2551). --define(wxAuiManager_LoadPaneInfo, 2552). --define(wxAuiManager_LoadPerspective, 2553). --define(wxAuiManager_SavePaneInfo, 2554). --define(wxAuiManager_SavePerspective, 2555). --define(wxAuiManager_SetArtProvider, 2556). --define(wxAuiManager_SetDockSizeConstraint, 2557). --define(wxAuiManager_SetFlags, 2558). --define(wxAuiManager_SetManagedWindow, 2559). --define(wxAuiManager_ShowHint, 2560). --define(wxAuiManager_UnInit, 2561). --define(wxAuiManager_Update, 2562). --define(wxAuiPaneInfo_new_0, 2563). --define(wxAuiPaneInfo_new_1, 2564). --define(wxAuiPaneInfo_destruct, 2565). --define(wxAuiPaneInfo_BestSize_1, 2566). --define(wxAuiPaneInfo_BestSize_2, 2567). --define(wxAuiPaneInfo_Bottom, 2568). --define(wxAuiPaneInfo_BottomDockable, 2569). --define(wxAuiPaneInfo_Caption, 2570). --define(wxAuiPaneInfo_CaptionVisible, 2571). --define(wxAuiPaneInfo_Centre, 2572). --define(wxAuiPaneInfo_CentrePane, 2573). --define(wxAuiPaneInfo_CloseButton, 2574). --define(wxAuiPaneInfo_DefaultPane, 2575). --define(wxAuiPaneInfo_DestroyOnClose, 2576). --define(wxAuiPaneInfo_Direction, 2577). --define(wxAuiPaneInfo_Dock, 2578). --define(wxAuiPaneInfo_Dockable, 2579). --define(wxAuiPaneInfo_Fixed, 2580). --define(wxAuiPaneInfo_Float, 2581). --define(wxAuiPaneInfo_Floatable, 2582). --define(wxAuiPaneInfo_FloatingPosition_1, 2583). --define(wxAuiPaneInfo_FloatingPosition_2, 2584). --define(wxAuiPaneInfo_FloatingSize_1, 2585). --define(wxAuiPaneInfo_FloatingSize_2, 2586). --define(wxAuiPaneInfo_Gripper, 2587). --define(wxAuiPaneInfo_GripperTop, 2588). --define(wxAuiPaneInfo_HasBorder, 2589). --define(wxAuiPaneInfo_HasCaption, 2590). --define(wxAuiPaneInfo_HasCloseButton, 2591). --define(wxAuiPaneInfo_HasFlag, 2592). --define(wxAuiPaneInfo_HasGripper, 2593). --define(wxAuiPaneInfo_HasGripperTop, 2594). --define(wxAuiPaneInfo_HasMaximizeButton, 2595). --define(wxAuiPaneInfo_HasMinimizeButton, 2596). --define(wxAuiPaneInfo_HasPinButton, 2597). --define(wxAuiPaneInfo_Hide, 2598). --define(wxAuiPaneInfo_IsBottomDockable, 2599). --define(wxAuiPaneInfo_IsDocked, 2600). --define(wxAuiPaneInfo_IsFixed, 2601). --define(wxAuiPaneInfo_IsFloatable, 2602). --define(wxAuiPaneInfo_IsFloating, 2603). --define(wxAuiPaneInfo_IsLeftDockable, 2604). --define(wxAuiPaneInfo_IsMovable, 2605). --define(wxAuiPaneInfo_IsOk, 2606). --define(wxAuiPaneInfo_IsResizable, 2607). --define(wxAuiPaneInfo_IsRightDockable, 2608). --define(wxAuiPaneInfo_IsShown, 2609). --define(wxAuiPaneInfo_IsToolbar, 2610). --define(wxAuiPaneInfo_IsTopDockable, 2611). --define(wxAuiPaneInfo_Layer, 2612). --define(wxAuiPaneInfo_Left, 2613). --define(wxAuiPaneInfo_LeftDockable, 2614). --define(wxAuiPaneInfo_MaxSize_1, 2615). --define(wxAuiPaneInfo_MaxSize_2, 2616). --define(wxAuiPaneInfo_MaximizeButton, 2617). --define(wxAuiPaneInfo_MinSize_1, 2618). --define(wxAuiPaneInfo_MinSize_2, 2619). --define(wxAuiPaneInfo_MinimizeButton, 2620). --define(wxAuiPaneInfo_Movable, 2621). --define(wxAuiPaneInfo_Name, 2622). --define(wxAuiPaneInfo_PaneBorder, 2623). --define(wxAuiPaneInfo_PinButton, 2624). --define(wxAuiPaneInfo_Position, 2625). --define(wxAuiPaneInfo_Resizable, 2626). --define(wxAuiPaneInfo_Right, 2627). --define(wxAuiPaneInfo_RightDockable, 2628). --define(wxAuiPaneInfo_Row, 2629). --define(wxAuiPaneInfo_SafeSet, 2630). --define(wxAuiPaneInfo_SetFlag, 2631). --define(wxAuiPaneInfo_Show, 2632). --define(wxAuiPaneInfo_ToolbarPane, 2633). --define(wxAuiPaneInfo_Top, 2634). --define(wxAuiPaneInfo_TopDockable, 2635). --define(wxAuiPaneInfo_Window, 2636). --define(wxAuiNotebook_new_0, 2637). --define(wxAuiNotebook_new_2, 2638). --define(wxAuiNotebook_AddPage, 2639). --define(wxAuiNotebook_Create, 2640). --define(wxAuiNotebook_DeletePage, 2641). --define(wxAuiNotebook_GetArtProvider, 2642). --define(wxAuiNotebook_GetPage, 2643). --define(wxAuiNotebook_GetPageBitmap, 2644). --define(wxAuiNotebook_GetPageCount, 2645). --define(wxAuiNotebook_GetPageIndex, 2646). --define(wxAuiNotebook_GetPageText, 2647). --define(wxAuiNotebook_GetSelection, 2648). --define(wxAuiNotebook_InsertPage, 2649). --define(wxAuiNotebook_RemovePage, 2650). --define(wxAuiNotebook_SetArtProvider, 2651). --define(wxAuiNotebook_SetFont, 2652). --define(wxAuiNotebook_SetPageBitmap, 2653). --define(wxAuiNotebook_SetPageText, 2654). --define(wxAuiNotebook_SetSelection, 2655). --define(wxAuiNotebook_SetTabCtrlHeight, 2656). --define(wxAuiNotebook_SetUniformBitmapSize, 2657). --define(wxAuiNotebook_destroy, 2658). --define(wxMDIParentFrame_new_0, 2659). --define(wxMDIParentFrame_new_4, 2660). --define(wxMDIParentFrame_destruct, 2661). --define(wxMDIParentFrame_ActivateNext, 2662). --define(wxMDIParentFrame_ActivatePrevious, 2663). --define(wxMDIParentFrame_ArrangeIcons, 2664). --define(wxMDIParentFrame_Cascade, 2665). --define(wxMDIParentFrame_Create, 2666). --define(wxMDIParentFrame_GetActiveChild, 2667). --define(wxMDIParentFrame_GetClientWindow, 2668). --define(wxMDIParentFrame_Tile, 2669). --define(wxMDIChildFrame_new_0, 2670). --define(wxMDIChildFrame_new_4, 2671). --define(wxMDIChildFrame_destruct, 2672). --define(wxMDIChildFrame_Activate, 2673). --define(wxMDIChildFrame_Create, 2674). --define(wxMDIChildFrame_Maximize, 2675). --define(wxMDIChildFrame_Restore, 2676). --define(wxMDIClientWindow_new_0, 2677). --define(wxMDIClientWindow_new_2, 2678). --define(wxMDIClientWindow_destruct, 2679). --define(wxMDIClientWindow_CreateClient, 2680). --define(wxLayoutAlgorithm_new, 2681). --define(wxLayoutAlgorithm_LayoutFrame, 2682). --define(wxLayoutAlgorithm_LayoutMDIFrame, 2683). --define(wxLayoutAlgorithm_LayoutWindow, 2684). --define(wxLayoutAlgorithm_destroy, 2685). --define(wxEvent_GetId, 2686). --define(wxEvent_GetSkipped, 2687). --define(wxEvent_GetTimestamp, 2688). --define(wxEvent_IsCommandEvent, 2689). --define(wxEvent_ResumePropagation, 2690). --define(wxEvent_ShouldPropagate, 2691). --define(wxEvent_Skip, 2692). --define(wxEvent_StopPropagation, 2693). --define(wxCommandEvent_getClientData, 2694). --define(wxCommandEvent_GetExtraLong, 2695). --define(wxCommandEvent_GetInt, 2696). --define(wxCommandEvent_GetSelection, 2697). --define(wxCommandEvent_GetString, 2698). --define(wxCommandEvent_IsChecked, 2699). --define(wxCommandEvent_IsSelection, 2700). --define(wxCommandEvent_SetInt, 2701). --define(wxCommandEvent_SetString, 2702). --define(wxScrollEvent_GetOrientation, 2703). --define(wxScrollEvent_GetPosition, 2704). --define(wxScrollWinEvent_GetOrientation, 2705). --define(wxScrollWinEvent_GetPosition, 2706). --define(wxMouseEvent_AltDown, 2707). --define(wxMouseEvent_Button, 2708). --define(wxMouseEvent_ButtonDClick, 2709). --define(wxMouseEvent_ButtonDown, 2710). --define(wxMouseEvent_ButtonUp, 2711). --define(wxMouseEvent_CmdDown, 2712). --define(wxMouseEvent_ControlDown, 2713). --define(wxMouseEvent_Dragging, 2714). --define(wxMouseEvent_Entering, 2715). --define(wxMouseEvent_GetButton, 2716). --define(wxMouseEvent_GetPosition, 2719). --define(wxMouseEvent_GetLogicalPosition, 2720). --define(wxMouseEvent_GetLinesPerAction, 2721). --define(wxMouseEvent_GetWheelRotation, 2722). --define(wxMouseEvent_GetWheelDelta, 2723). --define(wxMouseEvent_GetX, 2724). --define(wxMouseEvent_GetY, 2725). --define(wxMouseEvent_IsButton, 2726). --define(wxMouseEvent_IsPageScroll, 2727). --define(wxMouseEvent_Leaving, 2728). --define(wxMouseEvent_LeftDClick, 2729). --define(wxMouseEvent_LeftDown, 2730). --define(wxMouseEvent_LeftIsDown, 2731). --define(wxMouseEvent_LeftUp, 2732). --define(wxMouseEvent_MetaDown, 2733). --define(wxMouseEvent_MiddleDClick, 2734). --define(wxMouseEvent_MiddleDown, 2735). --define(wxMouseEvent_MiddleIsDown, 2736). --define(wxMouseEvent_MiddleUp, 2737). --define(wxMouseEvent_Moving, 2738). --define(wxMouseEvent_RightDClick, 2739). --define(wxMouseEvent_RightDown, 2740). --define(wxMouseEvent_RightIsDown, 2741). --define(wxMouseEvent_RightUp, 2742). --define(wxMouseEvent_ShiftDown, 2743). --define(wxSetCursorEvent_GetCursor, 2744). --define(wxSetCursorEvent_GetX, 2745). --define(wxSetCursorEvent_GetY, 2746). --define(wxSetCursorEvent_HasCursor, 2747). --define(wxSetCursorEvent_SetCursor, 2748). --define(wxKeyEvent_AltDown, 2749). --define(wxKeyEvent_CmdDown, 2750). --define(wxKeyEvent_ControlDown, 2751). --define(wxKeyEvent_GetKeyCode, 2752). --define(wxKeyEvent_GetModifiers, 2753). --define(wxKeyEvent_GetPosition, 2756). --define(wxKeyEvent_GetRawKeyCode, 2757). --define(wxKeyEvent_GetRawKeyFlags, 2758). --define(wxKeyEvent_GetUnicodeKey, 2759). --define(wxKeyEvent_GetX, 2760). --define(wxKeyEvent_GetY, 2761). --define(wxKeyEvent_HasModifiers, 2762). --define(wxKeyEvent_MetaDown, 2763). --define(wxKeyEvent_ShiftDown, 2764). --define(wxSizeEvent_GetSize, 2765). --define(wxMoveEvent_GetPosition, 2766). --define(wxEraseEvent_GetDC, 2767). --define(wxFocusEvent_GetWindow, 2768). --define(wxChildFocusEvent_GetWindow, 2769). --define(wxMenuEvent_GetMenu, 2770). --define(wxMenuEvent_GetMenuId, 2771). --define(wxMenuEvent_IsPopup, 2772). --define(wxCloseEvent_CanVeto, 2773). --define(wxCloseEvent_GetLoggingOff, 2774). --define(wxCloseEvent_SetCanVeto, 2775). --define(wxCloseEvent_SetLoggingOff, 2776). --define(wxCloseEvent_Veto, 2777). --define(wxShowEvent_SetShow, 2778). --define(wxShowEvent_GetShow, 2779). --define(wxIconizeEvent_Iconized, 2780). --define(wxJoystickEvent_ButtonDown, 2781). --define(wxJoystickEvent_ButtonIsDown, 2782). --define(wxJoystickEvent_ButtonUp, 2783). --define(wxJoystickEvent_GetButtonChange, 2784). --define(wxJoystickEvent_GetButtonState, 2785). --define(wxJoystickEvent_GetJoystick, 2786). --define(wxJoystickEvent_GetPosition, 2787). --define(wxJoystickEvent_GetZPosition, 2788). --define(wxJoystickEvent_IsButton, 2789). --define(wxJoystickEvent_IsMove, 2790). --define(wxJoystickEvent_IsZMove, 2791). --define(wxUpdateUIEvent_CanUpdate, 2792). --define(wxUpdateUIEvent_Check, 2793). --define(wxUpdateUIEvent_Enable, 2794). --define(wxUpdateUIEvent_Show, 2795). --define(wxUpdateUIEvent_GetChecked, 2796). --define(wxUpdateUIEvent_GetEnabled, 2797). --define(wxUpdateUIEvent_GetShown, 2798). --define(wxUpdateUIEvent_GetSetChecked, 2799). --define(wxUpdateUIEvent_GetSetEnabled, 2800). --define(wxUpdateUIEvent_GetSetShown, 2801). --define(wxUpdateUIEvent_GetSetText, 2802). --define(wxUpdateUIEvent_GetText, 2803). --define(wxUpdateUIEvent_GetMode, 2804). --define(wxUpdateUIEvent_GetUpdateInterval, 2805). --define(wxUpdateUIEvent_ResetUpdateTime, 2806). --define(wxUpdateUIEvent_SetMode, 2807). --define(wxUpdateUIEvent_SetText, 2808). --define(wxUpdateUIEvent_SetUpdateInterval, 2809). --define(wxMouseCaptureChangedEvent_GetCapturedWindow, 2810). --define(wxPaletteChangedEvent_SetChangedWindow, 2811). --define(wxPaletteChangedEvent_GetChangedWindow, 2812). --define(wxQueryNewPaletteEvent_SetPaletteRealized, 2813). --define(wxQueryNewPaletteEvent_GetPaletteRealized, 2814). --define(wxNavigationKeyEvent_GetDirection, 2815). --define(wxNavigationKeyEvent_SetDirection, 2816). --define(wxNavigationKeyEvent_IsWindowChange, 2817). --define(wxNavigationKeyEvent_SetWindowChange, 2818). --define(wxNavigationKeyEvent_IsFromTab, 2819). --define(wxNavigationKeyEvent_SetFromTab, 2820). --define(wxNavigationKeyEvent_GetCurrentFocus, 2821). --define(wxNavigationKeyEvent_SetCurrentFocus, 2822). --define(wxHelpEvent_GetOrigin, 2823). --define(wxHelpEvent_GetPosition, 2824). --define(wxHelpEvent_SetOrigin, 2825). --define(wxHelpEvent_SetPosition, 2826). --define(wxContextMenuEvent_GetPosition, 2827). --define(wxContextMenuEvent_SetPosition, 2828). --define(wxIdleEvent_CanSend, 2829). --define(wxIdleEvent_GetMode, 2830). --define(wxIdleEvent_RequestMore, 2831). --define(wxIdleEvent_MoreRequested, 2832). --define(wxIdleEvent_SetMode, 2833). --define(wxGridEvent_AltDown, 2834). --define(wxGridEvent_ControlDown, 2835). --define(wxGridEvent_GetCol, 2836). --define(wxGridEvent_GetPosition, 2837). --define(wxGridEvent_GetRow, 2838). --define(wxGridEvent_MetaDown, 2839). --define(wxGridEvent_Selecting, 2840). --define(wxGridEvent_ShiftDown, 2841). --define(wxNotifyEvent_Allow, 2842). --define(wxNotifyEvent_IsAllowed, 2843). --define(wxNotifyEvent_Veto, 2844). --define(wxSashEvent_GetEdge, 2845). --define(wxSashEvent_GetDragRect, 2846). --define(wxSashEvent_GetDragStatus, 2847). --define(wxListEvent_GetCacheFrom, 2848). --define(wxListEvent_GetCacheTo, 2849). --define(wxListEvent_GetKeyCode, 2850). --define(wxListEvent_GetIndex, 2851). --define(wxListEvent_GetColumn, 2852). --define(wxListEvent_GetPoint, 2853). --define(wxListEvent_GetLabel, 2854). --define(wxListEvent_GetText, 2855). --define(wxListEvent_GetImage, 2856). --define(wxListEvent_GetData, 2857). --define(wxListEvent_GetMask, 2858). --define(wxListEvent_GetItem, 2859). --define(wxListEvent_IsEditCancelled, 2860). --define(wxDateEvent_GetDate, 2861). --define(wxCalendarEvent_GetWeekDay, 2862). --define(wxFileDirPickerEvent_GetPath, 2863). --define(wxColourPickerEvent_GetColour, 2864). --define(wxFontPickerEvent_GetFont, 2865). --define(wxStyledTextEvent_GetPosition, 2866). --define(wxStyledTextEvent_GetKey, 2867). --define(wxStyledTextEvent_GetModifiers, 2868). --define(wxStyledTextEvent_GetModificationType, 2869). --define(wxStyledTextEvent_GetText, 2870). --define(wxStyledTextEvent_GetLength, 2871). --define(wxStyledTextEvent_GetLinesAdded, 2872). --define(wxStyledTextEvent_GetLine, 2873). --define(wxStyledTextEvent_GetFoldLevelNow, 2874). --define(wxStyledTextEvent_GetFoldLevelPrev, 2875). --define(wxStyledTextEvent_GetMargin, 2876). --define(wxStyledTextEvent_GetMessage, 2877). --define(wxStyledTextEvent_GetWParam, 2878). --define(wxStyledTextEvent_GetLParam, 2879). --define(wxStyledTextEvent_GetListType, 2880). --define(wxStyledTextEvent_GetX, 2881). --define(wxStyledTextEvent_GetY, 2882). --define(wxStyledTextEvent_GetDragText, 2883). --define(wxStyledTextEvent_GetDragAllowMove, 2884). --define(wxStyledTextEvent_GetDragResult, 2885). --define(wxStyledTextEvent_GetShift, 2886). --define(wxStyledTextEvent_GetControl, 2887). --define(wxStyledTextEvent_GetAlt, 2888). --define(utils_wxGetKeyState, 2889). --define(utils_wxGetMousePosition, 2890). --define(utils_wxGetMouseState, 2891). --define(utils_wxSetDetectableAutoRepeat, 2892). --define(utils_wxBell, 2893). --define(utils_wxFindMenuItemId, 2894). --define(utils_wxGenericFindWindowAtPoint, 2895). --define(utils_wxFindWindowAtPoint, 2896). --define(utils_wxBeginBusyCursor, 2897). --define(utils_wxEndBusyCursor, 2898). --define(utils_wxIsBusy, 2899). --define(utils_wxShutdown, 2900). --define(utils_wxShell, 2901). --define(utils_wxLaunchDefaultBrowser, 2902). --define(utils_wxGetEmailAddress, 2903). --define(utils_wxGetUserId, 2904). --define(utils_wxGetHomeDir, 2905). --define(utils_wxNewId, 2906). --define(utils_wxRegisterId, 2907). --define(utils_wxGetCurrentId, 2908). --define(utils_wxGetOsDescription, 2909). --define(utils_wxIsPlatformLittleEndian, 2910). --define(utils_wxIsPlatform64Bit, 2911). --define(wxPrintout_new, 2912). --define(wxPrintout_destruct, 2913). --define(wxPrintout_GetDC, 2914). --define(wxPrintout_GetPageSizeMM, 2915). --define(wxPrintout_GetPageSizePixels, 2916). --define(wxPrintout_GetPaperRectPixels, 2917). --define(wxPrintout_GetPPIPrinter, 2918). --define(wxPrintout_GetPPIScreen, 2919). --define(wxPrintout_GetTitle, 2920). --define(wxPrintout_IsPreview, 2921). --define(wxPrintout_FitThisSizeToPaper, 2922). --define(wxPrintout_FitThisSizeToPage, 2923). --define(wxPrintout_FitThisSizeToPageMargins, 2924). --define(wxPrintout_MapScreenSizeToPaper, 2925). --define(wxPrintout_MapScreenSizeToPage, 2926). --define(wxPrintout_MapScreenSizeToPageMargins, 2927). --define(wxPrintout_MapScreenSizeToDevice, 2928). --define(wxPrintout_GetLogicalPaperRect, 2929). --define(wxPrintout_GetLogicalPageRect, 2930). --define(wxPrintout_GetLogicalPageMarginsRect, 2931). --define(wxPrintout_SetLogicalOrigin, 2932). --define(wxPrintout_OffsetLogicalOrigin, 2933). --define(wxStyledTextCtrl_new_2, 2934). --define(wxStyledTextCtrl_new_0, 2935). --define(wxStyledTextCtrl_destruct, 2936). --define(wxStyledTextCtrl_Create, 2937). --define(wxStyledTextCtrl_AddText, 2938). --define(wxStyledTextCtrl_AddStyledText, 2939). --define(wxStyledTextCtrl_InsertText, 2940). --define(wxStyledTextCtrl_ClearAll, 2941). --define(wxStyledTextCtrl_ClearDocumentStyle, 2942). --define(wxStyledTextCtrl_GetLength, 2943). --define(wxStyledTextCtrl_GetCharAt, 2944). --define(wxStyledTextCtrl_GetCurrentPos, 2945). --define(wxStyledTextCtrl_GetAnchor, 2946). --define(wxStyledTextCtrl_GetStyleAt, 2947). --define(wxStyledTextCtrl_Redo, 2948). --define(wxStyledTextCtrl_SetUndoCollection, 2949). --define(wxStyledTextCtrl_SelectAll, 2950). --define(wxStyledTextCtrl_SetSavePoint, 2951). --define(wxStyledTextCtrl_GetStyledText, 2952). --define(wxStyledTextCtrl_CanRedo, 2953). --define(wxStyledTextCtrl_MarkerLineFromHandle, 2954). --define(wxStyledTextCtrl_MarkerDeleteHandle, 2955). --define(wxStyledTextCtrl_GetUndoCollection, 2956). --define(wxStyledTextCtrl_GetViewWhiteSpace, 2957). --define(wxStyledTextCtrl_SetViewWhiteSpace, 2958). --define(wxStyledTextCtrl_PositionFromPoint, 2959). --define(wxStyledTextCtrl_PositionFromPointClose, 2960). --define(wxStyledTextCtrl_GotoLine, 2961). --define(wxStyledTextCtrl_GotoPos, 2962). --define(wxStyledTextCtrl_SetAnchor, 2963). --define(wxStyledTextCtrl_GetCurLine, 2964). --define(wxStyledTextCtrl_GetEndStyled, 2965). --define(wxStyledTextCtrl_ConvertEOLs, 2966). --define(wxStyledTextCtrl_GetEOLMode, 2967). --define(wxStyledTextCtrl_SetEOLMode, 2968). --define(wxStyledTextCtrl_StartStyling, 2969). --define(wxStyledTextCtrl_SetStyling, 2970). --define(wxStyledTextCtrl_GetBufferedDraw, 2971). --define(wxStyledTextCtrl_SetBufferedDraw, 2972). --define(wxStyledTextCtrl_SetTabWidth, 2973). --define(wxStyledTextCtrl_GetTabWidth, 2974). --define(wxStyledTextCtrl_SetCodePage, 2975). --define(wxStyledTextCtrl_MarkerDefine, 2976). --define(wxStyledTextCtrl_MarkerSetForeground, 2977). --define(wxStyledTextCtrl_MarkerSetBackground, 2978). --define(wxStyledTextCtrl_MarkerAdd, 2979). --define(wxStyledTextCtrl_MarkerDelete, 2980). --define(wxStyledTextCtrl_MarkerDeleteAll, 2981). --define(wxStyledTextCtrl_MarkerGet, 2982). --define(wxStyledTextCtrl_MarkerNext, 2983). --define(wxStyledTextCtrl_MarkerPrevious, 2984). --define(wxStyledTextCtrl_MarkerDefineBitmap, 2985). --define(wxStyledTextCtrl_MarkerAddSet, 2986). --define(wxStyledTextCtrl_MarkerSetAlpha, 2987). --define(wxStyledTextCtrl_SetMarginType, 2988). --define(wxStyledTextCtrl_GetMarginType, 2989). --define(wxStyledTextCtrl_SetMarginWidth, 2990). --define(wxStyledTextCtrl_GetMarginWidth, 2991). --define(wxStyledTextCtrl_SetMarginMask, 2992). --define(wxStyledTextCtrl_GetMarginMask, 2993). --define(wxStyledTextCtrl_SetMarginSensitive, 2994). --define(wxStyledTextCtrl_GetMarginSensitive, 2995). --define(wxStyledTextCtrl_StyleClearAll, 2996). --define(wxStyledTextCtrl_StyleSetForeground, 2997). --define(wxStyledTextCtrl_StyleSetBackground, 2998). --define(wxStyledTextCtrl_StyleSetBold, 2999). --define(wxStyledTextCtrl_StyleSetItalic, 3000). --define(wxStyledTextCtrl_StyleSetSize, 3001). --define(wxStyledTextCtrl_StyleSetFaceName, 3002). --define(wxStyledTextCtrl_StyleSetEOLFilled, 3003). --define(wxStyledTextCtrl_StyleResetDefault, 3004). --define(wxStyledTextCtrl_StyleSetUnderline, 3005). --define(wxStyledTextCtrl_StyleSetCase, 3006). --define(wxStyledTextCtrl_StyleSetHotSpot, 3007). --define(wxStyledTextCtrl_SetSelForeground, 3008). --define(wxStyledTextCtrl_SetSelBackground, 3009). --define(wxStyledTextCtrl_GetSelAlpha, 3010). --define(wxStyledTextCtrl_SetSelAlpha, 3011). --define(wxStyledTextCtrl_SetCaretForeground, 3012). --define(wxStyledTextCtrl_CmdKeyAssign, 3013). --define(wxStyledTextCtrl_CmdKeyClear, 3014). --define(wxStyledTextCtrl_CmdKeyClearAll, 3015). --define(wxStyledTextCtrl_SetStyleBytes, 3016). --define(wxStyledTextCtrl_StyleSetVisible, 3017). --define(wxStyledTextCtrl_GetCaretPeriod, 3018). --define(wxStyledTextCtrl_SetCaretPeriod, 3019). --define(wxStyledTextCtrl_SetWordChars, 3020). --define(wxStyledTextCtrl_BeginUndoAction, 3021). --define(wxStyledTextCtrl_EndUndoAction, 3022). --define(wxStyledTextCtrl_IndicatorSetStyle, 3023). --define(wxStyledTextCtrl_IndicatorGetStyle, 3024). --define(wxStyledTextCtrl_IndicatorSetForeground, 3025). --define(wxStyledTextCtrl_IndicatorGetForeground, 3026). --define(wxStyledTextCtrl_SetWhitespaceForeground, 3027). --define(wxStyledTextCtrl_SetWhitespaceBackground, 3028). --define(wxStyledTextCtrl_GetStyleBits, 3029). --define(wxStyledTextCtrl_SetLineState, 3030). --define(wxStyledTextCtrl_GetLineState, 3031). --define(wxStyledTextCtrl_GetMaxLineState, 3032). --define(wxStyledTextCtrl_GetCaretLineVisible, 3033). --define(wxStyledTextCtrl_SetCaretLineVisible, 3034). --define(wxStyledTextCtrl_GetCaretLineBackground, 3035). --define(wxStyledTextCtrl_SetCaretLineBackground, 3036). --define(wxStyledTextCtrl_AutoCompShow, 3037). --define(wxStyledTextCtrl_AutoCompCancel, 3038). --define(wxStyledTextCtrl_AutoCompActive, 3039). --define(wxStyledTextCtrl_AutoCompPosStart, 3040). --define(wxStyledTextCtrl_AutoCompComplete, 3041). --define(wxStyledTextCtrl_AutoCompStops, 3042). --define(wxStyledTextCtrl_AutoCompSetSeparator, 3043). --define(wxStyledTextCtrl_AutoCompGetSeparator, 3044). --define(wxStyledTextCtrl_AutoCompSelect, 3045). --define(wxStyledTextCtrl_AutoCompSetCancelAtStart, 3046). --define(wxStyledTextCtrl_AutoCompGetCancelAtStart, 3047). --define(wxStyledTextCtrl_AutoCompSetFillUps, 3048). --define(wxStyledTextCtrl_AutoCompSetChooseSingle, 3049). --define(wxStyledTextCtrl_AutoCompGetChooseSingle, 3050). --define(wxStyledTextCtrl_AutoCompSetIgnoreCase, 3051). --define(wxStyledTextCtrl_AutoCompGetIgnoreCase, 3052). --define(wxStyledTextCtrl_UserListShow, 3053). --define(wxStyledTextCtrl_AutoCompSetAutoHide, 3054). --define(wxStyledTextCtrl_AutoCompGetAutoHide, 3055). --define(wxStyledTextCtrl_AutoCompSetDropRestOfWord, 3056). --define(wxStyledTextCtrl_AutoCompGetDropRestOfWord, 3057). --define(wxStyledTextCtrl_RegisterImage, 3058). --define(wxStyledTextCtrl_ClearRegisteredImages, 3059). --define(wxStyledTextCtrl_AutoCompGetTypeSeparator, 3060). --define(wxStyledTextCtrl_AutoCompSetTypeSeparator, 3061). --define(wxStyledTextCtrl_AutoCompSetMaxWidth, 3062). --define(wxStyledTextCtrl_AutoCompGetMaxWidth, 3063). --define(wxStyledTextCtrl_AutoCompSetMaxHeight, 3064). --define(wxStyledTextCtrl_AutoCompGetMaxHeight, 3065). --define(wxStyledTextCtrl_SetIndent, 3066). --define(wxStyledTextCtrl_GetIndent, 3067). --define(wxStyledTextCtrl_SetUseTabs, 3068). --define(wxStyledTextCtrl_GetUseTabs, 3069). --define(wxStyledTextCtrl_SetLineIndentation, 3070). --define(wxStyledTextCtrl_GetLineIndentation, 3071). --define(wxStyledTextCtrl_GetLineIndentPosition, 3072). --define(wxStyledTextCtrl_GetColumn, 3073). --define(wxStyledTextCtrl_SetUseHorizontalScrollBar, 3074). --define(wxStyledTextCtrl_GetUseHorizontalScrollBar, 3075). --define(wxStyledTextCtrl_SetIndentationGuides, 3076). --define(wxStyledTextCtrl_GetIndentationGuides, 3077). --define(wxStyledTextCtrl_SetHighlightGuide, 3078). --define(wxStyledTextCtrl_GetHighlightGuide, 3079). --define(wxStyledTextCtrl_GetLineEndPosition, 3080). --define(wxStyledTextCtrl_GetCodePage, 3081). --define(wxStyledTextCtrl_GetCaretForeground, 3082). --define(wxStyledTextCtrl_GetReadOnly, 3083). --define(wxStyledTextCtrl_SetCurrentPos, 3084). --define(wxStyledTextCtrl_SetSelectionStart, 3085). --define(wxStyledTextCtrl_GetSelectionStart, 3086). --define(wxStyledTextCtrl_SetSelectionEnd, 3087). --define(wxStyledTextCtrl_GetSelectionEnd, 3088). --define(wxStyledTextCtrl_SetPrintMagnification, 3089). --define(wxStyledTextCtrl_GetPrintMagnification, 3090). --define(wxStyledTextCtrl_SetPrintColourMode, 3091). --define(wxStyledTextCtrl_GetPrintColourMode, 3092). --define(wxStyledTextCtrl_FindText, 3093). --define(wxStyledTextCtrl_FormatRange, 3094). --define(wxStyledTextCtrl_GetFirstVisibleLine, 3095). --define(wxStyledTextCtrl_GetLine, 3096). --define(wxStyledTextCtrl_GetLineCount, 3097). --define(wxStyledTextCtrl_SetMarginLeft, 3098). --define(wxStyledTextCtrl_GetMarginLeft, 3099). --define(wxStyledTextCtrl_SetMarginRight, 3100). --define(wxStyledTextCtrl_GetMarginRight, 3101). --define(wxStyledTextCtrl_GetModify, 3102). --define(wxStyledTextCtrl_SetSelection, 3103). --define(wxStyledTextCtrl_GetSelectedText, 3104). --define(wxStyledTextCtrl_GetTextRange, 3105). --define(wxStyledTextCtrl_HideSelection, 3106). --define(wxStyledTextCtrl_LineFromPosition, 3107). --define(wxStyledTextCtrl_PositionFromLine, 3108). --define(wxStyledTextCtrl_LineScroll, 3109). --define(wxStyledTextCtrl_EnsureCaretVisible, 3110). --define(wxStyledTextCtrl_ReplaceSelection, 3111). --define(wxStyledTextCtrl_SetReadOnly, 3112). --define(wxStyledTextCtrl_CanPaste, 3113). --define(wxStyledTextCtrl_CanUndo, 3114). --define(wxStyledTextCtrl_EmptyUndoBuffer, 3115). --define(wxStyledTextCtrl_Undo, 3116). --define(wxStyledTextCtrl_Cut, 3117). --define(wxStyledTextCtrl_Copy, 3118). --define(wxStyledTextCtrl_Paste, 3119). --define(wxStyledTextCtrl_Clear, 3120). --define(wxStyledTextCtrl_SetText, 3121). --define(wxStyledTextCtrl_GetText, 3122). --define(wxStyledTextCtrl_GetTextLength, 3123). --define(wxStyledTextCtrl_GetOvertype, 3124). --define(wxStyledTextCtrl_SetCaretWidth, 3125). --define(wxStyledTextCtrl_GetCaretWidth, 3126). --define(wxStyledTextCtrl_SetTargetStart, 3127). --define(wxStyledTextCtrl_GetTargetStart, 3128). --define(wxStyledTextCtrl_SetTargetEnd, 3129). --define(wxStyledTextCtrl_GetTargetEnd, 3130). --define(wxStyledTextCtrl_ReplaceTarget, 3131). --define(wxStyledTextCtrl_SearchInTarget, 3132). --define(wxStyledTextCtrl_SetSearchFlags, 3133). --define(wxStyledTextCtrl_GetSearchFlags, 3134). --define(wxStyledTextCtrl_CallTipShow, 3135). --define(wxStyledTextCtrl_CallTipCancel, 3136). --define(wxStyledTextCtrl_CallTipActive, 3137). --define(wxStyledTextCtrl_CallTipPosAtStart, 3138). --define(wxStyledTextCtrl_CallTipSetHighlight, 3139). --define(wxStyledTextCtrl_CallTipSetBackground, 3140). --define(wxStyledTextCtrl_CallTipSetForeground, 3141). --define(wxStyledTextCtrl_CallTipSetForegroundHighlight, 3142). --define(wxStyledTextCtrl_CallTipUseStyle, 3143). --define(wxStyledTextCtrl_VisibleFromDocLine, 3144). --define(wxStyledTextCtrl_DocLineFromVisible, 3145). --define(wxStyledTextCtrl_WrapCount, 3146). --define(wxStyledTextCtrl_SetFoldLevel, 3147). --define(wxStyledTextCtrl_GetFoldLevel, 3148). --define(wxStyledTextCtrl_GetLastChild, 3149). --define(wxStyledTextCtrl_GetFoldParent, 3150). --define(wxStyledTextCtrl_ShowLines, 3151). --define(wxStyledTextCtrl_HideLines, 3152). --define(wxStyledTextCtrl_GetLineVisible, 3153). --define(wxStyledTextCtrl_SetFoldExpanded, 3154). --define(wxStyledTextCtrl_GetFoldExpanded, 3155). --define(wxStyledTextCtrl_ToggleFold, 3156). --define(wxStyledTextCtrl_EnsureVisible, 3157). --define(wxStyledTextCtrl_SetFoldFlags, 3158). --define(wxStyledTextCtrl_EnsureVisibleEnforcePolicy, 3159). --define(wxStyledTextCtrl_SetTabIndents, 3160). --define(wxStyledTextCtrl_GetTabIndents, 3161). --define(wxStyledTextCtrl_SetBackSpaceUnIndents, 3162). --define(wxStyledTextCtrl_GetBackSpaceUnIndents, 3163). --define(wxStyledTextCtrl_SetMouseDwellTime, 3164). --define(wxStyledTextCtrl_GetMouseDwellTime, 3165). --define(wxStyledTextCtrl_WordStartPosition, 3166). --define(wxStyledTextCtrl_WordEndPosition, 3167). --define(wxStyledTextCtrl_SetWrapMode, 3168). --define(wxStyledTextCtrl_GetWrapMode, 3169). --define(wxStyledTextCtrl_SetWrapVisualFlags, 3170). --define(wxStyledTextCtrl_GetWrapVisualFlags, 3171). --define(wxStyledTextCtrl_SetWrapVisualFlagsLocation, 3172). --define(wxStyledTextCtrl_GetWrapVisualFlagsLocation, 3173). --define(wxStyledTextCtrl_SetWrapStartIndent, 3174). --define(wxStyledTextCtrl_GetWrapStartIndent, 3175). --define(wxStyledTextCtrl_SetLayoutCache, 3176). --define(wxStyledTextCtrl_GetLayoutCache, 3177). --define(wxStyledTextCtrl_SetScrollWidth, 3178). --define(wxStyledTextCtrl_GetScrollWidth, 3179). --define(wxStyledTextCtrl_TextWidth, 3180). --define(wxStyledTextCtrl_GetEndAtLastLine, 3181). --define(wxStyledTextCtrl_TextHeight, 3182). --define(wxStyledTextCtrl_SetUseVerticalScrollBar, 3183). --define(wxStyledTextCtrl_GetUseVerticalScrollBar, 3184). --define(wxStyledTextCtrl_AppendText, 3185). --define(wxStyledTextCtrl_GetTwoPhaseDraw, 3186). --define(wxStyledTextCtrl_SetTwoPhaseDraw, 3187). --define(wxStyledTextCtrl_TargetFromSelection, 3188). --define(wxStyledTextCtrl_LinesJoin, 3189). --define(wxStyledTextCtrl_LinesSplit, 3190). --define(wxStyledTextCtrl_SetFoldMarginColour, 3191). --define(wxStyledTextCtrl_SetFoldMarginHiColour, 3192). --define(wxStyledTextCtrl_LineDown, 3193). --define(wxStyledTextCtrl_LineDownExtend, 3194). --define(wxStyledTextCtrl_LineUp, 3195). --define(wxStyledTextCtrl_LineUpExtend, 3196). --define(wxStyledTextCtrl_CharLeft, 3197). --define(wxStyledTextCtrl_CharLeftExtend, 3198). --define(wxStyledTextCtrl_CharRight, 3199). --define(wxStyledTextCtrl_CharRightExtend, 3200). --define(wxStyledTextCtrl_WordLeft, 3201). --define(wxStyledTextCtrl_WordLeftExtend, 3202). --define(wxStyledTextCtrl_WordRight, 3203). --define(wxStyledTextCtrl_WordRightExtend, 3204). --define(wxStyledTextCtrl_Home, 3205). --define(wxStyledTextCtrl_HomeExtend, 3206). --define(wxStyledTextCtrl_LineEnd, 3207). --define(wxStyledTextCtrl_LineEndExtend, 3208). --define(wxStyledTextCtrl_DocumentStart, 3209). --define(wxStyledTextCtrl_DocumentStartExtend, 3210). --define(wxStyledTextCtrl_DocumentEnd, 3211). --define(wxStyledTextCtrl_DocumentEndExtend, 3212). --define(wxStyledTextCtrl_PageUp, 3213). --define(wxStyledTextCtrl_PageUpExtend, 3214). --define(wxStyledTextCtrl_PageDown, 3215). --define(wxStyledTextCtrl_PageDownExtend, 3216). --define(wxStyledTextCtrl_EditToggleOvertype, 3217). --define(wxStyledTextCtrl_Cancel, 3218). --define(wxStyledTextCtrl_DeleteBack, 3219). --define(wxStyledTextCtrl_Tab, 3220). --define(wxStyledTextCtrl_BackTab, 3221). --define(wxStyledTextCtrl_NewLine, 3222). --define(wxStyledTextCtrl_FormFeed, 3223). --define(wxStyledTextCtrl_VCHome, 3224). --define(wxStyledTextCtrl_VCHomeExtend, 3225). --define(wxStyledTextCtrl_ZoomIn, 3226). --define(wxStyledTextCtrl_ZoomOut, 3227). --define(wxStyledTextCtrl_DelWordLeft, 3228). --define(wxStyledTextCtrl_DelWordRight, 3229). --define(wxStyledTextCtrl_LineCut, 3230). --define(wxStyledTextCtrl_LineDelete, 3231). --define(wxStyledTextCtrl_LineTranspose, 3232). --define(wxStyledTextCtrl_LineDuplicate, 3233). --define(wxStyledTextCtrl_LowerCase, 3234). --define(wxStyledTextCtrl_UpperCase, 3235). --define(wxStyledTextCtrl_LineScrollDown, 3236). --define(wxStyledTextCtrl_LineScrollUp, 3237). --define(wxStyledTextCtrl_DeleteBackNotLine, 3238). --define(wxStyledTextCtrl_HomeDisplay, 3239). --define(wxStyledTextCtrl_HomeDisplayExtend, 3240). --define(wxStyledTextCtrl_LineEndDisplay, 3241). --define(wxStyledTextCtrl_LineEndDisplayExtend, 3242). --define(wxStyledTextCtrl_HomeWrapExtend, 3243). --define(wxStyledTextCtrl_LineEndWrap, 3244). --define(wxStyledTextCtrl_LineEndWrapExtend, 3245). --define(wxStyledTextCtrl_VCHomeWrap, 3246). --define(wxStyledTextCtrl_VCHomeWrapExtend, 3247). --define(wxStyledTextCtrl_LineCopy, 3248). --define(wxStyledTextCtrl_MoveCaretInsideView, 3249). --define(wxStyledTextCtrl_LineLength, 3250). --define(wxStyledTextCtrl_BraceHighlight, 3251). --define(wxStyledTextCtrl_BraceBadLight, 3252). --define(wxStyledTextCtrl_BraceMatch, 3253). --define(wxStyledTextCtrl_GetViewEOL, 3254). --define(wxStyledTextCtrl_SetViewEOL, 3255). --define(wxStyledTextCtrl_SetModEventMask, 3256). --define(wxStyledTextCtrl_GetEdgeColumn, 3257). --define(wxStyledTextCtrl_SetEdgeColumn, 3258). --define(wxStyledTextCtrl_GetEdgeMode, 3259). --define(wxStyledTextCtrl_GetEdgeColour, 3260). --define(wxStyledTextCtrl_SetEdgeColour, 3261). --define(wxStyledTextCtrl_SearchAnchor, 3262). --define(wxStyledTextCtrl_SearchNext, 3263). --define(wxStyledTextCtrl_SearchPrev, 3264). --define(wxStyledTextCtrl_LinesOnScreen, 3265). --define(wxStyledTextCtrl_UsePopUp, 3266). --define(wxStyledTextCtrl_SelectionIsRectangle, 3267). --define(wxStyledTextCtrl_SetZoom, 3268). --define(wxStyledTextCtrl_GetZoom, 3269). --define(wxStyledTextCtrl_GetModEventMask, 3270). --define(wxStyledTextCtrl_SetSTCFocus, 3271). --define(wxStyledTextCtrl_GetSTCFocus, 3272). --define(wxStyledTextCtrl_SetStatus, 3273). --define(wxStyledTextCtrl_GetStatus, 3274). --define(wxStyledTextCtrl_SetMouseDownCaptures, 3275). --define(wxStyledTextCtrl_GetMouseDownCaptures, 3276). --define(wxStyledTextCtrl_SetSTCCursor, 3277). --define(wxStyledTextCtrl_GetSTCCursor, 3278). --define(wxStyledTextCtrl_SetControlCharSymbol, 3279). --define(wxStyledTextCtrl_GetControlCharSymbol, 3280). --define(wxStyledTextCtrl_WordPartLeft, 3281). --define(wxStyledTextCtrl_WordPartLeftExtend, 3282). --define(wxStyledTextCtrl_WordPartRight, 3283). --define(wxStyledTextCtrl_WordPartRightExtend, 3284). --define(wxStyledTextCtrl_SetVisiblePolicy, 3285). --define(wxStyledTextCtrl_DelLineLeft, 3286). --define(wxStyledTextCtrl_DelLineRight, 3287). --define(wxStyledTextCtrl_GetXOffset, 3288). --define(wxStyledTextCtrl_ChooseCaretX, 3289). --define(wxStyledTextCtrl_SetXCaretPolicy, 3290). --define(wxStyledTextCtrl_SetYCaretPolicy, 3291). --define(wxStyledTextCtrl_GetPrintWrapMode, 3292). --define(wxStyledTextCtrl_SetHotspotActiveForeground, 3293). --define(wxStyledTextCtrl_SetHotspotActiveBackground, 3294). --define(wxStyledTextCtrl_SetHotspotActiveUnderline, 3295). --define(wxStyledTextCtrl_SetHotspotSingleLine, 3296). --define(wxStyledTextCtrl_ParaDownExtend, 3297). --define(wxStyledTextCtrl_ParaUp, 3298). --define(wxStyledTextCtrl_ParaUpExtend, 3299). --define(wxStyledTextCtrl_PositionBefore, 3300). --define(wxStyledTextCtrl_PositionAfter, 3301). --define(wxStyledTextCtrl_CopyRange, 3302). --define(wxStyledTextCtrl_CopyText, 3303). --define(wxStyledTextCtrl_SetSelectionMode, 3304). --define(wxStyledTextCtrl_GetSelectionMode, 3305). --define(wxStyledTextCtrl_LineDownRectExtend, 3306). --define(wxStyledTextCtrl_LineUpRectExtend, 3307). --define(wxStyledTextCtrl_CharLeftRectExtend, 3308). --define(wxStyledTextCtrl_CharRightRectExtend, 3309). --define(wxStyledTextCtrl_HomeRectExtend, 3310). --define(wxStyledTextCtrl_VCHomeRectExtend, 3311). --define(wxStyledTextCtrl_LineEndRectExtend, 3312). --define(wxStyledTextCtrl_PageUpRectExtend, 3313). --define(wxStyledTextCtrl_PageDownRectExtend, 3314). --define(wxStyledTextCtrl_StutteredPageUp, 3315). --define(wxStyledTextCtrl_StutteredPageUpExtend, 3316). --define(wxStyledTextCtrl_StutteredPageDown, 3317). --define(wxStyledTextCtrl_StutteredPageDownExtend, 3318). --define(wxStyledTextCtrl_WordLeftEnd, 3319). --define(wxStyledTextCtrl_WordLeftEndExtend, 3320). --define(wxStyledTextCtrl_WordRightEnd, 3321). --define(wxStyledTextCtrl_WordRightEndExtend, 3322). --define(wxStyledTextCtrl_SetWhitespaceChars, 3323). --define(wxStyledTextCtrl_SetCharsDefault, 3324). --define(wxStyledTextCtrl_AutoCompGetCurrent, 3325). --define(wxStyledTextCtrl_Allocate, 3326). --define(wxStyledTextCtrl_FindColumn, 3327). --define(wxStyledTextCtrl_GetCaretSticky, 3328). --define(wxStyledTextCtrl_SetCaretSticky, 3329). --define(wxStyledTextCtrl_ToggleCaretSticky, 3330). --define(wxStyledTextCtrl_SetPasteConvertEndings, 3331). --define(wxStyledTextCtrl_GetPasteConvertEndings, 3332). --define(wxStyledTextCtrl_SelectionDuplicate, 3333). --define(wxStyledTextCtrl_SetCaretLineBackAlpha, 3334). --define(wxStyledTextCtrl_GetCaretLineBackAlpha, 3335). --define(wxStyledTextCtrl_StartRecord, 3336). --define(wxStyledTextCtrl_StopRecord, 3337). --define(wxStyledTextCtrl_SetLexer, 3338). --define(wxStyledTextCtrl_GetLexer, 3339). --define(wxStyledTextCtrl_Colourise, 3340). --define(wxStyledTextCtrl_SetProperty, 3341). --define(wxStyledTextCtrl_SetKeyWords, 3342). --define(wxStyledTextCtrl_SetLexerLanguage, 3343). --define(wxStyledTextCtrl_GetProperty, 3344). --define(wxStyledTextCtrl_GetStyleBitsNeeded, 3345). --define(wxStyledTextCtrl_GetCurrentLine, 3346). --define(wxStyledTextCtrl_StyleSetSpec, 3347). --define(wxStyledTextCtrl_StyleSetFont, 3348). --define(wxStyledTextCtrl_StyleSetFontAttr, 3349). --define(wxStyledTextCtrl_StyleSetCharacterSet, 3350). --define(wxStyledTextCtrl_StyleSetFontEncoding, 3351). --define(wxStyledTextCtrl_CmdKeyExecute, 3352). --define(wxStyledTextCtrl_SetMargins, 3353). --define(wxStyledTextCtrl_GetSelection, 3354). --define(wxStyledTextCtrl_PointFromPosition, 3355). --define(wxStyledTextCtrl_ScrollToLine, 3356). --define(wxStyledTextCtrl_ScrollToColumn, 3357). --define(wxStyledTextCtrl_SendMsg, 3358). --define(wxStyledTextCtrl_SetVScrollBar, 3359). --define(wxStyledTextCtrl_SetHScrollBar, 3360). --define(wxStyledTextCtrl_GetLastKeydownProcessed, 3361). --define(wxStyledTextCtrl_SetLastKeydownProcessed, 3362). --define(wxStyledTextCtrl_SaveFile, 3363). --define(wxStyledTextCtrl_LoadFile, 3364). --define(wxStyledTextCtrl_DoDragOver, 3365). --define(wxStyledTextCtrl_DoDropText, 3366). --define(wxStyledTextCtrl_GetUseAntiAliasing, 3367). --define(wxStyledTextCtrl_AddTextRaw, 3368). --define(wxStyledTextCtrl_InsertTextRaw, 3369). --define(wxStyledTextCtrl_GetCurLineRaw, 3370). --define(wxStyledTextCtrl_GetLineRaw, 3371). --define(wxStyledTextCtrl_GetSelectedTextRaw, 3372). --define(wxStyledTextCtrl_GetTextRangeRaw, 3373). --define(wxStyledTextCtrl_SetTextRaw, 3374). --define(wxStyledTextCtrl_GetTextRaw, 3375). --define(wxStyledTextCtrl_AppendTextRaw, 3376). --define(wxArtProvider_GetBitmap, 3377). --define(wxArtProvider_GetIcon, 3378). --define(wxTreeEvent_GetKeyCode, 3379). --define(wxTreeEvent_GetItem, 3380). --define(wxTreeEvent_GetKeyEvent, 3381). --define(wxTreeEvent_GetLabel, 3382). --define(wxTreeEvent_GetOldItem, 3383). --define(wxTreeEvent_GetPoint, 3384). --define(wxTreeEvent_IsEditCancelled, 3385). --define(wxTreeEvent_SetToolTip, 3386). --define(wxNotebookEvent_GetOldSelection, 3387). --define(wxNotebookEvent_GetSelection, 3388). --define(wxNotebookEvent_SetOldSelection, 3389). --define(wxNotebookEvent_SetSelection, 3390). --define(wxFileDataObject_new, 3391). --define(wxFileDataObject_AddFile, 3392). --define(wxFileDataObject_GetFilenames, 3393). --define(wxFileDataObject_destroy, 3394). --define(wxTextDataObject_new, 3395). --define(wxTextDataObject_GetTextLength, 3396). --define(wxTextDataObject_GetText, 3397). --define(wxTextDataObject_SetText, 3398). --define(wxTextDataObject_destroy, 3399). --define(wxBitmapDataObject_new_1_1, 3400). --define(wxBitmapDataObject_new_1_0, 3401). --define(wxBitmapDataObject_GetBitmap, 3402). --define(wxBitmapDataObject_SetBitmap, 3403). --define(wxBitmapDataObject_destroy, 3404). --define(wxClipboard_new, 3406). --define(wxClipboard_destruct, 3407). --define(wxClipboard_AddData, 3408). --define(wxClipboard_Clear, 3409). --define(wxClipboard_Close, 3410). --define(wxClipboard_Flush, 3411). --define(wxClipboard_GetData, 3412). --define(wxClipboard_IsOpened, 3413). --define(wxClipboard_Open, 3414). --define(wxClipboard_SetData, 3415). --define(wxClipboard_UsePrimarySelection, 3417). --define(wxClipboard_IsSupported, 3418). --define(wxClipboard_Get, 3419). --define(wxSpinEvent_GetPosition, 3420). --define(wxSpinEvent_SetPosition, 3421). --define(wxSplitterWindow_new_0, 3422). --define(wxSplitterWindow_new_2, 3423). --define(wxSplitterWindow_destruct, 3424). --define(wxSplitterWindow_Create, 3425). --define(wxSplitterWindow_GetMinimumPaneSize, 3426). --define(wxSplitterWindow_GetSashGravity, 3427). --define(wxSplitterWindow_GetSashPosition, 3428). --define(wxSplitterWindow_GetSplitMode, 3429). --define(wxSplitterWindow_GetWindow1, 3430). --define(wxSplitterWindow_GetWindow2, 3431). --define(wxSplitterWindow_Initialize, 3432). --define(wxSplitterWindow_IsSplit, 3433). --define(wxSplitterWindow_ReplaceWindow, 3434). --define(wxSplitterWindow_SetSashGravity, 3435). --define(wxSplitterWindow_SetSashPosition, 3436). --define(wxSplitterWindow_SetSashSize, 3437). --define(wxSplitterWindow_SetMinimumPaneSize, 3438). --define(wxSplitterWindow_SetSplitMode, 3439). --define(wxSplitterWindow_SplitHorizontally, 3440). --define(wxSplitterWindow_SplitVertically, 3441). --define(wxSplitterWindow_Unsplit, 3442). --define(wxSplitterWindow_UpdateSize, 3443). --define(wxSplitterEvent_GetSashPosition, 3444). --define(wxSplitterEvent_GetX, 3445). --define(wxSplitterEvent_GetY, 3446). --define(wxSplitterEvent_GetWindowBeingRemoved, 3447). --define(wxSplitterEvent_SetSashPosition, 3448). --define(wxHtmlWindow_new_0, 3449). --define(wxHtmlWindow_new_2, 3450). --define(wxHtmlWindow_AppendToPage, 3451). --define(wxHtmlWindow_GetOpenedAnchor, 3452). --define(wxHtmlWindow_GetOpenedPage, 3453). --define(wxHtmlWindow_GetOpenedPageTitle, 3454). --define(wxHtmlWindow_GetRelatedFrame, 3455). --define(wxHtmlWindow_HistoryBack, 3456). --define(wxHtmlWindow_HistoryCanBack, 3457). --define(wxHtmlWindow_HistoryCanForward, 3458). --define(wxHtmlWindow_HistoryClear, 3459). --define(wxHtmlWindow_HistoryForward, 3460). --define(wxHtmlWindow_LoadFile, 3461). --define(wxHtmlWindow_LoadPage, 3462). --define(wxHtmlWindow_SelectAll, 3463). --define(wxHtmlWindow_SelectionToText, 3464). --define(wxHtmlWindow_SelectLine, 3465). --define(wxHtmlWindow_SelectWord, 3466). --define(wxHtmlWindow_SetBorders, 3467). --define(wxHtmlWindow_SetFonts, 3468). --define(wxHtmlWindow_SetPage, 3469). --define(wxHtmlWindow_SetRelatedFrame, 3470). --define(wxHtmlWindow_SetRelatedStatusBar, 3471). --define(wxHtmlWindow_ToText, 3472). --define(wxHtmlWindow_destroy, 3473). --define(wxHtmlLinkEvent_GetLinkInfo, 3474). --define(wxAuiNotebookEvent_SetSelection, 3475). --define(wxAuiNotebookEvent_GetSelection, 3476). --define(wxAuiNotebookEvent_SetOldSelection, 3477). --define(wxAuiNotebookEvent_GetOldSelection, 3478). --define(wxAuiNotebookEvent_SetDragSource, 3479). --define(wxAuiNotebookEvent_GetDragSource, 3480). --define(wxAuiManagerEvent_SetManager, 3481). --define(wxAuiManagerEvent_GetManager, 3482). --define(wxAuiManagerEvent_SetPane, 3483). --define(wxAuiManagerEvent_GetPane, 3484). --define(wxAuiManagerEvent_SetButton, 3485). --define(wxAuiManagerEvent_GetButton, 3486). --define(wxAuiManagerEvent_SetDC, 3487). --define(wxAuiManagerEvent_GetDC, 3488). --define(wxAuiManagerEvent_Veto, 3489). --define(wxAuiManagerEvent_GetVeto, 3490). --define(wxAuiManagerEvent_SetCanVeto, 3491). --define(wxAuiManagerEvent_CanVeto, 3492). --define(wxLogNull_new, 3493). --define(wxLogNull_destroy, 3494). +-define(wxTreeCtrl_EditLabel, 2010). +-define(wxTreeCtrl_EnsureVisible, 2011). +-define(wxTreeCtrl_Expand, 2012). +-define(wxTreeCtrl_GetBoundingRect, 2013). +-define(wxTreeCtrl_GetChildrenCount, 2015). +-define(wxTreeCtrl_GetCount, 2016). +-define(wxTreeCtrl_GetEditControl, 2017). +-define(wxTreeCtrl_GetFirstChild, 2018). +-define(wxTreeCtrl_GetNextChild, 2019). +-define(wxTreeCtrl_GetFirstVisibleItem, 2020). +-define(wxTreeCtrl_GetImageList, 2021). +-define(wxTreeCtrl_GetIndent, 2022). +-define(wxTreeCtrl_GetItemBackgroundColour, 2023). +-define(wxTreeCtrl_GetItemData, 2024). +-define(wxTreeCtrl_GetItemFont, 2025). +-define(wxTreeCtrl_GetItemImage_1, 2026). +-define(wxTreeCtrl_GetItemImage_2, 2027). +-define(wxTreeCtrl_GetItemText, 2028). +-define(wxTreeCtrl_GetItemTextColour, 2029). +-define(wxTreeCtrl_GetLastChild, 2030). +-define(wxTreeCtrl_GetNextSibling, 2031). +-define(wxTreeCtrl_GetNextVisible, 2032). +-define(wxTreeCtrl_GetItemParent, 2033). +-define(wxTreeCtrl_GetPrevSibling, 2034). +-define(wxTreeCtrl_GetPrevVisible, 2035). +-define(wxTreeCtrl_GetRootItem, 2036). +-define(wxTreeCtrl_GetSelection, 2037). +-define(wxTreeCtrl_GetSelections, 2038). +-define(wxTreeCtrl_GetStateImageList, 2039). +-define(wxTreeCtrl_HitTest, 2040). +-define(wxTreeCtrl_InsertItem, 2042). +-define(wxTreeCtrl_IsBold, 2043). +-define(wxTreeCtrl_IsExpanded, 2044). +-define(wxTreeCtrl_IsSelected, 2045). +-define(wxTreeCtrl_IsVisible, 2046). +-define(wxTreeCtrl_ItemHasChildren, 2047). +-define(wxTreeCtrl_PrependItem, 2048). +-define(wxTreeCtrl_ScrollTo, 2049). +-define(wxTreeCtrl_SelectItem_1, 2050). +-define(wxTreeCtrl_SelectItem_2, 2051). +-define(wxTreeCtrl_SetIndent, 2052). +-define(wxTreeCtrl_SetImageList, 2053). +-define(wxTreeCtrl_SetItemBackgroundColour, 2054). +-define(wxTreeCtrl_SetItemBold, 2055). +-define(wxTreeCtrl_SetItemData, 2056). +-define(wxTreeCtrl_SetItemDropHighlight, 2057). +-define(wxTreeCtrl_SetItemFont, 2058). +-define(wxTreeCtrl_SetItemHasChildren, 2059). +-define(wxTreeCtrl_SetItemImage_2, 2060). +-define(wxTreeCtrl_SetItemImage_3, 2061). +-define(wxTreeCtrl_SetItemText, 2062). +-define(wxTreeCtrl_SetItemTextColour, 2063). +-define(wxTreeCtrl_SetStateImageList, 2064). +-define(wxTreeCtrl_SetWindowStyle, 2065). +-define(wxTreeCtrl_SortChildren, 2066). +-define(wxTreeCtrl_Toggle, 2067). +-define(wxTreeCtrl_ToggleItemSelection, 2068). +-define(wxTreeCtrl_Unselect, 2069). +-define(wxTreeCtrl_UnselectAll, 2070). +-define(wxTreeCtrl_UnselectItem, 2071). +-define(wxScrollBar_new_0, 2072). +-define(wxScrollBar_new_3, 2073). +-define(wxScrollBar_destruct, 2074). +-define(wxScrollBar_Create, 2075). +-define(wxScrollBar_GetRange, 2076). +-define(wxScrollBar_GetPageSize, 2077). +-define(wxScrollBar_GetThumbPosition, 2078). +-define(wxScrollBar_GetThumbSize, 2079). +-define(wxScrollBar_SetThumbPosition, 2080). +-define(wxScrollBar_SetScrollbar, 2081). +-define(wxSpinButton_new_2, 2083). +-define(wxSpinButton_new_0, 2084). +-define(wxSpinButton_Create, 2085). +-define(wxSpinButton_GetMax, 2086). +-define(wxSpinButton_GetMin, 2087). +-define(wxSpinButton_GetValue, 2088). +-define(wxSpinButton_SetRange, 2089). +-define(wxSpinButton_SetValue, 2090). +-define(wxSpinButton_destroy, 2091). +-define(wxSpinCtrl_new_0, 2092). +-define(wxSpinCtrl_new_2, 2093). +-define(wxSpinCtrl_Create, 2095). +-define(wxSpinCtrl_SetValue_1_1, 2098). +-define(wxSpinCtrl_SetValue_1_0, 2099). +-define(wxSpinCtrl_GetValue, 2101). +-define(wxSpinCtrl_SetRange, 2103). +-define(wxSpinCtrl_SetSelection, 2104). +-define(wxSpinCtrl_GetMin, 2106). +-define(wxSpinCtrl_GetMax, 2108). +-define(wxSpinCtrl_destroy, 2109). +-define(wxStaticText_new_0, 2110). +-define(wxStaticText_new_4, 2111). +-define(wxStaticText_Create, 2112). +-define(wxStaticText_GetLabel, 2113). +-define(wxStaticText_SetLabel, 2114). +-define(wxStaticText_Wrap, 2115). +-define(wxStaticText_destroy, 2116). +-define(wxStaticBitmap_new_0, 2117). +-define(wxStaticBitmap_new_4, 2118). +-define(wxStaticBitmap_Create, 2119). +-define(wxStaticBitmap_GetBitmap, 2120). +-define(wxStaticBitmap_SetBitmap, 2121). +-define(wxStaticBitmap_destroy, 2122). +-define(wxRadioBox_new, 2123). +-define(wxRadioBox_destruct, 2125). +-define(wxRadioBox_Create, 2126). +-define(wxRadioBox_Enable_2, 2127). +-define(wxRadioBox_Enable_1, 2128). +-define(wxRadioBox_GetSelection, 2129). +-define(wxRadioBox_GetString, 2130). +-define(wxRadioBox_SetSelection, 2131). +-define(wxRadioBox_Show_2, 2132). +-define(wxRadioBox_Show_1, 2133). +-define(wxRadioBox_GetColumnCount, 2134). +-define(wxRadioBox_GetItemHelpText, 2135). +-define(wxRadioBox_GetItemToolTip, 2136). +-define(wxRadioBox_GetItemFromPoint, 2138). +-define(wxRadioBox_GetRowCount, 2139). +-define(wxRadioBox_IsItemEnabled, 2140). +-define(wxRadioBox_IsItemShown, 2141). +-define(wxRadioBox_SetItemHelpText, 2142). +-define(wxRadioBox_SetItemToolTip, 2143). +-define(wxRadioButton_new_0, 2144). +-define(wxRadioButton_new_4, 2145). +-define(wxRadioButton_Create, 2146). +-define(wxRadioButton_GetValue, 2147). +-define(wxRadioButton_SetValue, 2148). +-define(wxRadioButton_destroy, 2149). +-define(wxSlider_new_6, 2151). +-define(wxSlider_new_0, 2152). +-define(wxSlider_Create, 2153). +-define(wxSlider_GetLineSize, 2154). +-define(wxSlider_GetMax, 2155). +-define(wxSlider_GetMin, 2156). +-define(wxSlider_GetPageSize, 2157). +-define(wxSlider_GetThumbLength, 2158). +-define(wxSlider_GetValue, 2159). +-define(wxSlider_SetLineSize, 2160). +-define(wxSlider_SetPageSize, 2161). +-define(wxSlider_SetRange, 2162). +-define(wxSlider_SetThumbLength, 2163). +-define(wxSlider_SetValue, 2164). +-define(wxSlider_destroy, 2165). +-define(wxDialog_new_4, 2167). +-define(wxDialog_new_0, 2168). +-define(wxDialog_destruct, 2170). +-define(wxDialog_Create, 2171). +-define(wxDialog_CreateButtonSizer, 2172). +-define(wxDialog_CreateStdDialogButtonSizer, 2173). +-define(wxDialog_EndModal, 2174). +-define(wxDialog_GetAffirmativeId, 2175). +-define(wxDialog_GetReturnCode, 2176). +-define(wxDialog_IsModal, 2177). +-define(wxDialog_SetAffirmativeId, 2178). +-define(wxDialog_SetReturnCode, 2179). +-define(wxDialog_Show, 2180). +-define(wxDialog_ShowModal, 2181). +-define(wxColourDialog_new_0, 2182). +-define(wxColourDialog_new_2, 2183). +-define(wxColourDialog_destruct, 2184). +-define(wxColourDialog_Create, 2185). +-define(wxColourDialog_GetColourData, 2186). +-define(wxColourData_new_0, 2187). +-define(wxColourData_new_1, 2188). +-define(wxColourData_destruct, 2189). +-define(wxColourData_GetChooseFull, 2190). +-define(wxColourData_GetColour, 2191). +-define(wxColourData_GetCustomColour, 2193). +-define(wxColourData_SetChooseFull, 2194). +-define(wxColourData_SetColour, 2195). +-define(wxColourData_SetCustomColour, 2196). +-define(wxPalette_new_0, 2197). +-define(wxPalette_new_4, 2198). +-define(wxPalette_destruct, 2200). +-define(wxPalette_Create, 2201). +-define(wxPalette_GetColoursCount, 2202). +-define(wxPalette_GetPixel, 2203). +-define(wxPalette_GetRGB, 2204). +-define(wxPalette_IsOk, 2205). +-define(wxDirDialog_new, 2209). +-define(wxDirDialog_destruct, 2210). +-define(wxDirDialog_GetPath, 2211). +-define(wxDirDialog_GetMessage, 2212). +-define(wxDirDialog_SetMessage, 2213). +-define(wxDirDialog_SetPath, 2214). +-define(wxFileDialog_new, 2218). +-define(wxFileDialog_destruct, 2219). +-define(wxFileDialog_GetDirectory, 2220). +-define(wxFileDialog_GetFilename, 2221). +-define(wxFileDialog_GetFilenames, 2222). +-define(wxFileDialog_GetFilterIndex, 2223). +-define(wxFileDialog_GetMessage, 2224). +-define(wxFileDialog_GetPath, 2225). +-define(wxFileDialog_GetPaths, 2226). +-define(wxFileDialog_GetWildcard, 2227). +-define(wxFileDialog_SetDirectory, 2228). +-define(wxFileDialog_SetFilename, 2229). +-define(wxFileDialog_SetFilterIndex, 2230). +-define(wxFileDialog_SetMessage, 2231). +-define(wxFileDialog_SetPath, 2232). +-define(wxFileDialog_SetWildcard, 2233). +-define(wxPickerBase_SetInternalMargin, 2234). +-define(wxPickerBase_GetInternalMargin, 2235). +-define(wxPickerBase_SetTextCtrlProportion, 2236). +-define(wxPickerBase_SetPickerCtrlProportion, 2237). +-define(wxPickerBase_GetTextCtrlProportion, 2238). +-define(wxPickerBase_GetPickerCtrlProportion, 2239). +-define(wxPickerBase_HasTextCtrl, 2240). +-define(wxPickerBase_GetTextCtrl, 2241). +-define(wxPickerBase_IsTextCtrlGrowable, 2242). +-define(wxPickerBase_SetPickerCtrlGrowable, 2243). +-define(wxPickerBase_SetTextCtrlGrowable, 2244). +-define(wxPickerBase_IsPickerCtrlGrowable, 2245). +-define(wxFilePickerCtrl_new_0, 2246). +-define(wxFilePickerCtrl_new_3, 2247). +-define(wxFilePickerCtrl_Create, 2248). +-define(wxFilePickerCtrl_GetPath, 2249). +-define(wxFilePickerCtrl_SetPath, 2250). +-define(wxFilePickerCtrl_destroy, 2251). +-define(wxDirPickerCtrl_new_0, 2252). +-define(wxDirPickerCtrl_new_3, 2253). +-define(wxDirPickerCtrl_Create, 2254). +-define(wxDirPickerCtrl_GetPath, 2255). +-define(wxDirPickerCtrl_SetPath, 2256). +-define(wxDirPickerCtrl_destroy, 2257). +-define(wxColourPickerCtrl_new_0, 2258). +-define(wxColourPickerCtrl_new_3, 2259). +-define(wxColourPickerCtrl_Create, 2260). +-define(wxColourPickerCtrl_GetColour, 2261). +-define(wxColourPickerCtrl_SetColour_1_1, 2262). +-define(wxColourPickerCtrl_SetColour_1_0, 2263). +-define(wxColourPickerCtrl_destroy, 2264). +-define(wxDatePickerCtrl_new_0, 2265). +-define(wxDatePickerCtrl_new_3, 2266). +-define(wxDatePickerCtrl_GetRange, 2267). +-define(wxDatePickerCtrl_GetValue, 2268). +-define(wxDatePickerCtrl_SetRange, 2269). +-define(wxDatePickerCtrl_SetValue, 2270). +-define(wxDatePickerCtrl_destroy, 2271). +-define(wxFontPickerCtrl_new_0, 2272). +-define(wxFontPickerCtrl_new_3, 2273). +-define(wxFontPickerCtrl_Create, 2274). +-define(wxFontPickerCtrl_GetSelectedFont, 2275). +-define(wxFontPickerCtrl_SetSelectedFont, 2276). +-define(wxFontPickerCtrl_GetMaxPointSize, 2277). +-define(wxFontPickerCtrl_SetMaxPointSize, 2278). +-define(wxFontPickerCtrl_destroy, 2279). +-define(wxFindReplaceDialog_new_0, 2282). +-define(wxFindReplaceDialog_new_4, 2283). +-define(wxFindReplaceDialog_destruct, 2284). +-define(wxFindReplaceDialog_Create, 2285). +-define(wxFindReplaceDialog_GetData, 2286). +-define(wxFindReplaceData_new_0, 2287). +-define(wxFindReplaceData_new_1, 2288). +-define(wxFindReplaceData_GetFindString, 2289). +-define(wxFindReplaceData_GetReplaceString, 2290). +-define(wxFindReplaceData_GetFlags, 2291). +-define(wxFindReplaceData_SetFlags, 2292). +-define(wxFindReplaceData_SetFindString, 2293). +-define(wxFindReplaceData_SetReplaceString, 2294). +-define(wxFindReplaceData_destroy, 2295). +-define(wxMultiChoiceDialog_new_0, 2296). +-define(wxMultiChoiceDialog_new_5, 2298). +-define(wxMultiChoiceDialog_GetSelections, 2299). +-define(wxMultiChoiceDialog_SetSelections, 2300). +-define(wxMultiChoiceDialog_destroy, 2301). +-define(wxSingleChoiceDialog_new_0, 2302). +-define(wxSingleChoiceDialog_new_5, 2304). +-define(wxSingleChoiceDialog_GetSelection, 2305). +-define(wxSingleChoiceDialog_GetStringSelection, 2306). +-define(wxSingleChoiceDialog_SetSelection, 2307). +-define(wxSingleChoiceDialog_destroy, 2308). +-define(wxTextEntryDialog_new, 2309). +-define(wxTextEntryDialog_GetValue, 2310). +-define(wxTextEntryDialog_SetValue, 2311). +-define(wxTextEntryDialog_destroy, 2312). +-define(wxPasswordEntryDialog_new, 2313). +-define(wxPasswordEntryDialog_destroy, 2314). +-define(wxFontData_new_0, 2315). +-define(wxFontData_new_1, 2316). +-define(wxFontData_destruct, 2317). +-define(wxFontData_EnableEffects, 2318). +-define(wxFontData_GetAllowSymbols, 2319). +-define(wxFontData_GetColour, 2320). +-define(wxFontData_GetChosenFont, 2321). +-define(wxFontData_GetEnableEffects, 2322). +-define(wxFontData_GetInitialFont, 2323). +-define(wxFontData_GetShowHelp, 2324). +-define(wxFontData_SetAllowSymbols, 2325). +-define(wxFontData_SetChosenFont, 2326). +-define(wxFontData_SetColour, 2327). +-define(wxFontData_SetInitialFont, 2328). +-define(wxFontData_SetRange, 2329). +-define(wxFontData_SetShowHelp, 2330). +-define(wxFontDialog_new_0, 2334). +-define(wxFontDialog_new_2, 2336). +-define(wxFontDialog_Create, 2338). +-define(wxFontDialog_GetFontData, 2339). +-define(wxFontDialog_destroy, 2341). +-define(wxProgressDialog_new, 2342). +-define(wxProgressDialog_destruct, 2343). +-define(wxProgressDialog_Resume, 2344). +-define(wxProgressDialog_Update_2, 2345). +-define(wxProgressDialog_Update_0, 2346). +-define(wxMessageDialog_new, 2347). +-define(wxMessageDialog_destruct, 2348). +-define(wxPageSetupDialog_new, 2349). +-define(wxPageSetupDialog_destruct, 2350). +-define(wxPageSetupDialog_GetPageSetupData, 2351). +-define(wxPageSetupDialog_ShowModal, 2352). +-define(wxPageSetupDialogData_new_0, 2353). +-define(wxPageSetupDialogData_new_1_0, 2354). +-define(wxPageSetupDialogData_new_1_1, 2355). +-define(wxPageSetupDialogData_destruct, 2356). +-define(wxPageSetupDialogData_EnableHelp, 2357). +-define(wxPageSetupDialogData_EnableMargins, 2358). +-define(wxPageSetupDialogData_EnableOrientation, 2359). +-define(wxPageSetupDialogData_EnablePaper, 2360). +-define(wxPageSetupDialogData_EnablePrinter, 2361). +-define(wxPageSetupDialogData_GetDefaultMinMargins, 2362). +-define(wxPageSetupDialogData_GetEnableMargins, 2363). +-define(wxPageSetupDialogData_GetEnableOrientation, 2364). +-define(wxPageSetupDialogData_GetEnablePaper, 2365). +-define(wxPageSetupDialogData_GetEnablePrinter, 2366). +-define(wxPageSetupDialogData_GetEnableHelp, 2367). +-define(wxPageSetupDialogData_GetDefaultInfo, 2368). +-define(wxPageSetupDialogData_GetMarginTopLeft, 2369). +-define(wxPageSetupDialogData_GetMarginBottomRight, 2370). +-define(wxPageSetupDialogData_GetMinMarginTopLeft, 2371). +-define(wxPageSetupDialogData_GetMinMarginBottomRight, 2372). +-define(wxPageSetupDialogData_GetPaperId, 2373). +-define(wxPageSetupDialogData_GetPaperSize, 2374). +-define(wxPageSetupDialogData_GetPrintData, 2376). +-define(wxPageSetupDialogData_IsOk, 2377). +-define(wxPageSetupDialogData_SetDefaultInfo, 2378). +-define(wxPageSetupDialogData_SetDefaultMinMargins, 2379). +-define(wxPageSetupDialogData_SetMarginTopLeft, 2380). +-define(wxPageSetupDialogData_SetMarginBottomRight, 2381). +-define(wxPageSetupDialogData_SetMinMarginTopLeft, 2382). +-define(wxPageSetupDialogData_SetMinMarginBottomRight, 2383). +-define(wxPageSetupDialogData_SetPaperId, 2384). +-define(wxPageSetupDialogData_SetPaperSize_1_1, 2385). +-define(wxPageSetupDialogData_SetPaperSize_1_0, 2386). +-define(wxPageSetupDialogData_SetPrintData, 2387). +-define(wxPrintDialog_new_2_0, 2388). +-define(wxPrintDialog_new_2_1, 2389). +-define(wxPrintDialog_destruct, 2390). +-define(wxPrintDialog_GetPrintDialogData, 2391). +-define(wxPrintDialog_GetPrintDC, 2392). +-define(wxPrintDialogData_new_0, 2393). +-define(wxPrintDialogData_new_1_1, 2394). +-define(wxPrintDialogData_new_1_0, 2395). +-define(wxPrintDialogData_destruct, 2396). +-define(wxPrintDialogData_EnableHelp, 2397). +-define(wxPrintDialogData_EnablePageNumbers, 2398). +-define(wxPrintDialogData_EnablePrintToFile, 2399). +-define(wxPrintDialogData_EnableSelection, 2400). +-define(wxPrintDialogData_GetAllPages, 2401). +-define(wxPrintDialogData_GetCollate, 2402). +-define(wxPrintDialogData_GetFromPage, 2403). +-define(wxPrintDialogData_GetMaxPage, 2404). +-define(wxPrintDialogData_GetMinPage, 2405). +-define(wxPrintDialogData_GetNoCopies, 2406). +-define(wxPrintDialogData_GetPrintData, 2407). +-define(wxPrintDialogData_GetPrintToFile, 2408). +-define(wxPrintDialogData_GetSelection, 2409). +-define(wxPrintDialogData_GetToPage, 2410). +-define(wxPrintDialogData_IsOk, 2411). +-define(wxPrintDialogData_SetCollate, 2412). +-define(wxPrintDialogData_SetFromPage, 2413). +-define(wxPrintDialogData_SetMaxPage, 2414). +-define(wxPrintDialogData_SetMinPage, 2415). +-define(wxPrintDialogData_SetNoCopies, 2416). +-define(wxPrintDialogData_SetPrintData, 2417). +-define(wxPrintDialogData_SetPrintToFile, 2418). +-define(wxPrintDialogData_SetSelection, 2419). +-define(wxPrintDialogData_SetToPage, 2420). +-define(wxPrintData_new_0, 2421). +-define(wxPrintData_new_1, 2422). +-define(wxPrintData_destruct, 2423). +-define(wxPrintData_GetCollate, 2424). +-define(wxPrintData_GetBin, 2425). +-define(wxPrintData_GetColour, 2426). +-define(wxPrintData_GetDuplex, 2427). +-define(wxPrintData_GetNoCopies, 2428). +-define(wxPrintData_GetOrientation, 2429). +-define(wxPrintData_GetPaperId, 2430). +-define(wxPrintData_GetPrinterName, 2431). +-define(wxPrintData_GetQuality, 2432). +-define(wxPrintData_IsOk, 2433). +-define(wxPrintData_SetBin, 2434). +-define(wxPrintData_SetCollate, 2435). +-define(wxPrintData_SetColour, 2436). +-define(wxPrintData_SetDuplex, 2437). +-define(wxPrintData_SetNoCopies, 2438). +-define(wxPrintData_SetOrientation, 2439). +-define(wxPrintData_SetPaperId, 2440). +-define(wxPrintData_SetPrinterName, 2441). +-define(wxPrintData_SetQuality, 2442). +-define(wxPrintPreview_new_2, 2445). +-define(wxPrintPreview_new_3, 2446). +-define(wxPrintPreview_destruct, 2448). +-define(wxPrintPreview_GetCanvas, 2449). +-define(wxPrintPreview_GetCurrentPage, 2450). +-define(wxPrintPreview_GetFrame, 2451). +-define(wxPrintPreview_GetMaxPage, 2452). +-define(wxPrintPreview_GetMinPage, 2453). +-define(wxPrintPreview_GetPrintout, 2454). +-define(wxPrintPreview_GetPrintoutForPrinting, 2455). +-define(wxPrintPreview_IsOk, 2456). +-define(wxPrintPreview_PaintPage, 2457). +-define(wxPrintPreview_Print, 2458). +-define(wxPrintPreview_RenderPage, 2459). +-define(wxPrintPreview_SetCanvas, 2460). +-define(wxPrintPreview_SetCurrentPage, 2461). +-define(wxPrintPreview_SetFrame, 2462). +-define(wxPrintPreview_SetPrintout, 2463). +-define(wxPrintPreview_SetZoom, 2464). +-define(wxPreviewFrame_new, 2465). +-define(wxPreviewFrame_destruct, 2466). +-define(wxPreviewFrame_CreateControlBar, 2467). +-define(wxPreviewFrame_CreateCanvas, 2468). +-define(wxPreviewFrame_Initialize, 2469). +-define(wxPreviewFrame_OnCloseWindow, 2470). +-define(wxPreviewControlBar_new, 2471). +-define(wxPreviewControlBar_destruct, 2472). +-define(wxPreviewControlBar_CreateButtons, 2473). +-define(wxPreviewControlBar_GetPrintPreview, 2474). +-define(wxPreviewControlBar_GetZoomControl, 2475). +-define(wxPreviewControlBar_SetZoomControl, 2476). +-define(wxPrinter_new, 2478). +-define(wxPrinter_CreateAbortWindow, 2479). +-define(wxPrinter_GetAbort, 2480). +-define(wxPrinter_GetLastError, 2481). +-define(wxPrinter_GetPrintDialogData, 2482). +-define(wxPrinter_Print, 2483). +-define(wxPrinter_PrintDialog, 2484). +-define(wxPrinter_ReportError, 2485). +-define(wxPrinter_Setup, 2486). +-define(wxPrinter_destroy, 2487). +-define(wxXmlResource_new_1, 2488). +-define(wxXmlResource_new_2, 2489). +-define(wxXmlResource_destruct, 2490). +-define(wxXmlResource_AttachUnknownControl, 2491). +-define(wxXmlResource_ClearHandlers, 2492). +-define(wxXmlResource_CompareVersion, 2493). +-define(wxXmlResource_Get, 2494). +-define(wxXmlResource_GetFlags, 2495). +-define(wxXmlResource_GetVersion, 2496). +-define(wxXmlResource_GetXRCID, 2497). +-define(wxXmlResource_InitAllHandlers, 2498). +-define(wxXmlResource_Load, 2499). +-define(wxXmlResource_LoadBitmap, 2500). +-define(wxXmlResource_LoadDialog_2, 2501). +-define(wxXmlResource_LoadDialog_3, 2502). +-define(wxXmlResource_LoadFrame_2, 2503). +-define(wxXmlResource_LoadFrame_3, 2504). +-define(wxXmlResource_LoadIcon, 2505). +-define(wxXmlResource_LoadMenu, 2506). +-define(wxXmlResource_LoadMenuBar_2, 2507). +-define(wxXmlResource_LoadMenuBar_1, 2508). +-define(wxXmlResource_LoadPanel_2, 2509). +-define(wxXmlResource_LoadPanel_3, 2510). +-define(wxXmlResource_LoadToolBar, 2511). +-define(wxXmlResource_Set, 2512). +-define(wxXmlResource_SetFlags, 2513). +-define(wxXmlResource_Unload, 2514). +-define(wxXmlResource_xrcctrl, 2515). +-define(wxHtmlEasyPrinting_new, 2516). +-define(wxHtmlEasyPrinting_destruct, 2517). +-define(wxHtmlEasyPrinting_GetPrintData, 2518). +-define(wxHtmlEasyPrinting_GetPageSetupData, 2519). +-define(wxHtmlEasyPrinting_PreviewFile, 2520). +-define(wxHtmlEasyPrinting_PreviewText, 2521). +-define(wxHtmlEasyPrinting_PrintFile, 2522). +-define(wxHtmlEasyPrinting_PrintText, 2523). +-define(wxHtmlEasyPrinting_PageSetup, 2524). +-define(wxHtmlEasyPrinting_SetFonts, 2525). +-define(wxHtmlEasyPrinting_SetHeader, 2526). +-define(wxHtmlEasyPrinting_SetFooter, 2527). +-define(wxGLCanvas_new_2, 2529). +-define(wxGLCanvas_new_3_1, 2530). +-define(wxGLCanvas_new_3_0, 2531). +-define(wxGLCanvas_GetContext, 2532). +-define(wxGLCanvas_SetCurrent, 2534). +-define(wxGLCanvas_SwapBuffers, 2535). +-define(wxGLCanvas_destroy, 2536). +-define(wxAuiManager_new, 2537). +-define(wxAuiManager_destruct, 2538). +-define(wxAuiManager_AddPane_2_1, 2539). +-define(wxAuiManager_AddPane_3, 2540). +-define(wxAuiManager_AddPane_2_0, 2541). +-define(wxAuiManager_DetachPane, 2542). +-define(wxAuiManager_GetAllPanes, 2543). +-define(wxAuiManager_GetArtProvider, 2544). +-define(wxAuiManager_GetDockSizeConstraint, 2545). +-define(wxAuiManager_GetFlags, 2546). +-define(wxAuiManager_GetManagedWindow, 2547). +-define(wxAuiManager_GetManager, 2548). +-define(wxAuiManager_GetPane_1_1, 2549). +-define(wxAuiManager_GetPane_1_0, 2550). +-define(wxAuiManager_HideHint, 2551). +-define(wxAuiManager_InsertPane, 2552). +-define(wxAuiManager_LoadPaneInfo, 2553). +-define(wxAuiManager_LoadPerspective, 2554). +-define(wxAuiManager_SavePaneInfo, 2555). +-define(wxAuiManager_SavePerspective, 2556). +-define(wxAuiManager_SetArtProvider, 2557). +-define(wxAuiManager_SetDockSizeConstraint, 2558). +-define(wxAuiManager_SetFlags, 2559). +-define(wxAuiManager_SetManagedWindow, 2560). +-define(wxAuiManager_ShowHint, 2561). +-define(wxAuiManager_UnInit, 2562). +-define(wxAuiManager_Update, 2563). +-define(wxAuiPaneInfo_new_0, 2564). +-define(wxAuiPaneInfo_new_1, 2565). +-define(wxAuiPaneInfo_destruct, 2566). +-define(wxAuiPaneInfo_BestSize_1, 2567). +-define(wxAuiPaneInfo_BestSize_2, 2568). +-define(wxAuiPaneInfo_Bottom, 2569). +-define(wxAuiPaneInfo_BottomDockable, 2570). +-define(wxAuiPaneInfo_Caption, 2571). +-define(wxAuiPaneInfo_CaptionVisible, 2572). +-define(wxAuiPaneInfo_Centre, 2573). +-define(wxAuiPaneInfo_CentrePane, 2574). +-define(wxAuiPaneInfo_CloseButton, 2575). +-define(wxAuiPaneInfo_DefaultPane, 2576). +-define(wxAuiPaneInfo_DestroyOnClose, 2577). +-define(wxAuiPaneInfo_Direction, 2578). +-define(wxAuiPaneInfo_Dock, 2579). +-define(wxAuiPaneInfo_Dockable, 2580). +-define(wxAuiPaneInfo_Fixed, 2581). +-define(wxAuiPaneInfo_Float, 2582). +-define(wxAuiPaneInfo_Floatable, 2583). +-define(wxAuiPaneInfo_FloatingPosition_1, 2584). +-define(wxAuiPaneInfo_FloatingPosition_2, 2585). +-define(wxAuiPaneInfo_FloatingSize_1, 2586). +-define(wxAuiPaneInfo_FloatingSize_2, 2587). +-define(wxAuiPaneInfo_Gripper, 2588). +-define(wxAuiPaneInfo_GripperTop, 2589). +-define(wxAuiPaneInfo_HasBorder, 2590). +-define(wxAuiPaneInfo_HasCaption, 2591). +-define(wxAuiPaneInfo_HasCloseButton, 2592). +-define(wxAuiPaneInfo_HasFlag, 2593). +-define(wxAuiPaneInfo_HasGripper, 2594). +-define(wxAuiPaneInfo_HasGripperTop, 2595). +-define(wxAuiPaneInfo_HasMaximizeButton, 2596). +-define(wxAuiPaneInfo_HasMinimizeButton, 2597). +-define(wxAuiPaneInfo_HasPinButton, 2598). +-define(wxAuiPaneInfo_Hide, 2599). +-define(wxAuiPaneInfo_IsBottomDockable, 2600). +-define(wxAuiPaneInfo_IsDocked, 2601). +-define(wxAuiPaneInfo_IsFixed, 2602). +-define(wxAuiPaneInfo_IsFloatable, 2603). +-define(wxAuiPaneInfo_IsFloating, 2604). +-define(wxAuiPaneInfo_IsLeftDockable, 2605). +-define(wxAuiPaneInfo_IsMovable, 2606). +-define(wxAuiPaneInfo_IsOk, 2607). +-define(wxAuiPaneInfo_IsResizable, 2608). +-define(wxAuiPaneInfo_IsRightDockable, 2609). +-define(wxAuiPaneInfo_IsShown, 2610). +-define(wxAuiPaneInfo_IsToolbar, 2611). +-define(wxAuiPaneInfo_IsTopDockable, 2612). +-define(wxAuiPaneInfo_Layer, 2613). +-define(wxAuiPaneInfo_Left, 2614). +-define(wxAuiPaneInfo_LeftDockable, 2615). +-define(wxAuiPaneInfo_MaxSize_1, 2616). +-define(wxAuiPaneInfo_MaxSize_2, 2617). +-define(wxAuiPaneInfo_MaximizeButton, 2618). +-define(wxAuiPaneInfo_MinSize_1, 2619). +-define(wxAuiPaneInfo_MinSize_2, 2620). +-define(wxAuiPaneInfo_MinimizeButton, 2621). +-define(wxAuiPaneInfo_Movable, 2622). +-define(wxAuiPaneInfo_Name, 2623). +-define(wxAuiPaneInfo_PaneBorder, 2624). +-define(wxAuiPaneInfo_PinButton, 2625). +-define(wxAuiPaneInfo_Position, 2626). +-define(wxAuiPaneInfo_Resizable, 2627). +-define(wxAuiPaneInfo_Right, 2628). +-define(wxAuiPaneInfo_RightDockable, 2629). +-define(wxAuiPaneInfo_Row, 2630). +-define(wxAuiPaneInfo_SafeSet, 2631). +-define(wxAuiPaneInfo_SetFlag, 2632). +-define(wxAuiPaneInfo_Show, 2633). +-define(wxAuiPaneInfo_ToolbarPane, 2634). +-define(wxAuiPaneInfo_Top, 2635). +-define(wxAuiPaneInfo_TopDockable, 2636). +-define(wxAuiPaneInfo_Window, 2637). +-define(wxAuiNotebook_new_0, 2638). +-define(wxAuiNotebook_new_2, 2639). +-define(wxAuiNotebook_AddPage, 2640). +-define(wxAuiNotebook_Create, 2641). +-define(wxAuiNotebook_DeletePage, 2642). +-define(wxAuiNotebook_GetArtProvider, 2643). +-define(wxAuiNotebook_GetPage, 2644). +-define(wxAuiNotebook_GetPageBitmap, 2645). +-define(wxAuiNotebook_GetPageCount, 2646). +-define(wxAuiNotebook_GetPageIndex, 2647). +-define(wxAuiNotebook_GetPageText, 2648). +-define(wxAuiNotebook_GetSelection, 2649). +-define(wxAuiNotebook_InsertPage, 2650). +-define(wxAuiNotebook_RemovePage, 2651). +-define(wxAuiNotebook_SetArtProvider, 2652). +-define(wxAuiNotebook_SetFont, 2653). +-define(wxAuiNotebook_SetPageBitmap, 2654). +-define(wxAuiNotebook_SetPageText, 2655). +-define(wxAuiNotebook_SetSelection, 2656). +-define(wxAuiNotebook_SetTabCtrlHeight, 2657). +-define(wxAuiNotebook_SetUniformBitmapSize, 2658). +-define(wxAuiNotebook_destroy, 2659). +-define(wxMDIParentFrame_new_0, 2660). +-define(wxMDIParentFrame_new_4, 2661). +-define(wxMDIParentFrame_destruct, 2662). +-define(wxMDIParentFrame_ActivateNext, 2663). +-define(wxMDIParentFrame_ActivatePrevious, 2664). +-define(wxMDIParentFrame_ArrangeIcons, 2665). +-define(wxMDIParentFrame_Cascade, 2666). +-define(wxMDIParentFrame_Create, 2667). +-define(wxMDIParentFrame_GetActiveChild, 2668). +-define(wxMDIParentFrame_GetClientWindow, 2669). +-define(wxMDIParentFrame_Tile, 2670). +-define(wxMDIChildFrame_new_0, 2671). +-define(wxMDIChildFrame_new_4, 2672). +-define(wxMDIChildFrame_destruct, 2673). +-define(wxMDIChildFrame_Activate, 2674). +-define(wxMDIChildFrame_Create, 2675). +-define(wxMDIChildFrame_Maximize, 2676). +-define(wxMDIChildFrame_Restore, 2677). +-define(wxMDIClientWindow_new_0, 2678). +-define(wxMDIClientWindow_new_2, 2679). +-define(wxMDIClientWindow_destruct, 2680). +-define(wxMDIClientWindow_CreateClient, 2681). +-define(wxLayoutAlgorithm_new, 2682). +-define(wxLayoutAlgorithm_LayoutFrame, 2683). +-define(wxLayoutAlgorithm_LayoutMDIFrame, 2684). +-define(wxLayoutAlgorithm_LayoutWindow, 2685). +-define(wxLayoutAlgorithm_destroy, 2686). +-define(wxEvent_GetId, 2687). +-define(wxEvent_GetSkipped, 2688). +-define(wxEvent_GetTimestamp, 2689). +-define(wxEvent_IsCommandEvent, 2690). +-define(wxEvent_ResumePropagation, 2691). +-define(wxEvent_ShouldPropagate, 2692). +-define(wxEvent_Skip, 2693). +-define(wxEvent_StopPropagation, 2694). +-define(wxCommandEvent_getClientData, 2695). +-define(wxCommandEvent_GetExtraLong, 2696). +-define(wxCommandEvent_GetInt, 2697). +-define(wxCommandEvent_GetSelection, 2698). +-define(wxCommandEvent_GetString, 2699). +-define(wxCommandEvent_IsChecked, 2700). +-define(wxCommandEvent_IsSelection, 2701). +-define(wxCommandEvent_SetInt, 2702). +-define(wxCommandEvent_SetString, 2703). +-define(wxScrollEvent_GetOrientation, 2704). +-define(wxScrollEvent_GetPosition, 2705). +-define(wxScrollWinEvent_GetOrientation, 2706). +-define(wxScrollWinEvent_GetPosition, 2707). +-define(wxMouseEvent_AltDown, 2708). +-define(wxMouseEvent_Button, 2709). +-define(wxMouseEvent_ButtonDClick, 2710). +-define(wxMouseEvent_ButtonDown, 2711). +-define(wxMouseEvent_ButtonUp, 2712). +-define(wxMouseEvent_CmdDown, 2713). +-define(wxMouseEvent_ControlDown, 2714). +-define(wxMouseEvent_Dragging, 2715). +-define(wxMouseEvent_Entering, 2716). +-define(wxMouseEvent_GetButton, 2717). +-define(wxMouseEvent_GetPosition, 2720). +-define(wxMouseEvent_GetLogicalPosition, 2721). +-define(wxMouseEvent_GetLinesPerAction, 2722). +-define(wxMouseEvent_GetWheelRotation, 2723). +-define(wxMouseEvent_GetWheelDelta, 2724). +-define(wxMouseEvent_GetX, 2725). +-define(wxMouseEvent_GetY, 2726). +-define(wxMouseEvent_IsButton, 2727). +-define(wxMouseEvent_IsPageScroll, 2728). +-define(wxMouseEvent_Leaving, 2729). +-define(wxMouseEvent_LeftDClick, 2730). +-define(wxMouseEvent_LeftDown, 2731). +-define(wxMouseEvent_LeftIsDown, 2732). +-define(wxMouseEvent_LeftUp, 2733). +-define(wxMouseEvent_MetaDown, 2734). +-define(wxMouseEvent_MiddleDClick, 2735). +-define(wxMouseEvent_MiddleDown, 2736). +-define(wxMouseEvent_MiddleIsDown, 2737). +-define(wxMouseEvent_MiddleUp, 2738). +-define(wxMouseEvent_Moving, 2739). +-define(wxMouseEvent_RightDClick, 2740). +-define(wxMouseEvent_RightDown, 2741). +-define(wxMouseEvent_RightIsDown, 2742). +-define(wxMouseEvent_RightUp, 2743). +-define(wxMouseEvent_ShiftDown, 2744). +-define(wxSetCursorEvent_GetCursor, 2745). +-define(wxSetCursorEvent_GetX, 2746). +-define(wxSetCursorEvent_GetY, 2747). +-define(wxSetCursorEvent_HasCursor, 2748). +-define(wxSetCursorEvent_SetCursor, 2749). +-define(wxKeyEvent_AltDown, 2750). +-define(wxKeyEvent_CmdDown, 2751). +-define(wxKeyEvent_ControlDown, 2752). +-define(wxKeyEvent_GetKeyCode, 2753). +-define(wxKeyEvent_GetModifiers, 2754). +-define(wxKeyEvent_GetPosition, 2757). +-define(wxKeyEvent_GetRawKeyCode, 2758). +-define(wxKeyEvent_GetRawKeyFlags, 2759). +-define(wxKeyEvent_GetUnicodeKey, 2760). +-define(wxKeyEvent_GetX, 2761). +-define(wxKeyEvent_GetY, 2762). +-define(wxKeyEvent_HasModifiers, 2763). +-define(wxKeyEvent_MetaDown, 2764). +-define(wxKeyEvent_ShiftDown, 2765). +-define(wxSizeEvent_GetSize, 2766). +-define(wxMoveEvent_GetPosition, 2767). +-define(wxEraseEvent_GetDC, 2768). +-define(wxFocusEvent_GetWindow, 2769). +-define(wxChildFocusEvent_GetWindow, 2770). +-define(wxMenuEvent_GetMenu, 2771). +-define(wxMenuEvent_GetMenuId, 2772). +-define(wxMenuEvent_IsPopup, 2773). +-define(wxCloseEvent_CanVeto, 2774). +-define(wxCloseEvent_GetLoggingOff, 2775). +-define(wxCloseEvent_SetCanVeto, 2776). +-define(wxCloseEvent_SetLoggingOff, 2777). +-define(wxCloseEvent_Veto, 2778). +-define(wxShowEvent_SetShow, 2779). +-define(wxShowEvent_GetShow, 2780). +-define(wxIconizeEvent_Iconized, 2781). +-define(wxJoystickEvent_ButtonDown, 2782). +-define(wxJoystickEvent_ButtonIsDown, 2783). +-define(wxJoystickEvent_ButtonUp, 2784). +-define(wxJoystickEvent_GetButtonChange, 2785). +-define(wxJoystickEvent_GetButtonState, 2786). +-define(wxJoystickEvent_GetJoystick, 2787). +-define(wxJoystickEvent_GetPosition, 2788). +-define(wxJoystickEvent_GetZPosition, 2789). +-define(wxJoystickEvent_IsButton, 2790). +-define(wxJoystickEvent_IsMove, 2791). +-define(wxJoystickEvent_IsZMove, 2792). +-define(wxUpdateUIEvent_CanUpdate, 2793). +-define(wxUpdateUIEvent_Check, 2794). +-define(wxUpdateUIEvent_Enable, 2795). +-define(wxUpdateUIEvent_Show, 2796). +-define(wxUpdateUIEvent_GetChecked, 2797). +-define(wxUpdateUIEvent_GetEnabled, 2798). +-define(wxUpdateUIEvent_GetShown, 2799). +-define(wxUpdateUIEvent_GetSetChecked, 2800). +-define(wxUpdateUIEvent_GetSetEnabled, 2801). +-define(wxUpdateUIEvent_GetSetShown, 2802). +-define(wxUpdateUIEvent_GetSetText, 2803). +-define(wxUpdateUIEvent_GetText, 2804). +-define(wxUpdateUIEvent_GetMode, 2805). +-define(wxUpdateUIEvent_GetUpdateInterval, 2806). +-define(wxUpdateUIEvent_ResetUpdateTime, 2807). +-define(wxUpdateUIEvent_SetMode, 2808). +-define(wxUpdateUIEvent_SetText, 2809). +-define(wxUpdateUIEvent_SetUpdateInterval, 2810). +-define(wxMouseCaptureChangedEvent_GetCapturedWindow, 2811). +-define(wxPaletteChangedEvent_SetChangedWindow, 2812). +-define(wxPaletteChangedEvent_GetChangedWindow, 2813). +-define(wxQueryNewPaletteEvent_SetPaletteRealized, 2814). +-define(wxQueryNewPaletteEvent_GetPaletteRealized, 2815). +-define(wxNavigationKeyEvent_GetDirection, 2816). +-define(wxNavigationKeyEvent_SetDirection, 2817). +-define(wxNavigationKeyEvent_IsWindowChange, 2818). +-define(wxNavigationKeyEvent_SetWindowChange, 2819). +-define(wxNavigationKeyEvent_IsFromTab, 2820). +-define(wxNavigationKeyEvent_SetFromTab, 2821). +-define(wxNavigationKeyEvent_GetCurrentFocus, 2822). +-define(wxNavigationKeyEvent_SetCurrentFocus, 2823). +-define(wxHelpEvent_GetOrigin, 2824). +-define(wxHelpEvent_GetPosition, 2825). +-define(wxHelpEvent_SetOrigin, 2826). +-define(wxHelpEvent_SetPosition, 2827). +-define(wxContextMenuEvent_GetPosition, 2828). +-define(wxContextMenuEvent_SetPosition, 2829). +-define(wxIdleEvent_CanSend, 2830). +-define(wxIdleEvent_GetMode, 2831). +-define(wxIdleEvent_RequestMore, 2832). +-define(wxIdleEvent_MoreRequested, 2833). +-define(wxIdleEvent_SetMode, 2834). +-define(wxGridEvent_AltDown, 2835). +-define(wxGridEvent_ControlDown, 2836). +-define(wxGridEvent_GetCol, 2837). +-define(wxGridEvent_GetPosition, 2838). +-define(wxGridEvent_GetRow, 2839). +-define(wxGridEvent_MetaDown, 2840). +-define(wxGridEvent_Selecting, 2841). +-define(wxGridEvent_ShiftDown, 2842). +-define(wxNotifyEvent_Allow, 2843). +-define(wxNotifyEvent_IsAllowed, 2844). +-define(wxNotifyEvent_Veto, 2845). +-define(wxSashEvent_GetEdge, 2846). +-define(wxSashEvent_GetDragRect, 2847). +-define(wxSashEvent_GetDragStatus, 2848). +-define(wxListEvent_GetCacheFrom, 2849). +-define(wxListEvent_GetCacheTo, 2850). +-define(wxListEvent_GetKeyCode, 2851). +-define(wxListEvent_GetIndex, 2852). +-define(wxListEvent_GetColumn, 2853). +-define(wxListEvent_GetPoint, 2854). +-define(wxListEvent_GetLabel, 2855). +-define(wxListEvent_GetText, 2856). +-define(wxListEvent_GetImage, 2857). +-define(wxListEvent_GetData, 2858). +-define(wxListEvent_GetMask, 2859). +-define(wxListEvent_GetItem, 2860). +-define(wxListEvent_IsEditCancelled, 2861). +-define(wxDateEvent_GetDate, 2862). +-define(wxCalendarEvent_GetWeekDay, 2863). +-define(wxFileDirPickerEvent_GetPath, 2864). +-define(wxColourPickerEvent_GetColour, 2865). +-define(wxFontPickerEvent_GetFont, 2866). +-define(wxStyledTextEvent_GetPosition, 2867). +-define(wxStyledTextEvent_GetKey, 2868). +-define(wxStyledTextEvent_GetModifiers, 2869). +-define(wxStyledTextEvent_GetModificationType, 2870). +-define(wxStyledTextEvent_GetText, 2871). +-define(wxStyledTextEvent_GetLength, 2872). +-define(wxStyledTextEvent_GetLinesAdded, 2873). +-define(wxStyledTextEvent_GetLine, 2874). +-define(wxStyledTextEvent_GetFoldLevelNow, 2875). +-define(wxStyledTextEvent_GetFoldLevelPrev, 2876). +-define(wxStyledTextEvent_GetMargin, 2877). +-define(wxStyledTextEvent_GetMessage, 2878). +-define(wxStyledTextEvent_GetWParam, 2879). +-define(wxStyledTextEvent_GetLParam, 2880). +-define(wxStyledTextEvent_GetListType, 2881). +-define(wxStyledTextEvent_GetX, 2882). +-define(wxStyledTextEvent_GetY, 2883). +-define(wxStyledTextEvent_GetDragText, 2884). +-define(wxStyledTextEvent_GetDragAllowMove, 2885). +-define(wxStyledTextEvent_GetDragResult, 2886). +-define(wxStyledTextEvent_GetShift, 2887). +-define(wxStyledTextEvent_GetControl, 2888). +-define(wxStyledTextEvent_GetAlt, 2889). +-define(utils_wxGetKeyState, 2890). +-define(utils_wxGetMousePosition, 2891). +-define(utils_wxGetMouseState, 2892). +-define(utils_wxSetDetectableAutoRepeat, 2893). +-define(utils_wxBell, 2894). +-define(utils_wxFindMenuItemId, 2895). +-define(utils_wxGenericFindWindowAtPoint, 2896). +-define(utils_wxFindWindowAtPoint, 2897). +-define(utils_wxBeginBusyCursor, 2898). +-define(utils_wxEndBusyCursor, 2899). +-define(utils_wxIsBusy, 2900). +-define(utils_wxShutdown, 2901). +-define(utils_wxShell, 2902). +-define(utils_wxLaunchDefaultBrowser, 2903). +-define(utils_wxGetEmailAddress, 2904). +-define(utils_wxGetUserId, 2905). +-define(utils_wxGetHomeDir, 2906). +-define(utils_wxNewId, 2907). +-define(utils_wxRegisterId, 2908). +-define(utils_wxGetCurrentId, 2909). +-define(utils_wxGetOsDescription, 2910). +-define(utils_wxIsPlatformLittleEndian, 2911). +-define(utils_wxIsPlatform64Bit, 2912). +-define(wxPrintout_new, 2913). +-define(wxPrintout_destruct, 2914). +-define(wxPrintout_GetDC, 2915). +-define(wxPrintout_GetPageSizeMM, 2916). +-define(wxPrintout_GetPageSizePixels, 2917). +-define(wxPrintout_GetPaperRectPixels, 2918). +-define(wxPrintout_GetPPIPrinter, 2919). +-define(wxPrintout_GetPPIScreen, 2920). +-define(wxPrintout_GetTitle, 2921). +-define(wxPrintout_IsPreview, 2922). +-define(wxPrintout_FitThisSizeToPaper, 2923). +-define(wxPrintout_FitThisSizeToPage, 2924). +-define(wxPrintout_FitThisSizeToPageMargins, 2925). +-define(wxPrintout_MapScreenSizeToPaper, 2926). +-define(wxPrintout_MapScreenSizeToPage, 2927). +-define(wxPrintout_MapScreenSizeToPageMargins, 2928). +-define(wxPrintout_MapScreenSizeToDevice, 2929). +-define(wxPrintout_GetLogicalPaperRect, 2930). +-define(wxPrintout_GetLogicalPageRect, 2931). +-define(wxPrintout_GetLogicalPageMarginsRect, 2932). +-define(wxPrintout_SetLogicalOrigin, 2933). +-define(wxPrintout_OffsetLogicalOrigin, 2934). +-define(wxStyledTextCtrl_new_2, 2935). +-define(wxStyledTextCtrl_new_0, 2936). +-define(wxStyledTextCtrl_destruct, 2937). +-define(wxStyledTextCtrl_Create, 2938). +-define(wxStyledTextCtrl_AddText, 2939). +-define(wxStyledTextCtrl_AddStyledText, 2940). +-define(wxStyledTextCtrl_InsertText, 2941). +-define(wxStyledTextCtrl_ClearAll, 2942). +-define(wxStyledTextCtrl_ClearDocumentStyle, 2943). +-define(wxStyledTextCtrl_GetLength, 2944). +-define(wxStyledTextCtrl_GetCharAt, 2945). +-define(wxStyledTextCtrl_GetCurrentPos, 2946). +-define(wxStyledTextCtrl_GetAnchor, 2947). +-define(wxStyledTextCtrl_GetStyleAt, 2948). +-define(wxStyledTextCtrl_Redo, 2949). +-define(wxStyledTextCtrl_SetUndoCollection, 2950). +-define(wxStyledTextCtrl_SelectAll, 2951). +-define(wxStyledTextCtrl_SetSavePoint, 2952). +-define(wxStyledTextCtrl_GetStyledText, 2953). +-define(wxStyledTextCtrl_CanRedo, 2954). +-define(wxStyledTextCtrl_MarkerLineFromHandle, 2955). +-define(wxStyledTextCtrl_MarkerDeleteHandle, 2956). +-define(wxStyledTextCtrl_GetUndoCollection, 2957). +-define(wxStyledTextCtrl_GetViewWhiteSpace, 2958). +-define(wxStyledTextCtrl_SetViewWhiteSpace, 2959). +-define(wxStyledTextCtrl_PositionFromPoint, 2960). +-define(wxStyledTextCtrl_PositionFromPointClose, 2961). +-define(wxStyledTextCtrl_GotoLine, 2962). +-define(wxStyledTextCtrl_GotoPos, 2963). +-define(wxStyledTextCtrl_SetAnchor, 2964). +-define(wxStyledTextCtrl_GetCurLine, 2965). +-define(wxStyledTextCtrl_GetEndStyled, 2966). +-define(wxStyledTextCtrl_ConvertEOLs, 2967). +-define(wxStyledTextCtrl_GetEOLMode, 2968). +-define(wxStyledTextCtrl_SetEOLMode, 2969). +-define(wxStyledTextCtrl_StartStyling, 2970). +-define(wxStyledTextCtrl_SetStyling, 2971). +-define(wxStyledTextCtrl_GetBufferedDraw, 2972). +-define(wxStyledTextCtrl_SetBufferedDraw, 2973). +-define(wxStyledTextCtrl_SetTabWidth, 2974). +-define(wxStyledTextCtrl_GetTabWidth, 2975). +-define(wxStyledTextCtrl_SetCodePage, 2976). +-define(wxStyledTextCtrl_MarkerDefine, 2977). +-define(wxStyledTextCtrl_MarkerSetForeground, 2978). +-define(wxStyledTextCtrl_MarkerSetBackground, 2979). +-define(wxStyledTextCtrl_MarkerAdd, 2980). +-define(wxStyledTextCtrl_MarkerDelete, 2981). +-define(wxStyledTextCtrl_MarkerDeleteAll, 2982). +-define(wxStyledTextCtrl_MarkerGet, 2983). +-define(wxStyledTextCtrl_MarkerNext, 2984). +-define(wxStyledTextCtrl_MarkerPrevious, 2985). +-define(wxStyledTextCtrl_MarkerDefineBitmap, 2986). +-define(wxStyledTextCtrl_MarkerAddSet, 2987). +-define(wxStyledTextCtrl_MarkerSetAlpha, 2988). +-define(wxStyledTextCtrl_SetMarginType, 2989). +-define(wxStyledTextCtrl_GetMarginType, 2990). +-define(wxStyledTextCtrl_SetMarginWidth, 2991). +-define(wxStyledTextCtrl_GetMarginWidth, 2992). +-define(wxStyledTextCtrl_SetMarginMask, 2993). +-define(wxStyledTextCtrl_GetMarginMask, 2994). +-define(wxStyledTextCtrl_SetMarginSensitive, 2995). +-define(wxStyledTextCtrl_GetMarginSensitive, 2996). +-define(wxStyledTextCtrl_StyleClearAll, 2997). +-define(wxStyledTextCtrl_StyleSetForeground, 2998). +-define(wxStyledTextCtrl_StyleSetBackground, 2999). +-define(wxStyledTextCtrl_StyleSetBold, 3000). +-define(wxStyledTextCtrl_StyleSetItalic, 3001). +-define(wxStyledTextCtrl_StyleSetSize, 3002). +-define(wxStyledTextCtrl_StyleSetFaceName, 3003). +-define(wxStyledTextCtrl_StyleSetEOLFilled, 3004). +-define(wxStyledTextCtrl_StyleResetDefault, 3005). +-define(wxStyledTextCtrl_StyleSetUnderline, 3006). +-define(wxStyledTextCtrl_StyleSetCase, 3007). +-define(wxStyledTextCtrl_StyleSetHotSpot, 3008). +-define(wxStyledTextCtrl_SetSelForeground, 3009). +-define(wxStyledTextCtrl_SetSelBackground, 3010). +-define(wxStyledTextCtrl_GetSelAlpha, 3011). +-define(wxStyledTextCtrl_SetSelAlpha, 3012). +-define(wxStyledTextCtrl_SetCaretForeground, 3013). +-define(wxStyledTextCtrl_CmdKeyAssign, 3014). +-define(wxStyledTextCtrl_CmdKeyClear, 3015). +-define(wxStyledTextCtrl_CmdKeyClearAll, 3016). +-define(wxStyledTextCtrl_SetStyleBytes, 3017). +-define(wxStyledTextCtrl_StyleSetVisible, 3018). +-define(wxStyledTextCtrl_GetCaretPeriod, 3019). +-define(wxStyledTextCtrl_SetCaretPeriod, 3020). +-define(wxStyledTextCtrl_SetWordChars, 3021). +-define(wxStyledTextCtrl_BeginUndoAction, 3022). +-define(wxStyledTextCtrl_EndUndoAction, 3023). +-define(wxStyledTextCtrl_IndicatorSetStyle, 3024). +-define(wxStyledTextCtrl_IndicatorGetStyle, 3025). +-define(wxStyledTextCtrl_IndicatorSetForeground, 3026). +-define(wxStyledTextCtrl_IndicatorGetForeground, 3027). +-define(wxStyledTextCtrl_SetWhitespaceForeground, 3028). +-define(wxStyledTextCtrl_SetWhitespaceBackground, 3029). +-define(wxStyledTextCtrl_GetStyleBits, 3030). +-define(wxStyledTextCtrl_SetLineState, 3031). +-define(wxStyledTextCtrl_GetLineState, 3032). +-define(wxStyledTextCtrl_GetMaxLineState, 3033). +-define(wxStyledTextCtrl_GetCaretLineVisible, 3034). +-define(wxStyledTextCtrl_SetCaretLineVisible, 3035). +-define(wxStyledTextCtrl_GetCaretLineBackground, 3036). +-define(wxStyledTextCtrl_SetCaretLineBackground, 3037). +-define(wxStyledTextCtrl_AutoCompShow, 3038). +-define(wxStyledTextCtrl_AutoCompCancel, 3039). +-define(wxStyledTextCtrl_AutoCompActive, 3040). +-define(wxStyledTextCtrl_AutoCompPosStart, 3041). +-define(wxStyledTextCtrl_AutoCompComplete, 3042). +-define(wxStyledTextCtrl_AutoCompStops, 3043). +-define(wxStyledTextCtrl_AutoCompSetSeparator, 3044). +-define(wxStyledTextCtrl_AutoCompGetSeparator, 3045). +-define(wxStyledTextCtrl_AutoCompSelect, 3046). +-define(wxStyledTextCtrl_AutoCompSetCancelAtStart, 3047). +-define(wxStyledTextCtrl_AutoCompGetCancelAtStart, 3048). +-define(wxStyledTextCtrl_AutoCompSetFillUps, 3049). +-define(wxStyledTextCtrl_AutoCompSetChooseSingle, 3050). +-define(wxStyledTextCtrl_AutoCompGetChooseSingle, 3051). +-define(wxStyledTextCtrl_AutoCompSetIgnoreCase, 3052). +-define(wxStyledTextCtrl_AutoCompGetIgnoreCase, 3053). +-define(wxStyledTextCtrl_UserListShow, 3054). +-define(wxStyledTextCtrl_AutoCompSetAutoHide, 3055). +-define(wxStyledTextCtrl_AutoCompGetAutoHide, 3056). +-define(wxStyledTextCtrl_AutoCompSetDropRestOfWord, 3057). +-define(wxStyledTextCtrl_AutoCompGetDropRestOfWord, 3058). +-define(wxStyledTextCtrl_RegisterImage, 3059). +-define(wxStyledTextCtrl_ClearRegisteredImages, 3060). +-define(wxStyledTextCtrl_AutoCompGetTypeSeparator, 3061). +-define(wxStyledTextCtrl_AutoCompSetTypeSeparator, 3062). +-define(wxStyledTextCtrl_AutoCompSetMaxWidth, 3063). +-define(wxStyledTextCtrl_AutoCompGetMaxWidth, 3064). +-define(wxStyledTextCtrl_AutoCompSetMaxHeight, 3065). +-define(wxStyledTextCtrl_AutoCompGetMaxHeight, 3066). +-define(wxStyledTextCtrl_SetIndent, 3067). +-define(wxStyledTextCtrl_GetIndent, 3068). +-define(wxStyledTextCtrl_SetUseTabs, 3069). +-define(wxStyledTextCtrl_GetUseTabs, 3070). +-define(wxStyledTextCtrl_SetLineIndentation, 3071). +-define(wxStyledTextCtrl_GetLineIndentation, 3072). +-define(wxStyledTextCtrl_GetLineIndentPosition, 3073). +-define(wxStyledTextCtrl_GetColumn, 3074). +-define(wxStyledTextCtrl_SetUseHorizontalScrollBar, 3075). +-define(wxStyledTextCtrl_GetUseHorizontalScrollBar, 3076). +-define(wxStyledTextCtrl_SetIndentationGuides, 3077). +-define(wxStyledTextCtrl_GetIndentationGuides, 3078). +-define(wxStyledTextCtrl_SetHighlightGuide, 3079). +-define(wxStyledTextCtrl_GetHighlightGuide, 3080). +-define(wxStyledTextCtrl_GetLineEndPosition, 3081). +-define(wxStyledTextCtrl_GetCodePage, 3082). +-define(wxStyledTextCtrl_GetCaretForeground, 3083). +-define(wxStyledTextCtrl_GetReadOnly, 3084). +-define(wxStyledTextCtrl_SetCurrentPos, 3085). +-define(wxStyledTextCtrl_SetSelectionStart, 3086). +-define(wxStyledTextCtrl_GetSelectionStart, 3087). +-define(wxStyledTextCtrl_SetSelectionEnd, 3088). +-define(wxStyledTextCtrl_GetSelectionEnd, 3089). +-define(wxStyledTextCtrl_SetPrintMagnification, 3090). +-define(wxStyledTextCtrl_GetPrintMagnification, 3091). +-define(wxStyledTextCtrl_SetPrintColourMode, 3092). +-define(wxStyledTextCtrl_GetPrintColourMode, 3093). +-define(wxStyledTextCtrl_FindText, 3094). +-define(wxStyledTextCtrl_FormatRange, 3095). +-define(wxStyledTextCtrl_GetFirstVisibleLine, 3096). +-define(wxStyledTextCtrl_GetLine, 3097). +-define(wxStyledTextCtrl_GetLineCount, 3098). +-define(wxStyledTextCtrl_SetMarginLeft, 3099). +-define(wxStyledTextCtrl_GetMarginLeft, 3100). +-define(wxStyledTextCtrl_SetMarginRight, 3101). +-define(wxStyledTextCtrl_GetMarginRight, 3102). +-define(wxStyledTextCtrl_GetModify, 3103). +-define(wxStyledTextCtrl_SetSelection, 3104). +-define(wxStyledTextCtrl_GetSelectedText, 3105). +-define(wxStyledTextCtrl_GetTextRange, 3106). +-define(wxStyledTextCtrl_HideSelection, 3107). +-define(wxStyledTextCtrl_LineFromPosition, 3108). +-define(wxStyledTextCtrl_PositionFromLine, 3109). +-define(wxStyledTextCtrl_LineScroll, 3110). +-define(wxStyledTextCtrl_EnsureCaretVisible, 3111). +-define(wxStyledTextCtrl_ReplaceSelection, 3112). +-define(wxStyledTextCtrl_SetReadOnly, 3113). +-define(wxStyledTextCtrl_CanPaste, 3114). +-define(wxStyledTextCtrl_CanUndo, 3115). +-define(wxStyledTextCtrl_EmptyUndoBuffer, 3116). +-define(wxStyledTextCtrl_Undo, 3117). +-define(wxStyledTextCtrl_Cut, 3118). +-define(wxStyledTextCtrl_Copy, 3119). +-define(wxStyledTextCtrl_Paste, 3120). +-define(wxStyledTextCtrl_Clear, 3121). +-define(wxStyledTextCtrl_SetText, 3122). +-define(wxStyledTextCtrl_GetText, 3123). +-define(wxStyledTextCtrl_GetTextLength, 3124). +-define(wxStyledTextCtrl_GetOvertype, 3125). +-define(wxStyledTextCtrl_SetCaretWidth, 3126). +-define(wxStyledTextCtrl_GetCaretWidth, 3127). +-define(wxStyledTextCtrl_SetTargetStart, 3128). +-define(wxStyledTextCtrl_GetTargetStart, 3129). +-define(wxStyledTextCtrl_SetTargetEnd, 3130). +-define(wxStyledTextCtrl_GetTargetEnd, 3131). +-define(wxStyledTextCtrl_ReplaceTarget, 3132). +-define(wxStyledTextCtrl_SearchInTarget, 3133). +-define(wxStyledTextCtrl_SetSearchFlags, 3134). +-define(wxStyledTextCtrl_GetSearchFlags, 3135). +-define(wxStyledTextCtrl_CallTipShow, 3136). +-define(wxStyledTextCtrl_CallTipCancel, 3137). +-define(wxStyledTextCtrl_CallTipActive, 3138). +-define(wxStyledTextCtrl_CallTipPosAtStart, 3139). +-define(wxStyledTextCtrl_CallTipSetHighlight, 3140). +-define(wxStyledTextCtrl_CallTipSetBackground, 3141). +-define(wxStyledTextCtrl_CallTipSetForeground, 3142). +-define(wxStyledTextCtrl_CallTipSetForegroundHighlight, 3143). +-define(wxStyledTextCtrl_CallTipUseStyle, 3144). +-define(wxStyledTextCtrl_VisibleFromDocLine, 3145). +-define(wxStyledTextCtrl_DocLineFromVisible, 3146). +-define(wxStyledTextCtrl_WrapCount, 3147). +-define(wxStyledTextCtrl_SetFoldLevel, 3148). +-define(wxStyledTextCtrl_GetFoldLevel, 3149). +-define(wxStyledTextCtrl_GetLastChild, 3150). +-define(wxStyledTextCtrl_GetFoldParent, 3151). +-define(wxStyledTextCtrl_ShowLines, 3152). +-define(wxStyledTextCtrl_HideLines, 3153). +-define(wxStyledTextCtrl_GetLineVisible, 3154). +-define(wxStyledTextCtrl_SetFoldExpanded, 3155). +-define(wxStyledTextCtrl_GetFoldExpanded, 3156). +-define(wxStyledTextCtrl_ToggleFold, 3157). +-define(wxStyledTextCtrl_EnsureVisible, 3158). +-define(wxStyledTextCtrl_SetFoldFlags, 3159). +-define(wxStyledTextCtrl_EnsureVisibleEnforcePolicy, 3160). +-define(wxStyledTextCtrl_SetTabIndents, 3161). +-define(wxStyledTextCtrl_GetTabIndents, 3162). +-define(wxStyledTextCtrl_SetBackSpaceUnIndents, 3163). +-define(wxStyledTextCtrl_GetBackSpaceUnIndents, 3164). +-define(wxStyledTextCtrl_SetMouseDwellTime, 3165). +-define(wxStyledTextCtrl_GetMouseDwellTime, 3166). +-define(wxStyledTextCtrl_WordStartPosition, 3167). +-define(wxStyledTextCtrl_WordEndPosition, 3168). +-define(wxStyledTextCtrl_SetWrapMode, 3169). +-define(wxStyledTextCtrl_GetWrapMode, 3170). +-define(wxStyledTextCtrl_SetWrapVisualFlags, 3171). +-define(wxStyledTextCtrl_GetWrapVisualFlags, 3172). +-define(wxStyledTextCtrl_SetWrapVisualFlagsLocation, 3173). +-define(wxStyledTextCtrl_GetWrapVisualFlagsLocation, 3174). +-define(wxStyledTextCtrl_SetWrapStartIndent, 3175). +-define(wxStyledTextCtrl_GetWrapStartIndent, 3176). +-define(wxStyledTextCtrl_SetLayoutCache, 3177). +-define(wxStyledTextCtrl_GetLayoutCache, 3178). +-define(wxStyledTextCtrl_SetScrollWidth, 3179). +-define(wxStyledTextCtrl_GetScrollWidth, 3180). +-define(wxStyledTextCtrl_TextWidth, 3181). +-define(wxStyledTextCtrl_GetEndAtLastLine, 3182). +-define(wxStyledTextCtrl_TextHeight, 3183). +-define(wxStyledTextCtrl_SetUseVerticalScrollBar, 3184). +-define(wxStyledTextCtrl_GetUseVerticalScrollBar, 3185). +-define(wxStyledTextCtrl_AppendText, 3186). +-define(wxStyledTextCtrl_GetTwoPhaseDraw, 3187). +-define(wxStyledTextCtrl_SetTwoPhaseDraw, 3188). +-define(wxStyledTextCtrl_TargetFromSelection, 3189). +-define(wxStyledTextCtrl_LinesJoin, 3190). +-define(wxStyledTextCtrl_LinesSplit, 3191). +-define(wxStyledTextCtrl_SetFoldMarginColour, 3192). +-define(wxStyledTextCtrl_SetFoldMarginHiColour, 3193). +-define(wxStyledTextCtrl_LineDown, 3194). +-define(wxStyledTextCtrl_LineDownExtend, 3195). +-define(wxStyledTextCtrl_LineUp, 3196). +-define(wxStyledTextCtrl_LineUpExtend, 3197). +-define(wxStyledTextCtrl_CharLeft, 3198). +-define(wxStyledTextCtrl_CharLeftExtend, 3199). +-define(wxStyledTextCtrl_CharRight, 3200). +-define(wxStyledTextCtrl_CharRightExtend, 3201). +-define(wxStyledTextCtrl_WordLeft, 3202). +-define(wxStyledTextCtrl_WordLeftExtend, 3203). +-define(wxStyledTextCtrl_WordRight, 3204). +-define(wxStyledTextCtrl_WordRightExtend, 3205). +-define(wxStyledTextCtrl_Home, 3206). +-define(wxStyledTextCtrl_HomeExtend, 3207). +-define(wxStyledTextCtrl_LineEnd, 3208). +-define(wxStyledTextCtrl_LineEndExtend, 3209). +-define(wxStyledTextCtrl_DocumentStart, 3210). +-define(wxStyledTextCtrl_DocumentStartExtend, 3211). +-define(wxStyledTextCtrl_DocumentEnd, 3212). +-define(wxStyledTextCtrl_DocumentEndExtend, 3213). +-define(wxStyledTextCtrl_PageUp, 3214). +-define(wxStyledTextCtrl_PageUpExtend, 3215). +-define(wxStyledTextCtrl_PageDown, 3216). +-define(wxStyledTextCtrl_PageDownExtend, 3217). +-define(wxStyledTextCtrl_EditToggleOvertype, 3218). +-define(wxStyledTextCtrl_Cancel, 3219). +-define(wxStyledTextCtrl_DeleteBack, 3220). +-define(wxStyledTextCtrl_Tab, 3221). +-define(wxStyledTextCtrl_BackTab, 3222). +-define(wxStyledTextCtrl_NewLine, 3223). +-define(wxStyledTextCtrl_FormFeed, 3224). +-define(wxStyledTextCtrl_VCHome, 3225). +-define(wxStyledTextCtrl_VCHomeExtend, 3226). +-define(wxStyledTextCtrl_ZoomIn, 3227). +-define(wxStyledTextCtrl_ZoomOut, 3228). +-define(wxStyledTextCtrl_DelWordLeft, 3229). +-define(wxStyledTextCtrl_DelWordRight, 3230). +-define(wxStyledTextCtrl_LineCut, 3231). +-define(wxStyledTextCtrl_LineDelete, 3232). +-define(wxStyledTextCtrl_LineTranspose, 3233). +-define(wxStyledTextCtrl_LineDuplicate, 3234). +-define(wxStyledTextCtrl_LowerCase, 3235). +-define(wxStyledTextCtrl_UpperCase, 3236). +-define(wxStyledTextCtrl_LineScrollDown, 3237). +-define(wxStyledTextCtrl_LineScrollUp, 3238). +-define(wxStyledTextCtrl_DeleteBackNotLine, 3239). +-define(wxStyledTextCtrl_HomeDisplay, 3240). +-define(wxStyledTextCtrl_HomeDisplayExtend, 3241). +-define(wxStyledTextCtrl_LineEndDisplay, 3242). +-define(wxStyledTextCtrl_LineEndDisplayExtend, 3243). +-define(wxStyledTextCtrl_HomeWrapExtend, 3244). +-define(wxStyledTextCtrl_LineEndWrap, 3245). +-define(wxStyledTextCtrl_LineEndWrapExtend, 3246). +-define(wxStyledTextCtrl_VCHomeWrap, 3247). +-define(wxStyledTextCtrl_VCHomeWrapExtend, 3248). +-define(wxStyledTextCtrl_LineCopy, 3249). +-define(wxStyledTextCtrl_MoveCaretInsideView, 3250). +-define(wxStyledTextCtrl_LineLength, 3251). +-define(wxStyledTextCtrl_BraceHighlight, 3252). +-define(wxStyledTextCtrl_BraceBadLight, 3253). +-define(wxStyledTextCtrl_BraceMatch, 3254). +-define(wxStyledTextCtrl_GetViewEOL, 3255). +-define(wxStyledTextCtrl_SetViewEOL, 3256). +-define(wxStyledTextCtrl_SetModEventMask, 3257). +-define(wxStyledTextCtrl_GetEdgeColumn, 3258). +-define(wxStyledTextCtrl_SetEdgeColumn, 3259). +-define(wxStyledTextCtrl_GetEdgeMode, 3260). +-define(wxStyledTextCtrl_GetEdgeColour, 3261). +-define(wxStyledTextCtrl_SetEdgeColour, 3262). +-define(wxStyledTextCtrl_SearchAnchor, 3263). +-define(wxStyledTextCtrl_SearchNext, 3264). +-define(wxStyledTextCtrl_SearchPrev, 3265). +-define(wxStyledTextCtrl_LinesOnScreen, 3266). +-define(wxStyledTextCtrl_UsePopUp, 3267). +-define(wxStyledTextCtrl_SelectionIsRectangle, 3268). +-define(wxStyledTextCtrl_SetZoom, 3269). +-define(wxStyledTextCtrl_GetZoom, 3270). +-define(wxStyledTextCtrl_GetModEventMask, 3271). +-define(wxStyledTextCtrl_SetSTCFocus, 3272). +-define(wxStyledTextCtrl_GetSTCFocus, 3273). +-define(wxStyledTextCtrl_SetStatus, 3274). +-define(wxStyledTextCtrl_GetStatus, 3275). +-define(wxStyledTextCtrl_SetMouseDownCaptures, 3276). +-define(wxStyledTextCtrl_GetMouseDownCaptures, 3277). +-define(wxStyledTextCtrl_SetSTCCursor, 3278). +-define(wxStyledTextCtrl_GetSTCCursor, 3279). +-define(wxStyledTextCtrl_SetControlCharSymbol, 3280). +-define(wxStyledTextCtrl_GetControlCharSymbol, 3281). +-define(wxStyledTextCtrl_WordPartLeft, 3282). +-define(wxStyledTextCtrl_WordPartLeftExtend, 3283). +-define(wxStyledTextCtrl_WordPartRight, 3284). +-define(wxStyledTextCtrl_WordPartRightExtend, 3285). +-define(wxStyledTextCtrl_SetVisiblePolicy, 3286). +-define(wxStyledTextCtrl_DelLineLeft, 3287). +-define(wxStyledTextCtrl_DelLineRight, 3288). +-define(wxStyledTextCtrl_GetXOffset, 3289). +-define(wxStyledTextCtrl_ChooseCaretX, 3290). +-define(wxStyledTextCtrl_SetXCaretPolicy, 3291). +-define(wxStyledTextCtrl_SetYCaretPolicy, 3292). +-define(wxStyledTextCtrl_GetPrintWrapMode, 3293). +-define(wxStyledTextCtrl_SetHotspotActiveForeground, 3294). +-define(wxStyledTextCtrl_SetHotspotActiveBackground, 3295). +-define(wxStyledTextCtrl_SetHotspotActiveUnderline, 3296). +-define(wxStyledTextCtrl_SetHotspotSingleLine, 3297). +-define(wxStyledTextCtrl_ParaDownExtend, 3298). +-define(wxStyledTextCtrl_ParaUp, 3299). +-define(wxStyledTextCtrl_ParaUpExtend, 3300). +-define(wxStyledTextCtrl_PositionBefore, 3301). +-define(wxStyledTextCtrl_PositionAfter, 3302). +-define(wxStyledTextCtrl_CopyRange, 3303). +-define(wxStyledTextCtrl_CopyText, 3304). +-define(wxStyledTextCtrl_SetSelectionMode, 3305). +-define(wxStyledTextCtrl_GetSelectionMode, 3306). +-define(wxStyledTextCtrl_LineDownRectExtend, 3307). +-define(wxStyledTextCtrl_LineUpRectExtend, 3308). +-define(wxStyledTextCtrl_CharLeftRectExtend, 3309). +-define(wxStyledTextCtrl_CharRightRectExtend, 3310). +-define(wxStyledTextCtrl_HomeRectExtend, 3311). +-define(wxStyledTextCtrl_VCHomeRectExtend, 3312). +-define(wxStyledTextCtrl_LineEndRectExtend, 3313). +-define(wxStyledTextCtrl_PageUpRectExtend, 3314). +-define(wxStyledTextCtrl_PageDownRectExtend, 3315). +-define(wxStyledTextCtrl_StutteredPageUp, 3316). +-define(wxStyledTextCtrl_StutteredPageUpExtend, 3317). +-define(wxStyledTextCtrl_StutteredPageDown, 3318). +-define(wxStyledTextCtrl_StutteredPageDownExtend, 3319). +-define(wxStyledTextCtrl_WordLeftEnd, 3320). +-define(wxStyledTextCtrl_WordLeftEndExtend, 3321). +-define(wxStyledTextCtrl_WordRightEnd, 3322). +-define(wxStyledTextCtrl_WordRightEndExtend, 3323). +-define(wxStyledTextCtrl_SetWhitespaceChars, 3324). +-define(wxStyledTextCtrl_SetCharsDefault, 3325). +-define(wxStyledTextCtrl_AutoCompGetCurrent, 3326). +-define(wxStyledTextCtrl_Allocate, 3327). +-define(wxStyledTextCtrl_FindColumn, 3328). +-define(wxStyledTextCtrl_GetCaretSticky, 3329). +-define(wxStyledTextCtrl_SetCaretSticky, 3330). +-define(wxStyledTextCtrl_ToggleCaretSticky, 3331). +-define(wxStyledTextCtrl_SetPasteConvertEndings, 3332). +-define(wxStyledTextCtrl_GetPasteConvertEndings, 3333). +-define(wxStyledTextCtrl_SelectionDuplicate, 3334). +-define(wxStyledTextCtrl_SetCaretLineBackAlpha, 3335). +-define(wxStyledTextCtrl_GetCaretLineBackAlpha, 3336). +-define(wxStyledTextCtrl_StartRecord, 3337). +-define(wxStyledTextCtrl_StopRecord, 3338). +-define(wxStyledTextCtrl_SetLexer, 3339). +-define(wxStyledTextCtrl_GetLexer, 3340). +-define(wxStyledTextCtrl_Colourise, 3341). +-define(wxStyledTextCtrl_SetProperty, 3342). +-define(wxStyledTextCtrl_SetKeyWords, 3343). +-define(wxStyledTextCtrl_SetLexerLanguage, 3344). +-define(wxStyledTextCtrl_GetProperty, 3345). +-define(wxStyledTextCtrl_GetStyleBitsNeeded, 3346). +-define(wxStyledTextCtrl_GetCurrentLine, 3347). +-define(wxStyledTextCtrl_StyleSetSpec, 3348). +-define(wxStyledTextCtrl_StyleSetFont, 3349). +-define(wxStyledTextCtrl_StyleSetFontAttr, 3350). +-define(wxStyledTextCtrl_StyleSetCharacterSet, 3351). +-define(wxStyledTextCtrl_StyleSetFontEncoding, 3352). +-define(wxStyledTextCtrl_CmdKeyExecute, 3353). +-define(wxStyledTextCtrl_SetMargins, 3354). +-define(wxStyledTextCtrl_GetSelection, 3355). +-define(wxStyledTextCtrl_PointFromPosition, 3356). +-define(wxStyledTextCtrl_ScrollToLine, 3357). +-define(wxStyledTextCtrl_ScrollToColumn, 3358). +-define(wxStyledTextCtrl_SendMsg, 3359). +-define(wxStyledTextCtrl_SetVScrollBar, 3360). +-define(wxStyledTextCtrl_SetHScrollBar, 3361). +-define(wxStyledTextCtrl_GetLastKeydownProcessed, 3362). +-define(wxStyledTextCtrl_SetLastKeydownProcessed, 3363). +-define(wxStyledTextCtrl_SaveFile, 3364). +-define(wxStyledTextCtrl_LoadFile, 3365). +-define(wxStyledTextCtrl_DoDragOver, 3366). +-define(wxStyledTextCtrl_DoDropText, 3367). +-define(wxStyledTextCtrl_GetUseAntiAliasing, 3368). +-define(wxStyledTextCtrl_AddTextRaw, 3369). +-define(wxStyledTextCtrl_InsertTextRaw, 3370). +-define(wxStyledTextCtrl_GetCurLineRaw, 3371). +-define(wxStyledTextCtrl_GetLineRaw, 3372). +-define(wxStyledTextCtrl_GetSelectedTextRaw, 3373). +-define(wxStyledTextCtrl_GetTextRangeRaw, 3374). +-define(wxStyledTextCtrl_SetTextRaw, 3375). +-define(wxStyledTextCtrl_GetTextRaw, 3376). +-define(wxStyledTextCtrl_AppendTextRaw, 3377). +-define(wxArtProvider_GetBitmap, 3378). +-define(wxArtProvider_GetIcon, 3379). +-define(wxTreeEvent_GetKeyCode, 3380). +-define(wxTreeEvent_GetItem, 3381). +-define(wxTreeEvent_GetKeyEvent, 3382). +-define(wxTreeEvent_GetLabel, 3383). +-define(wxTreeEvent_GetOldItem, 3384). +-define(wxTreeEvent_GetPoint, 3385). +-define(wxTreeEvent_IsEditCancelled, 3386). +-define(wxTreeEvent_SetToolTip, 3387). +-define(wxNotebookEvent_GetOldSelection, 3388). +-define(wxNotebookEvent_GetSelection, 3389). +-define(wxNotebookEvent_SetOldSelection, 3390). +-define(wxNotebookEvent_SetSelection, 3391). +-define(wxFileDataObject_new, 3392). +-define(wxFileDataObject_AddFile, 3393). +-define(wxFileDataObject_GetFilenames, 3394). +-define(wxFileDataObject_destroy, 3395). +-define(wxTextDataObject_new, 3396). +-define(wxTextDataObject_GetTextLength, 3397). +-define(wxTextDataObject_GetText, 3398). +-define(wxTextDataObject_SetText, 3399). +-define(wxTextDataObject_destroy, 3400). +-define(wxBitmapDataObject_new_1_1, 3401). +-define(wxBitmapDataObject_new_1_0, 3402). +-define(wxBitmapDataObject_GetBitmap, 3403). +-define(wxBitmapDataObject_SetBitmap, 3404). +-define(wxBitmapDataObject_destroy, 3405). +-define(wxClipboard_new, 3407). +-define(wxClipboard_destruct, 3408). +-define(wxClipboard_AddData, 3409). +-define(wxClipboard_Clear, 3410). +-define(wxClipboard_Close, 3411). +-define(wxClipboard_Flush, 3412). +-define(wxClipboard_GetData, 3413). +-define(wxClipboard_IsOpened, 3414). +-define(wxClipboard_Open, 3415). +-define(wxClipboard_SetData, 3416). +-define(wxClipboard_UsePrimarySelection, 3418). +-define(wxClipboard_IsSupported, 3419). +-define(wxClipboard_Get, 3420). +-define(wxSpinEvent_GetPosition, 3421). +-define(wxSpinEvent_SetPosition, 3422). +-define(wxSplitterWindow_new_0, 3423). +-define(wxSplitterWindow_new_2, 3424). +-define(wxSplitterWindow_destruct, 3425). +-define(wxSplitterWindow_Create, 3426). +-define(wxSplitterWindow_GetMinimumPaneSize, 3427). +-define(wxSplitterWindow_GetSashGravity, 3428). +-define(wxSplitterWindow_GetSashPosition, 3429). +-define(wxSplitterWindow_GetSplitMode, 3430). +-define(wxSplitterWindow_GetWindow1, 3431). +-define(wxSplitterWindow_GetWindow2, 3432). +-define(wxSplitterWindow_Initialize, 3433). +-define(wxSplitterWindow_IsSplit, 3434). +-define(wxSplitterWindow_ReplaceWindow, 3435). +-define(wxSplitterWindow_SetSashGravity, 3436). +-define(wxSplitterWindow_SetSashPosition, 3437). +-define(wxSplitterWindow_SetSashSize, 3438). +-define(wxSplitterWindow_SetMinimumPaneSize, 3439). +-define(wxSplitterWindow_SetSplitMode, 3440). +-define(wxSplitterWindow_SplitHorizontally, 3441). +-define(wxSplitterWindow_SplitVertically, 3442). +-define(wxSplitterWindow_Unsplit, 3443). +-define(wxSplitterWindow_UpdateSize, 3444). +-define(wxSplitterEvent_GetSashPosition, 3445). +-define(wxSplitterEvent_GetX, 3446). +-define(wxSplitterEvent_GetY, 3447). +-define(wxSplitterEvent_GetWindowBeingRemoved, 3448). +-define(wxSplitterEvent_SetSashPosition, 3449). +-define(wxHtmlWindow_new_0, 3450). +-define(wxHtmlWindow_new_2, 3451). +-define(wxHtmlWindow_AppendToPage, 3452). +-define(wxHtmlWindow_GetOpenedAnchor, 3453). +-define(wxHtmlWindow_GetOpenedPage, 3454). +-define(wxHtmlWindow_GetOpenedPageTitle, 3455). +-define(wxHtmlWindow_GetRelatedFrame, 3456). +-define(wxHtmlWindow_HistoryBack, 3457). +-define(wxHtmlWindow_HistoryCanBack, 3458). +-define(wxHtmlWindow_HistoryCanForward, 3459). +-define(wxHtmlWindow_HistoryClear, 3460). +-define(wxHtmlWindow_HistoryForward, 3461). +-define(wxHtmlWindow_LoadFile, 3462). +-define(wxHtmlWindow_LoadPage, 3463). +-define(wxHtmlWindow_SelectAll, 3464). +-define(wxHtmlWindow_SelectionToText, 3465). +-define(wxHtmlWindow_SelectLine, 3466). +-define(wxHtmlWindow_SelectWord, 3467). +-define(wxHtmlWindow_SetBorders, 3468). +-define(wxHtmlWindow_SetFonts, 3469). +-define(wxHtmlWindow_SetPage, 3470). +-define(wxHtmlWindow_SetRelatedFrame, 3471). +-define(wxHtmlWindow_SetRelatedStatusBar, 3472). +-define(wxHtmlWindow_ToText, 3473). +-define(wxHtmlWindow_destroy, 3474). +-define(wxHtmlLinkEvent_GetLinkInfo, 3475). +-define(wxSystemSettings_GetColour, 3476). +-define(wxSystemSettings_GetFont, 3477). +-define(wxSystemSettings_GetMetric, 3478). +-define(wxSystemSettings_GetScreenType, 3479). +-define(wxAuiNotebookEvent_SetSelection, 3480). +-define(wxAuiNotebookEvent_GetSelection, 3481). +-define(wxAuiNotebookEvent_SetOldSelection, 3482). +-define(wxAuiNotebookEvent_GetOldSelection, 3483). +-define(wxAuiNotebookEvent_SetDragSource, 3484). +-define(wxAuiNotebookEvent_GetDragSource, 3485). +-define(wxAuiManagerEvent_SetManager, 3486). +-define(wxAuiManagerEvent_GetManager, 3487). +-define(wxAuiManagerEvent_SetPane, 3488). +-define(wxAuiManagerEvent_GetPane, 3489). +-define(wxAuiManagerEvent_SetButton, 3490). +-define(wxAuiManagerEvent_GetButton, 3491). +-define(wxAuiManagerEvent_SetDC, 3492). +-define(wxAuiManagerEvent_GetDC, 3493). +-define(wxAuiManagerEvent_Veto, 3494). +-define(wxAuiManagerEvent_GetVeto, 3495). +-define(wxAuiManagerEvent_SetCanVeto, 3496). +-define(wxAuiManagerEvent_CanVeto, 3497). +-define(wxLogNull_new, 3498). +-define(wxLogNull_destroy, 3499). diff --git a/lib/wx/test/wx_class_SUITE.erl b/lib/wx/test/wx_class_SUITE.erl index 76df6e4a23..6f43247d74 100644 --- a/lib/wx/test/wx_class_SUITE.erl +++ b/lib/wx/test/wx_class_SUITE.erl @@ -137,6 +137,9 @@ treeCtrl(Config) -> wxFrame:connect(Tree, command_tree_item_expanded), wxFrame:connect(Tree, command_tree_item_collapsed), wxFrame:connect(Frame, close_window), + + wxTreeCtrl:editLabel(Tree, Root), + wx_test_lib:wx_destroy(Frame,Config). diff --git a/lib/wx/vsn.mk b/lib/wx/vsn.mk index 4ed22d2256..c3ad3920a4 100644 --- a/lib/wx/vsn.mk +++ b/lib/wx/vsn.mk @@ -1,9 +1 @@ WX_VSN = 0.98.6 - -TICKETS = OTP-8656 - -TICKETS_0.98.5 = OTP-8330 OTP-8461 OTP-8408 OTP-8455 OTP-8462 -TICKETS_0.98.4 = OTP-8243 OTP-8250 OTP-8292 -TICKETS_0.98.3 = OTP-8138 OTP-8126 OTP-8083 -TICKETS_0.98.2 = OTP-7943 -TICKETS_0.98.1 = OTP-7875
\ No newline at end of file diff --git a/lib/xmerl/src/xmerl_dtd.erl b/lib/xmerl/src/xmerl_dtd.erl deleted file mode 100644 index e69de29bb2..0000000000 --- a/lib/xmerl/src/xmerl_dtd.erl +++ /dev/null diff --git a/lib/xmerl/vsn.mk b/lib/xmerl/vsn.mk index aee7546c3c..03d16ad6fe 100644 --- a/lib/xmerl/vsn.mk +++ b/lib/xmerl/vsn.mk @@ -1,130 +1 @@ -# -# %CopyrightBegin% -# -# Copyright Ericsson AB 2003-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% -# - XMERL_VSN = 1.2.5 - - -TICKETS = \ - OTP-8537 \ - OTP-8599 - -TICKETS_1.2.5 = \ - OTP-8537 - -TICKETS_1.2.4 = \ - OTP-8343 - -TICKETS_1.2.3 = \ - OTP-8251 \ - OTP-8252 \ - OTP-8253 - -TICKETS_1.2.2 = \ - OTP-8213 \ - OTP-8214 - -TICKETS_1.2.1 = \ - OTP-8084 \ - OTP-8153 \ - OTP-8156 - -TICKETS_1.2 = \ - OTP-6635 - -TICKETS_1.1.12 = \ - OTP-7847 - -TICKETS_1.1.11 = \ - OTP-7736 - -TICKETS_1.1.10 = \ - OTP-6053 \ - OTP-6873 \ - OTP-7430 \ - OTP-7473 \ - OTP-7496 - -TICKETS_1.1.9 = \ - OTP-5998 \ - OTP-6947 \ - OTP-7288 - -TICKETS_1.1.8 = \ - OTP-7211 \ - OTP-7214 - -TICKETS_1.1.7 = \ - OTP-7190 - -TICKETS_1.1.6 = \ - OTP-6773 \ - OTP-6777 \ - OTP-6877 \ - OTP-6910 - -TICKETS_1.1.5 = \ - OTP-6720 \ - OTP-6739 \ - OTP-6752 - -TICKETS_1.1.4 = \ - OTP-6679 - -TICKETS_1.1.3 = \ - OTP-6599 - -TICKETS_1.1.2 = \ - OTP-6507 \ - OTP-6460 - -TICKETS_1.1.1 = \ - OTP-6402 - -TICKETS_1.1 = \ - OTP-6043 \ - OTP-6099 \ - OTP-6401 - -TICKETS_1.0.5 = \ - - -TICKETS_1.0.4 = \ - OTP-5599 \ - OTP-5718 \ - OTP-5734 \ - OTP-5895 \ - OTP-5902 \ - OTP-5905 - -TICKETS_1.0.3 = \ - OTP-5587 - -TICKETS_1.0.2 = \ - OTP-5498 \ - OTP-5500 \ - OTP-5531 - -TICKETS_1.0.1 = \ - OTP-5268 \ - OTP-5301 \ - OTP-5407 - -TICKETS_1.0 = \ - OTP-5174 \ - diff --git a/make/otp.mk.in b/make/otp.mk.in index 9f0486a609..6ae7c5b456 100644 --- a/make/otp.mk.in +++ b/make/otp.mk.in @@ -25,6 +25,11 @@ .3 .1 .fig .dvi .tex .class .java .pdf .fo .psframe .pscrop .el .elc # ---------------------------------------------------- +# Cross Compiling +# ---------------------------------------------------- +CROSS_COMPILING = @CROSS_COMPILING@ + +# ---------------------------------------------------- # Common macros # ---------------------------------------------------- DEFAULT_TARGETS = opt debug release release_docs clean docs diff --git a/system/doc/reference_manual/typespec.xml b/system/doc/reference_manual/typespec.xml index a3660713e4..52dc0c943e 100755 --- a/system/doc/reference_manual/typespec.xml +++ b/system/doc/reference_manual/typespec.xml @@ -96,7 +96,7 @@ Type :: any() %% The top type, the set of all Erlang terms. | none() %% The bottom type, contains no terms. | pid() | port() - | ref() + | reference() | [] %% nil | Atom | Binary diff --git a/system/doc/top/Makefile b/system/doc/top/Makefile index 154deb006b..148fefaf13 100644 --- a/system/doc/top/Makefile +++ b/system/doc/top/Makefile @@ -111,6 +111,10 @@ GLOSSARY = $(HTMLDIR)/glossary.html GLOSSARY_SRC = $(ERL_TOP)/system/internal_tools/doctools/src/glossary.erl GLOSSARY_SCRIPT = $(EBIN)/glossary.$(EMULATOR) +TEMPLATES = \ + templates/index.html.src \ + templates/applications.html.src + #-------------------------------------------------------------------------- $(INDEX_SCRIPT): $(INDEX_SRC) @@ -119,8 +123,14 @@ $(INDEX_SCRIPT): $(INDEX_SRC) # We don't list toc_*.html as targets because we don't know $(HTMLDIR)/index.html + $(HTMLDIR)/applications.html: $(INDEX_SCRIPT) echo "Generating index $@" - $(ERL) -noshell -pa $(EBIN) -s erl_html_tools top_index $(ERL_TOP) \ - $(HTMLDIR) $(SYSTEM_VSN) -s erlang halt +# Check if we are building the index from source or an installed release + if test "$$RELEASE_ROOT" = "" ; then \ + $(ERL) -noshell -pa $(EBIN) -s erl_html_tools top_index src $(ERL_TOP) \ + $(HTMLDIR) $(SYSTEM_VSN) -s erlang halt ;\ + else \ + $(ERL) -noshell -pa $(EBIN) -s erl_html_tools top_index rel $(RELEASE_ROOT) \ + $(HTMLDIR) $(SYSTEM_VSN) -s erlang halt ;\ + fi #-------------------------------------------------------------------------- @@ -139,8 +149,15 @@ $(MAN_INDEX_SCRIPT): $(MAN_INDEX_SRC) $(ERLC) -o$(EBIN) +warn_unused_vars $< $(MAN_INDEX): $(MAN_INDEX_SCRIPT) - $(ERL) -noshell -pa $(EBIN) -s otp_man_index gen $(ERL_TOP) $@ \ - -s erlang halt +# Check if we are building the index from source or an installed release + if test "$$RELEASE_ROOT" = "" ; then \ + $(ERL) -noshell -pa $(EBIN) -s otp_man_index gen src $(ERL_TOP) $@ \ + -s erlang halt ;\ + else \ + $(ERL) -noshell -pa $(EBIN) -s otp_man_index gen rel $(RELEASE_ROOT) $@ \ + -s erlang halt ;\ + fi + #-------------------------------------------------------------------------- @@ -226,7 +243,11 @@ release_docs_spec: docs $(INSTALL_DIR) $(RELSYSDIR)/js $(INSTALL_DATA) \ $(JAVASCRIPT) $(RELSYSDIR)/js - $(INSTALL_DATA) $(INDEX_FILES) $(MAN_INDEX) $(TOP_HTML_FILES) $(RELSYSDIR) + $(INSTALL_DATA) $(INDEX_FILES) $(MAN_INDEX) $(TOP_HTML_FILES) $(RELSYSDIR) + $(INSTALL_DIR) $(RELSYSDIR)/docbuild + $(INSTALL_DATA) $(INDEX_SCRIPT) $(MAN_INDEX_SCRIPT) $(JAVASCRIPT_BUILD_SCRIPT) \ + $(INDEX_SCRIPT_SRC) $(MAN_INDEX_SCRIPT_SRC) $(JAVASCRIPT_BUILD_SCRIPT_SRC) \ + $(TEMPLATES) $(RELSYSDIR)/docbuild release_spec: diff --git a/system/doc/top/src/erl_html_tools.erl b/system/doc/top/src/erl_html_tools.erl index c920245f94..fef56331fc 100644 --- a/system/doc/top/src/erl_html_tools.erl +++ b/system/doc/top/src/erl_html_tools.erl @@ -26,7 +26,7 @@ %%----------------------------------------------------------------- -module(erl_html_tools). --export([top_index/0,top_index/1,top_index/3,top_index_silent/3]). +-export([top_index/0,top_index/1,top_index/4,top_index_silent/3]). -include_lib("kernel/include/file.hrl"). @@ -49,19 +49,22 @@ top_index() -> io:format("Variable ERL_TOP is required\n",[]); Value -> {_,RelName} = init:script_id(), - top_index(Value, filename:join(Value, "doc"), RelName) + top_index(src, Value, filename:join(Value, "doc"), RelName) end. -top_index([RootDir, DestDir, OtpRel]) +top_index([src, RootDir, DestDir, OtpRel]) when is_atom(RootDir), is_atom(DestDir), is_atom(OtpRel) -> - top_index(atom_to_list(RootDir), atom_to_list(DestDir), atom_to_list(OtpRel)); -top_index(RootDir) when is_atom(RootDir) -> + top_index(src, atom_to_list(RootDir), atom_to_list(DestDir), atom_to_list(OtpRel)); +top_index([rel, RootDir, DestDir, OtpRel]) + when is_atom(RootDir), is_atom(DestDir), is_atom(OtpRel) -> + top_index(rel, atom_to_list(RootDir), atom_to_list(DestDir), atom_to_list(OtpRel)); +top_index(RootDir) when is_atom(RootDir) -> {_,RelName} = init:script_id(), - top_index(RootDir, filename:join(RootDir, "doc"), RelName). + top_index(rel, RootDir, filename:join(RootDir, "doc"), RelName). -top_index(RootDir, DestDir, OtpRel) -> +top_index(Source, RootDir, DestDir, OtpRel) -> report("****\nRootDir: ~p", [RootDir]), report("****\nDestDir: ~p", [DestDir]), report("****\nOtpRel: ~p", [OtpRel]), @@ -72,13 +75,13 @@ top_index(RootDir, DestDir, OtpRel) -> report("****\nTemplates: ~p", [Templates]), Bases = [{"../lib/", filename:join(RootDir,"lib")}, {"../", RootDir}], - Groups = find_information(Bases), + Groups = find_information(Source, Bases), report("****\nGroups: ~p", [Groups]), process_templates(Templates, DestDir, Groups). top_index_silent(RootDir, DestDir, OtpRel) -> put(silent,true), - Result = top_index(RootDir, DestDir, OtpRel), + Result = top_index(rel, RootDir, DestDir, OtpRel), erase(silent), Result. @@ -159,8 +162,8 @@ find_templates([], AllSearchPaths) -> % This function read all application names and if present all "info" files. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -find_information(Bases) -> - Paths = find_application_paths(Bases), +find_information(Source, Bases) -> + Paths = find_application_paths(Source, Bases), % report("****\nPaths: ~p", [Paths]), Apps = find_application_infos(Paths), % report("****\nApps: ~p", [Apps]), @@ -176,35 +179,47 @@ find_information(Bases) -> % % We know URL ends in a slash. -find_application_paths([]) -> +find_application_paths(_, []) -> []; -find_application_paths([{URL, Dir} | Paths]) -> +find_application_paths(Source, [{URL, Dir} | Paths]) -> + + AppDirs = get_app_dirs(Dir), + AppPaths = get_app_paths(Source, AppDirs, URL), + AppPaths ++ find_application_paths(Source, Paths). + + +get_app_paths(src, AppDirs, URL) -> Sub1 = "doc/html/index.html", %% Sub2 = "doc/index.html", + lists:map( + fun({App, AppPath}) -> + VsnFile = filename:join(AppPath, "vsn.mk"), + VsnStr = + case file:read_file(VsnFile) of + {ok, Bin} -> + case re:run(Bin, ".*VSN\s*=\s*([0-9\.]+).*",[{capture,[1],list}]) of + {match, [V]} -> + V; + nomatch -> + exit(io_lib:format("No VSN variable found in ~s\n", + [VsnFile])) + end; + {error, Reason} -> + exit(io_lib:format("~p : ~s\n", [Reason, VsnFile])) + end, + AppURL = URL ++ App ++ "-" ++ VsnStr, + {App, VsnStr, AppPath, AppURL ++ "/" ++ Sub1} + end, AppDirs); +get_app_paths(rel, AppDirs, URL) -> + Sub1 = "doc/html/index.html", +%% Sub2 = "doc/index.html", + lists:map( + fun({App, AppPath}) -> + [AppName, VsnStr] = string:tokens(App, "-"), + AppURL = URL ++ App, + {AppName, VsnStr, AppPath, AppURL ++ "/" ++ Sub1} + end, AppDirs). - AppDirs = get_app_dirs(Dir), - - AppPaths = - lists:map( - fun({App, AppPath}) -> - VsnFile = filename:join(AppPath, "vsn.mk"), - VsnStr = - case file:read_file(VsnFile) of - {ok, Bin} -> - case re:run(Bin, ".*VSN\s*=\s*([0-9\.]+).*",[{capture,[1],list}]) of - {match, [V]} -> - V; - nomatch -> - exit(io_lib:format("No VSN variable found in ~s\n", - [VsnFile])) - end; - {error, Reason} -> - exit(io_lib:format("~p : ~s\n", [Reason, VsnFile])) - end, - AppURL = URL ++ App ++ "-" ++ VsnStr, - {App, VsnStr, AppPath, AppURL ++ "/" ++ Sub1} - end, AppDirs), - AppPaths ++ find_application_paths(Paths). get_app_dirs(Dir) -> {ok, Files} = file:list_dir(Dir), @@ -212,7 +227,7 @@ get_app_dirs(Dir) -> lists:map(fun(File) -> {File, filename:join([Dir, File])} end, Files), lists:zf(fun is_app_with_doc/1, AFiles). -is_app_with_doc({"." ++ ADir, _APath}) -> +is_app_with_doc({"." ++ _ADir, _APath}) -> false; is_app_with_doc({ADir, APath}) -> case file:read_file_info(filename:join([APath, "info"])) of diff --git a/system/doc/top/src/otp_man_index.erl b/system/doc/top/src/otp_man_index.erl index 0fdc531b37..4ad975c53d 100644 --- a/system/doc/top/src/otp_man_index.erl +++ b/system/doc/top/src/otp_man_index.erl @@ -27,14 +27,20 @@ -module(otp_man_index). --export([gen/1]). +-export([gen/1, gen/2]). -include_lib("kernel/include/file.hrl"). -gen([RootDir, OutFile]) when is_atom(RootDir), is_atom(OutFile)-> +gen([Source, RootDir, OutFile]) when is_atom(RootDir), is_atom(OutFile)-> + gen(Source, RootDir, OutFile). + +gen(RootDir, OutFile) -> + gen(rel, RootDir, OutFile). + +gen(Source, RootDir, OutFile) -> Bases = [{"../lib/", filename:join(RootDir, "lib")}, {"../", RootDir}], - Apps = find_application_paths(Bases), + Apps = find_application_paths(Source, Bases), RefPages = find_ref_files(Apps), gen_html(RefPages, atom_to_list(OutFile)). @@ -81,43 +87,52 @@ find_ref_files([{App, Vsn, AppPath, RelPath} |Apps], Acc) -> find_ref_files(Apps, Refs2 ++ Acc) end. -find_application_paths([]) -> +find_application_paths(_, []) -> []; -find_application_paths([{URL, Dir} | Paths]) -> - Sub1 = "doc/html", +find_application_paths(Source, [{URL, Dir} | Paths]) -> AppDirs = get_app_dirs(Dir), - - AppPaths = - lists:map( - fun({App, AppPath}) -> - VsnFile = filename:join(AppPath, "vsn.mk"), - VsnStr = - case file:read_file(VsnFile) of - {ok, Bin} -> - case re:run(Bin, ".*VSN\s*=\s*([0-9\.]+).*",[{capture,[1],list}]) of - {match, [V]} -> - V; - nomatch -> - exit(io_lib:format("No VSN variable found in ~s\n", - [VsnFile])) - end; - {error, Reason} -> - exit(io_lib:format("~p : ~s\n", [Reason, VsnFile])) - end, - AppURL = URL ++ App ++ "-" ++ VsnStr, - {App, VsnStr, AppPath ++ "/" ++ Sub1, AppURL ++ "/" ++ Sub1} - end, AppDirs), - AppPaths ++ find_application_paths(Paths). - + AppPaths = get_app_paths(Source, AppDirs, URL), + AppPaths ++ find_application_paths(Source, Paths). +get_app_paths(src, AppDirs, URL) -> + Sub1 = "doc/html", + lists:map( + fun({App, AppPath}) -> + VsnFile = filename:join(AppPath, "vsn.mk"), + VsnStr = + case file:read_file(VsnFile) of + {ok, Bin} -> + case re:run(Bin, ".*VSN\s*=\s*([0-9\.]+).*",[{capture,[1],list}]) of + {match, [V]} -> + V; + nomatch -> + exit(io_lib:format("No VSN variable found in ~s\n", + [VsnFile])) + end; + {error, Reason} -> + exit(io_lib:format("~p : ~s\n", [Reason, VsnFile])) + end, + AppURL = URL ++ App ++ "-" ++ VsnStr, + {App, VsnStr, AppPath ++ "/" ++ Sub1, AppURL ++ "/" ++ Sub1} + end, AppDirs); +get_app_paths(rel, AppDirs, URL) -> + Sub1 = "doc/html", + lists:map( + fun({App, AppPath}) -> + [AppName, VsnStr] = string:tokens(App, "-"), + AppURL = URL ++ App, + {AppName, VsnStr, AppPath ++ "/" ++ Sub1, AppURL ++ "/" ++ Sub1} + end, AppDirs). + + get_app_dirs(Dir) -> {ok, Files} = file:list_dir(Dir), AFiles = lists:map(fun(File) -> {File, filename:join([Dir, File])} end, Files), lists:zf(fun is_app_with_doc/1, AFiles). -is_app_with_doc({"." ++ ADir, _APath}) -> +is_app_with_doc({"." ++ _ADir, _APath}) -> false; is_app_with_doc({ADir, APath}) -> case file:read_file_info(filename:join([APath, "info"])) of diff --git a/system/doc/top/templates/index.html.src b/system/doc/top/templates/index.html.src index 88d425ac1d..655f532a5d 100644 --- a/system/doc/top/templates/index.html.src +++ b/system/doc/top/templates/index.html.src @@ -39,10 +39,6 @@ under the License. <small><a href="applications.html">Applications</a><br> <a href="man_index.html">Modules</a></small> <p/> -<small><a href="highlights.html">Release highlights</a><br/> -<a href="incompatible.html">Potential incompatibilities</a><br/> -</small> -<br> <a href="javascript:openAllFlips()">Expand All</a><br> <a href="javascript:closeAllFlips()">Contract All</a> <p/> |